PageRenderTime 20ms CodeModel.GetById 5ms RepoModel.GetById 1ms app.codeStats 0ms

/dep/acelite/ace/Asynch_Acceptor.cpp

https://github.com/chucho/FaceCore
C++ | 505 lines | 386 code | 68 blank | 51 comment | 56 complexity | 51194a6a76173c0414ebaefd180a2e8a MD5 | raw file
  1. /* -*- C++ -*- */
  2. // $Id: Asynch_Acceptor.cpp 91693 2010-09-09 12:57:54Z johnnyw $
  3. #ifndef ACE_ASYNCH_ACCEPTOR_C
  4. #define ACE_ASYNCH_ACCEPTOR_C
  5. #include "ace/Asynch_Acceptor.h"
  6. #if !defined (ACE_LACKS_PRAGMA_ONCE)
  7. # pragma once
  8. #endif /* ACE_LACKS_PRAGMA_ONCE */
  9. #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
  10. // This only works on platforms that support async i/o.
  11. #include "ace/OS_Errno.h"
  12. #include "ace/OS_Memory.h"
  13. #include "ace/OS_NS_sys_socket.h"
  14. #include "ace/Log_Msg.h"
  15. #include "ace/Message_Block.h"
  16. #include "ace/INET_Addr.h"
  17. #include "ace/SOCK_Stream.h"
  18. #include "ace/Sock_Connect.h"
  19. ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  20. template <class HANDLER>
  21. ACE_Asynch_Acceptor<HANDLER>::ACE_Asynch_Acceptor (void)
  22. : listen_handle_ (ACE_INVALID_HANDLE),
  23. pass_addresses_ (false),
  24. validate_new_connection_ (false),
  25. reissue_accept_ (1),
  26. bytes_to_read_ (0)
  27. {
  28. }
  29. template <class HANDLER>
  30. ACE_Asynch_Acceptor<HANDLER>::~ACE_Asynch_Acceptor (void)
  31. {
  32. // Close down the listen socket
  33. if (this->listen_handle_ != ACE_INVALID_HANDLE)
  34. {
  35. ACE_OS::closesocket (this->listen_handle_);
  36. this->listen_handle_ = ACE_INVALID_HANDLE;
  37. }
  38. }
  39. template <class HANDLER> int
  40. ACE_Asynch_Acceptor<HANDLER>::open (const ACE_INET_Addr &address,
  41. size_t bytes_to_read,
  42. bool pass_addresses,
  43. int backlog,
  44. int reuse_addr,
  45. ACE_Proactor *proactor,
  46. bool validate_new_connection,
  47. int reissue_accept,
  48. int number_of_initial_accepts)
  49. {
  50. ACE_TRACE ("ACE_Asynch_Acceptor<>::open");
  51. this->proactor (proactor);
  52. this->pass_addresses_ = pass_addresses;
  53. this->bytes_to_read_ = bytes_to_read;
  54. this->validate_new_connection_ = validate_new_connection;
  55. this->reissue_accept_ = reissue_accept;
  56. this->addr_family_ = address.get_type ();
  57. // Create the listener socket
  58. this->listen_handle_ = ACE_OS::socket (address.get_type (), SOCK_STREAM, 0);
  59. if (this->listen_handle_ == ACE_INVALID_HANDLE)
  60. ACE_ERROR_RETURN ((LM_ERROR,
  61. ACE_TEXT ("%p\n"),
  62. ACE_TEXT ("ACE_OS::socket")),
  63. -1);
  64. // Initialize the ACE_Asynch_Accept
  65. if (this->asynch_accept_.open (*this,
  66. this->listen_handle_,
  67. 0,
  68. this->proactor ()) == -1)
  69. {
  70. ACE_Errno_Guard g (errno);
  71. ACE_ERROR ((LM_ERROR,
  72. ACE_TEXT ("%p\n"),
  73. ACE_TEXT ("ACE_Asynch_Accept::open")));
  74. ACE_OS::closesocket (this->listen_handle_);
  75. this->listen_handle_ = ACE_INVALID_HANDLE;
  76. return -1;
  77. }
  78. if (reuse_addr)
  79. {
  80. // Reuse the address
  81. int one = 1;
  82. if (ACE_OS::setsockopt (this->listen_handle_,
  83. SOL_SOCKET,
  84. SO_REUSEADDR,
  85. (const char*) &one,
  86. sizeof one) == -1)
  87. {
  88. ACE_Errno_Guard g (errno);
  89. ACE_ERROR ((LM_ERROR,
  90. ACE_TEXT ("%p\n"),
  91. ACE_TEXT ("ACE_OS::setsockopt")));
  92. ACE_OS::closesocket (this->listen_handle_);
  93. this->listen_handle_ = ACE_INVALID_HANDLE;
  94. return -1;
  95. }
  96. }
  97. // If port is not specified, bind to any port.
  98. static ACE_INET_Addr sa (ACE_sap_any_cast (const ACE_INET_Addr &));
  99. if (address == sa &&
  100. ACE::bind_port (this->listen_handle_,
  101. INADDR_ANY,
  102. address.get_type()) == -1)
  103. {
  104. ACE_Errno_Guard g (errno);
  105. ACE_ERROR ((LM_ERROR,
  106. ACE_TEXT ("%p\n"),
  107. ACE_TEXT ("ACE::bind_port")));
  108. ACE_OS::closesocket (this->listen_handle_);
  109. this->listen_handle_ = ACE_INVALID_HANDLE;
  110. return -1;
  111. }
  112. // Bind to the specified port.
  113. if (ACE_OS::bind (this->listen_handle_,
  114. reinterpret_cast<sockaddr *> (address.get_addr ()),
  115. address.get_size ()) == -1)
  116. {
  117. ACE_Errno_Guard g (errno);
  118. ACE_ERROR ((LM_ERROR,
  119. ACE_TEXT ("%p\n"),
  120. ACE_TEXT ("ACE_OS::bind")));
  121. ACE_OS::closesocket (this->listen_handle_);
  122. this->listen_handle_ = ACE_INVALID_HANDLE;
  123. return -1;
  124. }
  125. // Start listening.
  126. if (ACE_OS::listen (this->listen_handle_, backlog) == -1)
  127. {
  128. ACE_Errno_Guard g (errno);
  129. ACE_ERROR ((LM_ERROR,
  130. ACE_TEXT ("%p\n"),
  131. ACE_TEXT ("ACE_OS::listen")));
  132. ACE_OS::closesocket (this->listen_handle_);
  133. this->listen_handle_ = ACE_INVALID_HANDLE;
  134. return -1;
  135. }
  136. // For the number of <intial_accepts>.
  137. if (number_of_initial_accepts == -1)
  138. number_of_initial_accepts = backlog;
  139. for (int i = 0; i < number_of_initial_accepts; i++)
  140. {
  141. // Initiate accepts.
  142. if (this->accept (bytes_to_read) == -1)
  143. {
  144. ACE_Errno_Guard g (errno);
  145. ACE_ERROR ((LM_ERROR,
  146. ACE_TEXT ("%p\n"),
  147. ACE_TEXT ("ACE_Asynch_Acceptor::accept")));
  148. ACE_OS::closesocket (this->listen_handle_);
  149. this->listen_handle_ = ACE_INVALID_HANDLE;
  150. return -1;
  151. }
  152. }
  153. return 0;
  154. }
  155. template <class HANDLER> int
  156. ACE_Asynch_Acceptor<HANDLER>::set_handle (ACE_HANDLE listen_handle)
  157. {
  158. ACE_TRACE ("ACE_Asynch_Acceptor<>::set_handle");
  159. // Take ownership of the <listen_handle>
  160. this->listen_handle_ = listen_handle;
  161. // Reinitialize the ACE_Asynch_Accept
  162. if (this->asynch_accept_.open (*this,
  163. this->listen_handle_,
  164. 0,
  165. this->proactor ()) == -1)
  166. ACE_ERROR_RETURN ((LM_ERROR,
  167. ACE_TEXT ("%p\n"),
  168. ACE_TEXT ("ACE_Asynch_Accept::open")),
  169. -1);
  170. return 0;
  171. }
  172. template <class HANDLER> ACE_HANDLE
  173. ACE_Asynch_Acceptor<HANDLER>::get_handle (void) const
  174. {
  175. return this->listen_handle_;
  176. }
  177. template <class HANDLER> int
  178. ACE_Asynch_Acceptor<HANDLER>::accept (size_t bytes_to_read, const void *act)
  179. {
  180. ACE_TRACE ("ACE_Asynch_Acceptor<>::accept");
  181. ACE_Message_Block *message_block = 0;
  182. // The space_needed calculation is drive by needs of Windows. POSIX doesn't
  183. // need to extra 16 bytes, but it doesn't hurt.
  184. size_t space_needed = sizeof (sockaddr_in) + 16;
  185. #if defined (ACE_HAS_IPV6)
  186. if (PF_INET6 == this->addr_family_)
  187. space_needed = sizeof (sockaddr_in6) + 16;
  188. #endif /* ACE_HAS_IPV6 */
  189. space_needed = (2 * space_needed) + bytes_to_read;
  190. // Create a new message block big enough for the addresses and data
  191. ACE_NEW_RETURN (message_block,
  192. ACE_Message_Block (space_needed),
  193. -1);
  194. // Initiate asynchronous accepts
  195. if (this->asynch_accept_.accept (*message_block,
  196. bytes_to_read,
  197. ACE_INVALID_HANDLE,
  198. act,
  199. 0,
  200. ACE_SIGRTMIN,
  201. this->addr_family_) == -1)
  202. {
  203. // Cleanup on error
  204. message_block->release ();
  205. return -1;
  206. }
  207. return 0;
  208. }
  209. template <class HANDLER> void
  210. ACE_Asynch_Acceptor<HANDLER>::handle_accept (const ACE_Asynch_Accept::Result &result)
  211. {
  212. ACE_TRACE ("ACE_Asynch_Acceptor<>::handle_accept");
  213. // Variable for error tracking
  214. int error = 0;
  215. // If the asynchronous accept fails.
  216. if (!result.success () || result.accept_handle () == ACE_INVALID_HANDLE)
  217. {
  218. error = 1;
  219. }
  220. #if defined (ACE_WIN32)
  221. // In order to use accept handle with other Window Sockets 1.1
  222. // functions, we call the setsockopt function with the
  223. // SO_UPDATE_ACCEPT_CONTEXT option. This option initializes the
  224. // socket so that other Windows Sockets routines to access the
  225. // socket correctly.
  226. if (!error &&
  227. ACE_OS::setsockopt (result.accept_handle (),
  228. SOL_SOCKET,
  229. SO_UPDATE_ACCEPT_CONTEXT,
  230. (char *) &this->listen_handle_,
  231. sizeof (this->listen_handle_)) == -1)
  232. {
  233. error = 1;
  234. }
  235. #endif /* ACE_WIN32 */
  236. // Parse address.
  237. ACE_INET_Addr local_address;
  238. ACE_INET_Addr remote_address;
  239. if (!error &&
  240. (this->validate_new_connection_ || this->pass_addresses_))
  241. // Parse the addresses.
  242. this->parse_address (result,
  243. remote_address,
  244. local_address);
  245. // Validate remote address
  246. if (!error &&
  247. this->validate_new_connection_ &&
  248. (this->validate_connection (result, remote_address, local_address) == -1))
  249. {
  250. error = 1;
  251. }
  252. HANDLER *new_handler = 0;
  253. if (!error)
  254. {
  255. // The Template method
  256. new_handler = this->make_handler ();
  257. if (new_handler == 0)
  258. {
  259. error = 1;
  260. }
  261. }
  262. // If no errors
  263. if (!error)
  264. {
  265. // Update the Proactor.
  266. new_handler->proactor (this->proactor ());
  267. // Pass the addresses
  268. if (this->pass_addresses_)
  269. new_handler->addresses (remote_address,
  270. local_address);
  271. // Pass the ACT
  272. if (result.act () != 0)
  273. new_handler->act (result.act ());
  274. // Set up the handler's new handle value
  275. new_handler->handle (result.accept_handle ());
  276. // Initiate the handler
  277. new_handler->open (result.accept_handle (),
  278. result.message_block ());
  279. }
  280. // On failure, no choice but to close the socket
  281. if (error &&
  282. result.accept_handle() != ACE_INVALID_HANDLE )
  283. ACE_OS::closesocket (result.accept_handle ());
  284. // Delete the dynamically allocated message_block
  285. result.message_block ().release ();
  286. // Start off another asynchronous accept to keep the backlog going,
  287. // unless we closed the listen socket already (from the destructor),
  288. // or this callback is the result of a canceled/aborted accept.
  289. if (this->should_reissue_accept () &&
  290. this->listen_handle_ != ACE_INVALID_HANDLE
  291. #if defined (ACE_WIN32)
  292. && result.error () != ERROR_OPERATION_ABORTED
  293. #else
  294. && result.error () != ECANCELED
  295. #endif
  296. )
  297. this->accept (this->bytes_to_read_, result.act ());
  298. }
  299. template <class HANDLER> int
  300. ACE_Asynch_Acceptor<HANDLER>::validate_connection
  301. (const ACE_Asynch_Accept::Result& /* result */,
  302. const ACE_INET_Addr& /* remote */,
  303. const ACE_INET_Addr& /* local */)
  304. {
  305. // Default implementation always validates the remote address.
  306. return 0;
  307. }
  308. template <class HANDLER> int
  309. ACE_Asynch_Acceptor<HANDLER>::cancel (void)
  310. {
  311. ACE_TRACE ("ACE_Asynch_Acceptor<>::cancel");
  312. // All I/O operations that are canceled will complete with the error
  313. // ERROR_OPERATION_ABORTED. All completion notifications for the I/O
  314. // operations will occur normally.
  315. #if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
  316. return (int) ::CancelIo (this->listen_handle_);
  317. #else
  318. // Supported now
  319. return this->asynch_accept_.cancel();
  320. #endif /* defined (ACE_HAS_WIN32_OVERLAPPED_IO) */
  321. }
  322. template <class HANDLER> void
  323. ACE_Asynch_Acceptor<HANDLER>::parse_address (const
  324. ACE_Asynch_Accept::Result &result,
  325. ACE_INET_Addr &remote_address,
  326. ACE_INET_Addr &local_address)
  327. {
  328. ACE_TRACE ("ACE_Asynch_Acceptor<>::parse_address");
  329. #if defined (ACE_HAS_AIO_CALLS)
  330. // Use an ACE_SOCK to get the addresses - it knows how to deal with
  331. // ACE_INET_Addr objects and get IPv4/v6 addresses.
  332. ACE_SOCK_Stream str (result.accept_handle ());
  333. str.get_local_addr (local_address);
  334. str.get_remote_addr (remote_address);
  335. #elif defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
  336. ACE_Message_Block &message_block = result.message_block ();
  337. sockaddr *local_addr = 0;
  338. sockaddr *remote_addr = 0;
  339. int local_size = 0;
  340. int remote_size = 0;
  341. // This matches setup in accept().
  342. size_t addr_size = sizeof (sockaddr_in) + 16;
  343. #if defined (ACE_HAS_IPV6)
  344. if (this->addr_family_ == PF_INET6)
  345. addr_size = sizeof (sockaddr_in6) + 16;
  346. #endif /* ACE_HAS_IPV6 */
  347. ::GetAcceptExSockaddrs (message_block.rd_ptr (),
  348. static_cast<DWORD> (this->bytes_to_read_),
  349. static_cast<DWORD> (addr_size),
  350. static_cast<DWORD> (addr_size),
  351. &local_addr,
  352. &local_size,
  353. &remote_addr,
  354. &remote_size);
  355. local_address.set (reinterpret_cast<sockaddr_in *> (local_addr),
  356. local_size);
  357. remote_address.set (reinterpret_cast<sockaddr_in *> (remote_addr),
  358. remote_size);
  359. #else
  360. // just in case
  361. errno = ENOTSUP;
  362. #endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
  363. return;
  364. }
  365. template <class HANDLER> ACE_HANDLE
  366. ACE_Asynch_Acceptor<HANDLER>::handle (void) const
  367. {
  368. return this->listen_handle_;
  369. }
  370. template <class HANDLER> void
  371. ACE_Asynch_Acceptor<HANDLER>::handle (ACE_HANDLE h)
  372. {
  373. ACE_Handler::handle (h);
  374. }
  375. template <class HANDLER> ACE_Asynch_Accept &
  376. ACE_Asynch_Acceptor<HANDLER>::asynch_accept (void)
  377. {
  378. return this->asynch_accept_;
  379. }
  380. template <class HANDLER> HANDLER *
  381. ACE_Asynch_Acceptor<HANDLER>::make_handler (void)
  382. {
  383. // Default behavior
  384. HANDLER *handler = 0;
  385. ACE_NEW_RETURN (handler,
  386. HANDLER,
  387. 0);
  388. return handler;
  389. }
  390. template <class HANDLER> bool
  391. ACE_Asynch_Acceptor<HANDLER>::pass_addresses (void) const
  392. {
  393. return this->pass_addresses_;
  394. }
  395. template <class HANDLER> void
  396. ACE_Asynch_Acceptor<HANDLER>::pass_addresses (bool new_value)
  397. {
  398. this->pass_addresses_ = new_value;
  399. }
  400. template <class HANDLER> bool
  401. ACE_Asynch_Acceptor<HANDLER>::validate_new_connection (void) const
  402. {
  403. return this->validate_new_connection_;
  404. }
  405. template <class HANDLER> void
  406. ACE_Asynch_Acceptor<HANDLER>::validate_new_connection (bool new_value)
  407. {
  408. this->validate_new_connection_ = new_value;
  409. }
  410. template <class HANDLER> int
  411. ACE_Asynch_Acceptor<HANDLER>::reissue_accept (void) const
  412. {
  413. return this->reissue_accept_;
  414. }
  415. template <class HANDLER> void
  416. ACE_Asynch_Acceptor<HANDLER>::reissue_accept (int new_value)
  417. {
  418. this->reissue_accept_ = new_value;
  419. }
  420. template <class HANDLER> size_t
  421. ACE_Asynch_Acceptor<HANDLER>::bytes_to_read (void) const
  422. {
  423. return this->bytes_to_read_;
  424. }
  425. template <class HANDLER> void
  426. ACE_Asynch_Acceptor<HANDLER>::bytes_to_read (size_t new_value)
  427. {
  428. this->bytes_to_read_ = new_value;
  429. }
  430. template <class HANDLER> int
  431. ACE_Asynch_Acceptor<HANDLER>::should_reissue_accept (void)
  432. {
  433. return this->reissue_accept_;
  434. }
  435. ACE_END_VERSIONED_NAMESPACE_DECL
  436. #endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
  437. #endif /* ACE_ASYNCH_ACCEPTOR_C */