0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
IOHandlerRaw.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
28 #include <Common/Compat.h>
29 
30 #include "IOHandlerRaw.h"
31 #include "PollEvent.h"
32 #include "ReactorRunner.h"
33 
34 #include <Common/Error.h>
35 #include <Common/FileUtils.h>
36 #include <Common/InetAddr.h>
37 #include <Common/Time.h>
38 
39 #include <cassert>
40 #include <iostream>
41 
42 extern "C" {
43 #include <arpa/inet.h>
44 #include <errno.h>
45 #include <stdlib.h>
46 #include <sys/socket.h>
47 #include <sys/types.h>
48 #if defined(__APPLE__) || defined(__FreeBSD__)
49 #include <sys/event.h>
50 #endif
51 #include <sys/uio.h>
52 }
53 
54 using namespace Hypertable;
55 using namespace std;
56 
57 
58 bool
59 IOHandlerRaw::handle_event(struct pollfd *event,
60  ClockT::time_point arrival_time) {
61 
62  //DisplayEvent(event);
63 
64  try {
65 
66  if (event->revents & POLLERR) {
67  HT_INFOF("Received POLLERR on descriptor %d (%s:%d)", m_sd,
68  inet_ntoa(m_addr.sin_addr), ntohs(m_addr.sin_port));
69  ReactorRunner::handler_map->decomission_handler(this);
70  return true;
71  }
72 
73  if (event->revents & POLLHUP) {
74  HT_DEBUGF("Received POLLHUP on descriptor %d (%s:%d)", m_sd,
75  inet_ntoa(m_addr.sin_addr), ntohs(m_addr.sin_port));
76  ReactorRunner::handler_map->decomission_handler(this);
77  return true;
78  }
79 
80  int events {};
81 
82  if (event->revents & POLLOUT)
83  events |= PollEvent::WRITE;
84 
85  if (event->revents & POLLIN)
86  events |= PollEvent::READ;
87 
88  if (!m_handler->handle(m_sd, events))
89  return true;
90 
91  update_poll_interest();
92 
93  }
94  catch (Hypertable::Exception &e) {
95  HT_ERROR_OUT << e << HT_END;
96  ReactorRunner::handler_map->decomission_handler(this);
97  return true;
98  }
99 
100  return m_error != Error::OK;
101 }
102 
103 #if defined(__linux__)
104 
105 bool
106 IOHandlerRaw::handle_event(struct epoll_event *event,
107  ClockT::time_point arrival_time) {
108 
109  //display_event(event);
110 
111  try {
112 
113  if (ReactorFactory::ms_epollet && event->events & POLLRDHUP) {
114  HT_DEBUGF("Received POLLRDHUP on descriptor %d (%s:%d)", m_sd,
115  inet_ntoa(m_addr.sin_addr), ntohs(m_addr.sin_port));
116  ReactorRunner::handler_map->decomission_handler(this);
117  return true;
118  }
119 
120  if (event->events & EPOLLERR) {
121  HT_INFOF("Received EPOLLERR on descriptor %d (%s:%d)", m_sd,
122  inet_ntoa(m_addr.sin_addr), ntohs(m_addr.sin_port));
123  ReactorRunner::handler_map->decomission_handler(this);
124  return true;
125  }
126 
127  if (event->events & EPOLLHUP) {
128  HT_DEBUGF("Received EPOLLHUP on descriptor %d (%s:%d)", m_sd,
129  inet_ntoa(m_addr.sin_addr), ntohs(m_addr.sin_port));
130  ReactorRunner::handler_map->decomission_handler(this);
131  return true;
132  }
133 
134  int events {};
135 
136  if (event->events & EPOLLOUT)
137  events |= PollEvent::WRITE;
138 
139  if (event->events & EPOLLIN)
140  events |= PollEvent::READ;
141 
142  if (!m_handler->handle(m_sd, events))
143  return true;
144 
145  update_poll_interest();
146 
147  }
148  catch (Hypertable::Exception &e) {
149  HT_ERROR_OUT << e << HT_END;
150  ReactorRunner::handler_map->decomission_handler(this);
151  return true;
152  }
153 
154  return m_error != Error::OK;
155 }
156 
157 #elif defined(__sun__)
158 
159 bool IOHandlerRaw::handle_event(port_event_t *event,
160  ClockT::time_point arrival_time) {
161 
162  //display_event(event);
163 
164  try {
165 
166  if (event->portev_events & POLLERR) {
167  HT_INFOF("Received POLLERR on descriptor %d (%s:%d)", m_sd,
168  inet_ntoa(m_addr.sin_addr), ntohs(m_addr.sin_port));
169  ReactorRunner::handler_map->decomission_handler(this);
170  return true;
171  }
172 
173  if (event->portev_events & POLLHUP) {
174  HT_DEBUGF("Received POLLHUP on descriptor %d (%s:%d)", m_sd,
175  inet_ntoa(m_addr.sin_addr), ntohs(m_addr.sin_port));
176  ReactorRunner::handler_map->decomission_handler(this);
177  return true;
178  }
179 
180  if (event->portev_events & POLLREMOVE) {
181  HT_DEBUGF("Received POLLREMOVE on descriptor %d (%s:%d)", m_sd,
182  inet_ntoa(m_addr.sin_addr), ntohs(m_addr.sin_port));
183  ReactorRunner::handler_map->decomission_handler(this);
184  return true;
185  }
186 
187  int events {};
188 
189  if (event->portev_events & POLLOUT)
190  events |= PollEvent::WRITE;
191 
192  if (event->portev_events & POLLIN)
193  events |= PollEvent::READ;
194 
195  if (!m_handler->handle(m_sd, events))
196  return true;
197 
198  update_poll_interest();
199 
200  }
201  catch (Hypertable::Exception &e) {
202  HT_ERROR_OUT << e << HT_END;
203  test_and_set_error(e.code());
204  ReactorRunner::handler_map->decomission_handler(this);
205  return true;
206  }
207 
208  return m_error != Error::OK;
209 }
210 
211 #elif defined(__APPLE__) || defined(__FreeBSD__)
212 
213 bool IOHandlerRaw::handle_event(struct kevent *event,
214  ClockT::time_point arrival_time) {
215 
216  //DisplayEvent(event);
217 
218  try {
219  assert(m_sd == (int)event->ident);
220 
221  if (event->flags & EV_EOF) {
222  ReactorRunner::handler_map->decomission_handler(this);
223  return true;
224  }
225 
226  int events {};
227 
228  if (event->filter == EVFILT_WRITE)
229  events |= PollEvent::WRITE;
230 
231  if (event->filter == EVFILT_READ)
232  events |= PollEvent::READ;
233 
234  if (!m_handler->handle(m_sd, events))
235  return true;
236 
237  update_poll_interest();
238 
239  }
240  catch (Hypertable::Exception &e) {
241  HT_ERROR_OUT << e << HT_END;
242  test_and_set_error(e.code());
243  ReactorRunner::handler_map->decomission_handler(this);
244  return true;
245  }
246 
247  return m_error != Error::OK;
248 }
249 #else
251 #endif
252 
254  int error;
255  int new_interest = m_handler->poll_interest(m_sd);
256  int changed = new_interest ^ m_poll_interest;
257  int turn_off = changed ^ new_interest;
258  int turn_on = changed ^ m_poll_interest;
259  int mask = ~(turn_off & turn_on);
260  turn_off &= mask;
261  turn_on &= mask;
262  if (turn_off) {
263  HT_DEBUGF("Turning poll interest OFF: 0x%x", turn_off);
264  if ((error = remove_poll_interest(turn_off)) != Error::OK) {
265  if (m_error == Error::OK)
266  m_error = error;
267  return;
268  }
269  }
270  if (turn_on) {
271  HT_DEBUGF("Turning poll interest ON: 0x%x", turn_on);
272  if ((error = add_poll_interest(turn_on)) != Error::OK) {
273  if (m_error == Error::OK)
274  m_error = error;
275  return;
276  }
277  }
278 }
chrono::time_point< fast_clock > time_point
Definition: fast_clock.h:42
Declarations for ReactorRunner.
static bool ms_epollet
Use "edge triggered" epoll.
STL namespace.
Declarations for IOHandlerRaw.
void update_poll_interest()
Updates polling interest for socket.
Data available to read.
Definition: PollEvent.h:42
static HandlerMapPtr handler_map
Smart pointer to HandlerMap.
Definition: ReactorRunner.h:70
File system utility functions.
ImplementMe
Compatibility Macros for C/C++.
#define HT_END
Definition: Logger.h:220
#define HT_ERROR_OUT
Definition: Logger.h:301
Declarations for PollEvent.
Time related declarations.
Hypertable definitions
#define HT_DEBUGF(msg,...)
Definition: Logger.h:260
Writing can be performed without blocking.
Definition: PollEvent.h:46
#define HT_INFOF(msg,...)
Definition: Logger.h:272
Internet address wrapper classes and utility functions.
This is a generic exception class for Hypertable.
Definition: Error.h:314
Error codes, Exception handling, error logging.
bool handle_event(struct pollfd *event, ClockT::time_point arrival_time) override
Handle poll() interface events.
Definition: IOHandlerRaw.cc:59
int code() const
Returns the error code.
Definition: Error.h:391