0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
IOHandler.h
Go to the documentation of this file.
1 /* -*- c++ -*-
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 #ifndef AsyncComm_IOHandler_h
29 #define AsyncComm_IOHandler_h
30 
31 #include "Clock.h"
32 #include "DispatchHandler.h"
33 #include "PollEvent.h"
34 #include "ReactorFactory.h"
35 #include "ExpireTimer.h"
36 
37 #include <Common/Logger.h>
38 #include <Common/Time.h>
39 
40 #include <mutex>
41 
42 extern "C" {
43 #include <errno.h>
44 #include <sys/types.h>
45 #include <sys/socket.h>
46 #include <poll.h>
47 #if defined(__APPLE__) || defined(__FreeBSD__)
48 #include <sys/event.h>
49 #elif defined(__linux__)
50 #include <sys/epoll.h>
51 #if !defined(POLLRDHUP)
52 #define POLLRDHUP 0x2000
53 #endif
54 #elif defined(__sun__)
55 #include <port.h>
56 #include <sys/port_impl.h>
57 #include <unistd.h>
58 #endif
59 }
60 
61 
62 namespace Hypertable {
63 
76  class IOHandler {
77 
78  public:
79 
87  IOHandler(int sd, const DispatchHandlerPtr &dhp,
90  m_sd(sd), m_dispatch_handler(dhp), m_decomissioned(false) {
92  m_poll_interest = 0;
93  socklen_t namelen = sizeof(m_local_addr);
94  getsockname(m_sd, (sockaddr *)&m_local_addr, &namelen);
95  memset(&m_alias, 0, sizeof(m_alias));
96  }
97 
104  m_error(Error::OK), m_sd(sd),
105  m_decomissioned(false) {
107  m_poll_interest = 0;
108  socklen_t namelen = sizeof(m_local_addr);
109  getsockname(m_sd, (sockaddr *)&m_local_addr, &namelen);
110  memset(&m_alias, 0, sizeof(m_alias));
111  }
112 
118  virtual bool handle_event(struct pollfd *event,
119  ClockT::time_point arrival_time) = 0;
120 
121 #if defined(__APPLE__) || defined(__FreeBSD__)
122 
127  virtual bool handle_event(struct kevent *event,
128  ClockT::time_point arrival_time) = 0;
129 #elif defined(__linux__)
130 
135  virtual bool handle_event(struct epoll_event *event,
136  ClockT::time_point arrival_time) = 0;
137 #elif defined(__sun__)
138 
143  virtual bool handle_event(port_event_t *event,
144  ClockT::time_point arrival_time) = 0;
145 #else
146  // Implement me!!!
147 #endif
148 
152  virtual ~IOHandler() {
153  HT_ASSERT(m_free_flag != 0xdeadbeef);
154  m_free_flag = 0xdeadbeef;
155  if (m_socket_internally_created)
156  ::close(m_sd);
157  return;
158  }
159 
169  void deliver_event(EventPtr &event, DispatchHandler *dh=0) {
170  memcpy(&event->local_addr, &m_local_addr, sizeof(m_local_addr));
171  if (dh)
172  dh->handle(event);
173  else {
174  if (!m_dispatch_handler)
175  HT_INFOF("%s", event->to_str().c_str());
176  else
177  m_dispatch_handler->handle(event);
178  }
179  }
180 
190  int start_polling(int mode=PollEvent::READ);
191 
201  int add_poll_interest(int mode);
202 
212  int remove_poll_interest(int mode);
213 
222  }
223 
230 
235 
239  void set_proxy(const String &proxy) {
240  std::lock_guard<std::mutex> lock(m_mutex);
241  m_proxy = proxy;
242  }
243 
247  const String& get_proxy() {
248  std::lock_guard<std::mutex> lock(m_mutex);
249  return m_proxy;
250  }
251 
255  int get_sd() { return m_sd; }
256 
260  void get_reactor(ReactorPtr &reactor) { reactor = m_reactor; }
261 
267  void display_event(struct pollfd *event);
268 
269 #if defined(__APPLE__) || defined(__FreeBSD__)
270 
275  void display_event(struct kevent *event);
276 #elif defined(__linux__)
277 
282  void display_event(struct epoll_event *event);
283 #elif defined(__sun__)
284 
289  void display_event(port_event_t *event);
290 #endif
291 
292  friend class HandlerMap;
293 
294  protected:
295 
303  bool test_and_set_error(int32_t error) {
304  std::lock_guard<std::mutex> lock(m_mutex);
305  if (m_error == Error::OK) {
306  m_error = error;
307  return true;
308  }
309  return false;
310  }
311 
319  int32_t get_error() {
320  std::lock_guard<std::mutex> lock(m_mutex);
321  return m_error;
322  }
323 
328  return m_alias;
329  }
330 
334  void set_alias(const InetAddr &alias) {
335  m_alias = alias;
336  }
337 
345  }
346 
359  m_reactor->schedule_removal(this);
360  }
361 
368  size_t reference_count() {
369  return m_reference_count;
370  }
371 
382  void decomission() {
383  if (!m_decomissioned) {
384  m_decomissioned = true;
385  if (m_reference_count == 0)
386  m_reactor->schedule_removal(this);
387  }
388  }
389 
394  return m_decomissioned;
395  }
396 
399  virtual void disconnect() { }
400 
408  short poll_events(int mode) {
409  short events = 0;
410  if (mode & PollEvent::READ)
411  events |= POLLIN;
412  if (mode & PollEvent::WRITE)
413  events |= POLLOUT;
414  return events;
415  }
416 
420  void stop_polling() {
422  m_poll_interest = 0;
423  m_reactor->modify_poll_interest(m_sd, 0);
424  return;
425  }
426 #if defined(__APPLE__) || defined(__sun__) || defined(__FreeBSD__)
428 #elif defined(__linux__)
429  struct epoll_event event; // this is necessary for < Linux 2.6.9
430  if (epoll_ctl(m_reactor->poll_fd, EPOLL_CTL_DEL, m_sd, &event) < 0) {
431  HT_ERRORF("epoll_ctl(%d, EPOLL_CTL_DEL, %d) failed : %s",
432  m_reactor->poll_fd, m_sd, strerror(errno));
433  exit(EXIT_FAILURE);
434  }
435  m_poll_interest = 0;
436 #endif
437  }
438 
441 
446 
448  uint32_t m_free_flag;
449 
451  int32_t m_error;
452 
455 
458 
461 
464 
466  int m_sd;
467 
470 
473 
479 
484 
486  bool m_socket_internally_created {true};
487  };
489 }
490 
491 #endif // AsyncComm_IOHandler_h
int start_polling(int mode=PollEvent::READ)
Start polling on the handler with the poll interest specified in mode.
Definition: IOHandler.cc:91
static void get_reactor(ReactorPtr &reactor, Reactor::Priority priority=Reactor::Priority::NORMAL)
This method returns the 'next' reactor.
static std::mutex mutex
Definition: Logger.cc:43
int reset_poll_interest()
Resets poll interest by adding m_poll_interest to the polling interface for this handler.
Definition: IOHandler.h:220
void set_proxy(const String &proxy)
Sets the proxy name for this connection.
Definition: IOHandler.h:239
virtual void disconnect()
Disconnect connection.
Definition: IOHandler.h:399
InetAddr get_local_address()
Get local socket address for connection.
Definition: IOHandler.h:234
InetAddr m_alias
Address alias for connection.
Definition: IOHandler.h:463
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
chrono::time_point< fast_clock > time_point
Definition: fast_clock.h:42
Abstract base class for application dispatch handlers registered with AsyncComm.
size_t m_reference_count
Reference count.
Definition: IOHandler.h:445
void set_alias(const InetAddr &alias)
Set alias address for this connection.
Definition: IOHandler.h:334
InetAddr get_address()
Gets the handler socket address.
Definition: IOHandler.h:229
void increment_reference_count()
Increment reference count.
Definition: IOHandler.h:343
std::shared_ptr< Event > EventPtr
Smart pointer to Event.
Definition: Event.h:228
Declarations for ExpireTimer.
int remove_poll_interest(int mode)
Removes the poll interest specified in mode to the polling interface for this handler.
std::mutex m_mutex
Mutex for serializing concurrent access
Definition: IOHandler.h:440
virtual ~IOHandler()
Destructor.
Definition: IOHandler.h:152
void display_event(struct pollfd *event)
Display polling event from poll() interface to stderr.
Definition: IOHandler.cc:60
Data structure for mapping socket addresses to I/O handlers.
Definition: HandlerMap.h:69
Data available to read.
Definition: PollEvent.h:42
#define HT_ASSERT(_e_)
Definition: Logger.h:396
Declaration of ClockT.
void decrement_reference_count()
Decrement reference count.
Definition: IOHandler.h:355
DispatchHandlerPtr m_dispatch_handler
Default dispatch hander for connection.
Definition: IOHandler.h:469
Declarations for DispatchHandler.
bool m_decomissioned
Decomissioned flag.
Definition: IOHandler.h:483
const String & get_proxy()
Gets the proxy name for this connection.
Definition: IOHandler.h:247
Encapsulate an internet address.
Definition: InetAddr.h:66
void decomission()
Decomission handler.
Definition: IOHandler.h:382
Logging routines and macros.
IOHandler(int sd)
Constructor.
Definition: IOHandler.h:103
Base class for socket descriptor I/O handlers.
Definition: IOHandler.h:76
int m_sd
Socket descriptor.
Definition: IOHandler.h:466
std::shared_ptr< Reactor > ReactorPtr
Shared smart pointer to Reactor.
Definition: Reactor.h:295
bool test_and_set_error(int32_t error)
Sets m_error to error if it has not already been set.
Definition: IOHandler.h:303
Declarations for PollEvent.
Time related declarations.
void stop_polling()
Stops polling by removing socket from polling interface.
Definition: IOHandler.h:420
short poll_events(int mode)
Return poll() interface events corresponding to the normalized polling interest in mode...
Definition: IOHandler.h:408
Hypertable definitions
InetAddr get_alias()
Get alias address for this connection.
Definition: IOHandler.h:327
Writing can be performed without blocking.
Definition: PollEvent.h:46
uint32_t m_free_flag
Free flag (for testing)
Definition: IOHandler.h:448
int get_sd()
Gets the socket descriptor for this connection.
Definition: IOHandler.h:255
#define HT_INFOF(msg,...)
Definition: Logger.h:272
virtual bool handle_event(struct pollfd *event, ClockT::time_point arrival_time)=0
Event handler method for Unix poll interface.
String m_proxy
Proxy name for this connection.
Definition: IOHandler.h:454
void get_reactor(ReactorPtr &reactor)
Get the reactor that this handler is assigned to.
Definition: IOHandler.h:260
int add_poll_interest(int mode)
Adds the poll interest specified in mode to the polling interface for this handler.
int32_t m_error
Error code.
Definition: IOHandler.h:451
Priority
Enumeration for reactor priority.
Definition: Reactor.h:73
Declarations for ReactorFactory.
size_t reference_count()
Return reference count.
Definition: IOHandler.h:368
std::shared_ptr< DispatchHandler > DispatchHandlerPtr
Smart pointer to DispatchHandler.
void deliver_event(EventPtr &event, DispatchHandler *dh=0)
Convenience method for delivering event to application.
Definition: IOHandler.h:169
int m_poll_interest
Current polling interest.
Definition: IOHandler.h:478
#define HT_ERRORF(msg,...)
Definition: Logger.h:300
IOHandler(int sd, const DispatchHandlerPtr &dhp, Reactor::Priority rp=Reactor::Priority::NORMAL)
Constructor.
Definition: IOHandler.h:87
ReactorPtr m_reactor
Reactor to which this handler is assigned.
Definition: IOHandler.h:472
int32_t get_error()
Returns first error code encountered by handler.
Definition: IOHandler.h:319
void alias(const String &cmdline_opt, const String &file_opt, bool overwrite)
Setup command line option alias for config file option.
Definition: Config.cc:607
bool is_decomissioned()
Checks to see if handler is decomissioned.
Definition: IOHandler.h:393
InetAddr m_addr
Handler socket address.
Definition: IOHandler.h:457
InetAddr m_local_addr
Local address of connection.
Definition: IOHandler.h:460