2 #ifndef ACE_ASYNCH_ACCEPTOR_C
3 #define ACE_ASYNCH_ACCEPTOR_C
5 #include "ace/Asynch_Acceptor.h"
7 #if !defined (ACE_LACKS_PRAGMA_ONCE)
9 #endif /* ACE_LACKS_PRAGMA_ONCE */
11 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
12 // This only works on platforms that support async i/o.
14 #include "ace/OS_Errno.h"
15 #include "ace/OS_Memory.h"
16 #include "ace/OS_NS_sys_socket.h"
17 #include "ace/Log_Category.h"
18 #include "ace/Message_Block.h"
19 #include "ace/INET_Addr.h"
20 #include "ace/SOCK_Stream.h"
21 #include "ace/Sock_Connect.h"
23 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
25 template <class HANDLER
>
26 ACE_Asynch_Acceptor
<HANDLER
>::ACE_Asynch_Acceptor ()
28 listen_handle_ (ACE_INVALID_HANDLE
),
29 pass_addresses_ (false),
30 validate_new_connection_ (false),
36 template <class HANDLER
>
37 ACE_Asynch_Acceptor
<HANDLER
>::~ACE_Asynch_Acceptor ()
39 // Close down the listen socket
40 if (this->listen_handle_
!= ACE_INVALID_HANDLE
)
42 ACE_OS::closesocket (this->listen_handle_
);
43 this->listen_handle_
= ACE_INVALID_HANDLE
;
47 template <class HANDLER
> int
48 ACE_Asynch_Acceptor
<HANDLER
>::open (const ACE_INET_Addr
&address
,
53 ACE_Proactor
*proactor
,
54 bool validate_new_connection
,
56 int number_of_initial_accepts
)
58 ACE_TRACE ("ACE_Asynch_Acceptor<>::open");
60 this->proactor (proactor
);
61 this->pass_addresses_
= pass_addresses
;
62 this->bytes_to_read_
= bytes_to_read
;
63 this->validate_new_connection_
= validate_new_connection
;
64 this->reissue_accept_
= reissue_accept
;
65 this->addr_family_
= address
.get_type ();
67 // Create the listener socket
68 this->listen_handle_
= ACE_OS::socket (address
.get_type (), SOCK_STREAM
, 0);
69 if (this->listen_handle_
== ACE_INVALID_HANDLE
)
70 ACELIB_ERROR_RETURN ((LM_ERROR
,
72 ACE_TEXT ("ACE_OS::socket")),
74 // Initialize the ACE_Asynch_Accept
75 if (this->asynch_accept_
.open (*this,
78 this->proactor ()) == -1)
80 ACE_Errno_Guard
g (errno
);
81 ACELIB_ERROR ((LM_ERROR
,
83 ACE_TEXT ("ACE_Asynch_Accept::open")));
84 ACE_OS::closesocket (this->listen_handle_
);
85 this->listen_handle_
= ACE_INVALID_HANDLE
;
93 if (ACE_OS::setsockopt (this->listen_handle_
,
99 ACE_Errno_Guard
g (errno
);
100 ACELIB_ERROR ((LM_ERROR
,
102 ACE_TEXT ("ACE_OS::setsockopt")));
103 ACE_OS::closesocket (this->listen_handle_
);
104 this->listen_handle_
= ACE_INVALID_HANDLE
;
109 // If port is not specified, bind to any port.
110 static ACE_INET_Addr
sa (ACE_sap_any_cast (const ACE_INET_Addr
&));
113 ACE::bind_port (this->listen_handle_
,
115 address
.get_type()) == -1)
117 ACE_Errno_Guard
g (errno
);
118 ACELIB_ERROR ((LM_ERROR
,
120 ACE_TEXT ("ACE::bind_port")));
121 ACE_OS::closesocket (this->listen_handle_
);
122 this->listen_handle_
= ACE_INVALID_HANDLE
;
126 // Bind to the specified port.
127 if (ACE_OS::bind (this->listen_handle_
,
128 reinterpret_cast<sockaddr
*> (address
.get_addr ()),
129 address
.get_size ()) == -1)
131 ACE_Errno_Guard
g (errno
);
132 ACELIB_ERROR ((LM_ERROR
,
134 ACE_TEXT ("ACE_OS::bind")));
135 ACE_OS::closesocket (this->listen_handle_
);
136 this->listen_handle_
= ACE_INVALID_HANDLE
;
141 if (ACE_OS::listen (this->listen_handle_
, backlog
) == -1)
143 ACE_Errno_Guard
g (errno
);
144 ACELIB_ERROR ((LM_ERROR
,
146 ACE_TEXT ("ACE_OS::listen")));
147 ACE_OS::closesocket (this->listen_handle_
);
148 this->listen_handle_
= ACE_INVALID_HANDLE
;
152 // For the number of <intial_accepts>.
153 if (number_of_initial_accepts
== -1)
154 number_of_initial_accepts
= backlog
;
156 for (int i
= 0; i
< number_of_initial_accepts
; i
++)
159 if (this->accept (bytes_to_read
) == -1)
161 ACE_Errno_Guard
g (errno
);
162 ACELIB_ERROR ((LM_ERROR
,
164 ACE_TEXT ("ACE_Asynch_Acceptor::accept")));
165 ACE_OS::closesocket (this->listen_handle_
);
166 this->listen_handle_
= ACE_INVALID_HANDLE
;
174 template <class HANDLER
> int
175 ACE_Asynch_Acceptor
<HANDLER
>::set_handle (ACE_HANDLE listen_handle
)
177 ACE_TRACE ("ACE_Asynch_Acceptor<>::set_handle");
179 // Take ownership of the <listen_handle>
180 this->listen_handle_
= listen_handle
;
182 // Reinitialize the ACE_Asynch_Accept
183 if (this->asynch_accept_
.open (*this,
184 this->listen_handle_
,
186 this->proactor ()) == -1)
187 ACELIB_ERROR_RETURN ((LM_ERROR
,
189 ACE_TEXT ("ACE_Asynch_Accept::open")),
194 template <class HANDLER
> ACE_HANDLE
195 ACE_Asynch_Acceptor
<HANDLER
>::get_handle () const
197 return this->listen_handle_
;
200 template <class HANDLER
> int
201 ACE_Asynch_Acceptor
<HANDLER
>::accept (size_t bytes_to_read
, const void *act
)
203 ACE_TRACE ("ACE_Asynch_Acceptor<>::accept");
205 ACE_Message_Block
*message_block
= 0;
206 // The space_needed calculation is drive by needs of Windows. POSIX doesn't
207 // need to extra 16 bytes, but it doesn't hurt.
208 size_t space_needed
= sizeof (sockaddr_in
) + 16;
209 #if defined (ACE_HAS_IPV6)
210 if (PF_INET6
== this->addr_family_
)
211 space_needed
= sizeof (sockaddr_in6
) + 16;
212 #endif /* ACE_HAS_IPV6 */
213 space_needed
= (2 * space_needed
) + bytes_to_read
;
215 // Create a new message block big enough for the addresses and data
216 ACE_NEW_RETURN (message_block
,
217 ACE_Message_Block (space_needed
),
220 // Initiate asynchronous accepts
221 if (this->asynch_accept_
.accept (*message_block
,
227 this->addr_family_
) == -1)
230 message_block
->release ();
236 template <class HANDLER
> void
237 ACE_Asynch_Acceptor
<HANDLER
>::handle_accept (const ACE_Asynch_Accept::Result
&result
)
239 ACE_TRACE ("ACE_Asynch_Acceptor<>::handle_accept");
241 // Variable for error tracking
244 // If the asynchronous accept fails.
245 if (!result
.success () || result
.accept_handle () == ACE_INVALID_HANDLE
)
250 #if defined (ACE_WIN32)
251 // In order to use accept handle with other Window Sockets 1.1
252 // functions, we call the setsockopt function with the
253 // SO_UPDATE_ACCEPT_CONTEXT option. This option initializes the
254 // socket so that other Windows Sockets routines to access the
257 ACE_OS::setsockopt (result
.accept_handle (),
259 SO_UPDATE_ACCEPT_CONTEXT
,
260 (char *) &this->listen_handle_
,
261 sizeof (this->listen_handle_
)) == -1)
265 #endif /* ACE_WIN32 */
268 ACE_INET_Addr local_address
;
269 ACE_INET_Addr remote_address
;
271 (this->validate_new_connection_
|| this->pass_addresses_
))
272 // Parse the addresses.
273 this->parse_address (result
,
277 // Validate remote address
279 this->validate_new_connection_
&&
280 (this->validate_connection (result
, remote_address
, local_address
) == -1))
285 HANDLER
*new_handler
= 0;
288 // The Template method
289 new_handler
= this->make_handler ();
290 if (new_handler
== 0)
299 // Update the Proactor unless make_handler() or constructed handler
301 if (new_handler
->proactor () == 0)
302 new_handler
->proactor (this->proactor ());
304 // Pass the addresses
305 if (this->pass_addresses_
)
306 new_handler
->addresses (remote_address
,
310 if (result
.act () != 0)
311 new_handler
->act (result
.act ());
313 // Set up the handler's new handle value
314 new_handler
->handle (result
.accept_handle ());
316 // Initiate the handler
317 new_handler
->open (result
.accept_handle (),
318 result
.message_block ());
321 // On failure, no choice but to close the socket
323 result
.accept_handle() != ACE_INVALID_HANDLE
)
324 ACE_OS::closesocket (result
.accept_handle ());
326 // Delete the dynamically allocated message_block
327 result
.message_block ().release ();
329 // Start off another asynchronous accept to keep the backlog going,
330 // unless we closed the listen socket already (from the destructor),
331 // or this callback is the result of a canceled/aborted accept.
332 if (this->should_reissue_accept () &&
333 this->listen_handle_
!= ACE_INVALID_HANDLE
334 #if defined (ACE_WIN32)
335 && result
.error () != ERROR_OPERATION_ABORTED
337 && result
.error () != ECANCELED
340 this->accept (this->bytes_to_read_
, result
.act ());
343 template <class HANDLER
> int
344 ACE_Asynch_Acceptor
<HANDLER
>::validate_connection
345 (const ACE_Asynch_Accept::Result
& /* result */,
346 const ACE_INET_Addr
& /* remote */,
347 const ACE_INET_Addr
& /* local */)
349 // Default implementation always validates the remote address.
353 template <class HANDLER
> int
354 ACE_Asynch_Acceptor
<HANDLER
>::cancel ()
356 ACE_TRACE ("ACE_Asynch_Acceptor<>::cancel");
358 // All I/O operations that are canceled will complete with the error
359 // ERROR_OPERATION_ABORTED. All completion notifications for the I/O
360 // operations will occur normally.
361 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
362 return (int) ::CancelIo (this->listen_handle_
);
365 return this->asynch_accept_
.cancel();
366 #endif /* defined (ACE_HAS_WIN32_OVERLAPPED_IO) */
369 template <class HANDLER
> void
370 ACE_Asynch_Acceptor
<HANDLER
>::parse_address (const
371 ACE_Asynch_Accept::Result
&result
,
372 ACE_INET_Addr
&remote_address
,
373 ACE_INET_Addr
&local_address
)
375 ACE_TRACE ("ACE_Asynch_Acceptor<>::parse_address");
377 #if defined (ACE_HAS_AIO_CALLS)
379 // Use an ACE_SOCK to get the addresses - it knows how to deal with
380 // ACE_INET_Addr objects and get IPv4/v6 addresses.
381 ACE_SOCK_Stream
str (result
.accept_handle ());
382 str
.get_local_addr (local_address
);
383 str
.get_remote_addr (remote_address
);
385 #elif defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
387 ACE_Message_Block
&message_block
= result
.message_block ();
389 sockaddr
*local_addr
= 0;
390 sockaddr
*remote_addr
= 0;
393 // This matches setup in accept().
394 size_t addr_size
= sizeof (sockaddr_in
) + 16;
395 #if defined (ACE_HAS_IPV6)
396 if (this->addr_family_
== PF_INET6
)
397 addr_size
= sizeof (sockaddr_in6
) + 16;
398 #endif /* ACE_HAS_IPV6 */
400 ::GetAcceptExSockaddrs (message_block
.rd_ptr (),
401 static_cast<DWORD
> (this->bytes_to_read_
),
402 static_cast<DWORD
> (addr_size
),
403 static_cast<DWORD
> (addr_size
),
409 local_address
.set (reinterpret_cast<sockaddr_in
*> (local_addr
),
411 remote_address
.set (reinterpret_cast<sockaddr_in
*> (remote_addr
),
416 #endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
420 template <class HANDLER
> ACE_HANDLE
421 ACE_Asynch_Acceptor
<HANDLER
>::handle () const
423 return this->listen_handle_
;
426 template <class HANDLER
> void
427 ACE_Asynch_Acceptor
<HANDLER
>::handle (ACE_HANDLE h
)
429 ACE_Handler::handle (h
);
432 template <class HANDLER
> ACE_Asynch_Accept
&
433 ACE_Asynch_Acceptor
<HANDLER
>::asynch_accept ()
435 return this->asynch_accept_
;
438 template <class HANDLER
> HANDLER
*
439 ACE_Asynch_Acceptor
<HANDLER
>::make_handler ()
442 HANDLER
*handler
= 0;
443 ACE_NEW_RETURN (handler
,
449 template <class HANDLER
> bool
450 ACE_Asynch_Acceptor
<HANDLER
>::pass_addresses () const
452 return this->pass_addresses_
;
455 template <class HANDLER
> void
456 ACE_Asynch_Acceptor
<HANDLER
>::pass_addresses (bool new_value
)
458 this->pass_addresses_
= new_value
;
461 template <class HANDLER
> bool
462 ACE_Asynch_Acceptor
<HANDLER
>::validate_new_connection () const
464 return this->validate_new_connection_
;
467 template <class HANDLER
> void
468 ACE_Asynch_Acceptor
<HANDLER
>::validate_new_connection (bool new_value
)
470 this->validate_new_connection_
= new_value
;
473 template <class HANDLER
> int
474 ACE_Asynch_Acceptor
<HANDLER
>::reissue_accept () const
476 return this->reissue_accept_
;
479 template <class HANDLER
> void
480 ACE_Asynch_Acceptor
<HANDLER
>::reissue_accept (int new_value
)
482 this->reissue_accept_
= new_value
;
485 template <class HANDLER
> size_t
486 ACE_Asynch_Acceptor
<HANDLER
>::bytes_to_read () const
488 return this->bytes_to_read_
;
491 template <class HANDLER
> void
492 ACE_Asynch_Acceptor
<HANDLER
>::bytes_to_read (size_t new_value
)
494 this->bytes_to_read_
= new_value
;
497 template <class HANDLER
> int
498 ACE_Asynch_Acceptor
<HANDLER
>::should_reissue_accept ()
500 return this->reissue_accept_
;
503 ACE_END_VERSIONED_NAMESPACE_DECL
505 #endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
506 #endif /* ACE_ASYNCH_ACCEPTOR_C */