0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
IOHandlerAccept.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 #define HT_DISABLE_LOG_DEBUG 1
31 
32 #include "HandlerMap.h"
33 #include "IOHandlerAccept.h"
34 #include "IOHandlerData.h"
35 #include "ReactorFactory.h"
36 #include "ReactorRunner.h"
37 
38 #include <Common/Error.h>
39 #include <Common/FileUtils.h>
40 #include <Common/Logger.h>
41 
42 #include <iostream>
43 
44 extern "C" {
45 #include <errno.h>
46 #include <netinet/tcp.h>
47 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <netinet/in.h>
50 #include <arpa/inet.h>
51 #include <fcntl.h>
52 }
53 
54 
55 using namespace Hypertable;
56 using namespace std;
57 
58 
59 bool
60 IOHandlerAccept::handle_event(struct pollfd *event,
62  if (event->revents & POLLIN)
63  return handle_incoming_connection();
64  ReactorRunner::handler_map->decomission_handler(this);
65  return true;
66 }
67 
71 #if defined(__APPLE__) || defined(__FreeBSD__)
72 bool IOHandlerAccept::handle_event(struct kevent *event,
74  //DisplayEvent(event);
75  if (event->filter == EVFILT_READ)
76  return handle_incoming_connection();
77  ReactorRunner::handler_map->decomission_handler(this);
78  return true;
79 }
80 #elif defined(__linux__)
81 bool IOHandlerAccept::handle_event(struct epoll_event *event,
83  //DisplayEvent(event);
84  return handle_incoming_connection();
85 }
86 #elif defined(__sun__)
87 bool IOHandlerAccept::handle_event(port_event_t *event,
89  if (event->portev_events == POLLIN)
90  return handle_incoming_connection();
91  ReactorRunner::handler_map->decomission_handler(this);
92  return true;
93 }
94 #else
96 #endif
97 
98 
99 
101  int sd;
102  struct sockaddr_in addr;
103  socklen_t addr_len = sizeof(sockaddr_in);
104  int one = 1;
105  IOHandlerData *handler;
106 
107  while (true) {
108 
109  if ((sd = accept(m_sd, (struct sockaddr *)&addr, &addr_len)) < 0) {
110  if (errno == EAGAIN)
111  break;
112  HT_ERRORF("accept() failure: %s", strerror(errno));
113  break;
114  }
115 
116  HT_DEBUGF("Just accepted incoming connection, fd=%d (%s:%d)",
117  m_sd, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
118 
119  // Set to non-blocking
120  FileUtils::set_flags(sd, O_NONBLOCK);
121 
122 #if defined(__linux__)
123  if (setsockopt(sd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)) < 0)
124  HT_WARNF("setsockopt(TCP_NODELAY) failure: %s", strerror(errno));
125 #elif defined(__sun__)
126  if (setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) < 0)
127  HT_ERRORF("setting TCP_NODELAY: %s", strerror(errno));
128 #elif defined(__APPLE__) || defined(__FreeBSD__)
129  if (setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one)) < 0)
130  HT_WARNF("setsockopt(SO_NOSIGPIPE) failure: %s", strerror(errno));
131 #endif
132 
133  if (setsockopt(m_sd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)) < 0)
134  HT_ERRORF("setsockopt(SO_KEEPALIVE) failure: %s", strerror(errno));
135 
136  int bufsize = 4*32768;
137 
138  if (setsockopt(sd, SOL_SOCKET, SO_SNDBUF, (char *)&bufsize, sizeof(bufsize)) < 0)
139  HT_WARNF("setsockopt(SO_SNDBUF) failed - %s", strerror(errno));
140 
141  if (setsockopt(sd, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize, sizeof(bufsize)) < 0)
142  HT_WARNF("setsockopt(SO_RCVBUF) failed - %s", strerror(errno));
143 
144  DispatchHandlerPtr dhp;
145  m_handler_factory->get_instance(dhp);
146 
147  handler = new IOHandlerData(sd, addr, dhp, true);
148 
149  m_handler_map->insert_handler(handler, true);
150 
151  int32_t error;
152  if ((error = handler->start_polling(PollEvent::READ |
154  HT_ERRORF("Problem starting polling on incoming connection - %s",
155  Error::get_text(error));
156  ReactorRunner::handler_map->decrement_reference_count(handler);
157  ReactorRunner::handler_map->decomission_handler(handler);
158  return false;
159  }
160 
162  if ((error = ReactorRunner::handler_map->propagate_proxy_map(handler))
163  != Error::OK) {
164  HT_ERRORF("Problem sending proxy map to %s - %s",
165  m_addr.format().c_str(), Error::get_text(error));
166  ReactorRunner::handler_map->decrement_reference_count(handler);
167  return false;
168  }
169  }
170 
171  ReactorRunner::handler_map->decrement_reference_count(handler);
172 
173  EventPtr event = make_shared<Event>(Event::CONNECTION_ESTABLISHED, addr, Error::OK);
174  deliver_event(event);
175  }
176 
177  return false;
178  }
int start_polling(int mode=PollEvent::READ)
Start polling on the handler with the poll interest specified in mode.
Definition: IOHandler.cc:91
ImplementMe
#define HT_WARNF(msg,...)
Definition: Logger.h:290
chrono::time_point< fast_clock > time_point
Definition: fast_clock.h:42
Declarations for ReactorRunner.
std::shared_ptr< Event > EventPtr
Smart pointer to Event.
Definition: Event.h:228
STL namespace.
Connection established event.
Definition: Event.h:61
Data available to read.
Definition: PollEvent.h:42
static HandlerMapPtr handler_map
Smart pointer to HandlerMap.
Definition: ReactorRunner.h:70
File system utility functions.
Declarations for IOHandlerAccept.
const char * get_text(int error)
Returns a descriptive error message.
Definition: Error.cc:330
Logging routines and macros.
Compatibility Macros for C/C++.
I/O handler for TCP sockets.
Definition: IOHandlerData.h:51
bool handle_incoming_connection()
Handles incoming connection requests.
Declarations for HandlerMap.
Declarations for IOHandlerData.
static bool set_flags(int fd, int flags)
Sets fcntl flags of a socket.
Definition: FileUtils.cc:256
Hypertable definitions
#define HT_DEBUGF(msg,...)
Definition: Logger.h:260
Writing can be performed without blocking.
Definition: PollEvent.h:46
Declarations for ReactorFactory.
std::shared_ptr< DispatchHandler > DispatchHandlerPtr
Smart pointer to DispatchHandler.
#define HT_ERRORF(msg,...)
Definition: Logger.h:300
Error codes, Exception handling, error logging.
bool handle_event(struct pollfd *event, ClockT::time_point arrival_time) override
Handle poll() interface events.
static bool proxy_master
Set to true if this process is acting as "Proxy Master".