1 #ifndef ACE_ASYNCH_CONNECTOR_CPP
2 #define ACE_ASYNCH_CONNECTOR_CPP
4 #include "ace/Asynch_Connector.h"
6 #if !defined (ACE_LACKS_PRAGMA_ONCE)
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
10 #if (defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)) && !defined(ACE_HAS_WINCE)
11 // This only works on platforms that support async I/O.
13 #include "ace/OS_NS_sys_socket.h"
14 #include "ace/OS_Memory.h"
15 #include "ace/Flag_Manip.h"
16 #include "ace/Log_Category.h"
17 #include "ace/Message_Block.h"
18 #include "ace/INET_Addr.h"
20 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
22 template <class HANDLER
>
23 ACE_Asynch_Connector
<HANDLER
>::ACE_Asynch_Connector (void)
24 : pass_addresses_ (false),
25 validate_new_connection_ (false)
29 template <class HANDLER
>
30 ACE_Asynch_Connector
<HANDLER
>::~ACE_Asynch_Connector (void)
32 //this->asynch_connect_.close ();
35 template <class HANDLER
> int
36 ACE_Asynch_Connector
<HANDLER
>::open (bool pass_addresses
,
37 ACE_Proactor
*proactor
,
38 bool validate_new_connection
)
40 this->proactor (proactor
);
41 this->pass_addresses_
= pass_addresses
;
42 this->validate_new_connection_
= validate_new_connection
;
44 // Initialize the ACE_Asynch_Connect
45 if (this->asynch_connect_
.open (*this,
48 this->proactor ()) == -1)
49 ACELIB_ERROR_RETURN ((LM_ERROR
,
51 ACE_TEXT ("ACE_Asynch_Connect::open")),
56 template <class HANDLER
> int
57 ACE_Asynch_Connector
<HANDLER
>::connect (const ACE_INET_Addr
& remote_sap
,
58 const ACE_INET_Addr
& local_sap
,
62 // Initiate asynchronous connect
63 if (this->asynch_connect_
.connect (ACE_INVALID_HANDLE
,
68 ACELIB_ERROR_RETURN ((LM_ERROR
,
70 ACE_TEXT ("ACE_Asynch_Connect::connect")),
75 template <class HANDLER
> void
76 ACE_Asynch_Connector
<HANDLER
>::handle_connect (const ACE_Asynch_Connect::Result
&result
)
78 // Variable for error tracking
81 // If the asynchronous connect fails.
82 if (!result
.success () ||
83 result
.connect_handle () == ACE_INVALID_HANDLE
)
88 if (result
.error () != 0)
96 (result
.connect_handle (), ACE_NONBLOCK
) != 0)
99 ACELIB_ERROR ((LM_ERROR
,
101 ACE_TEXT ("ACE_Asynch_Connector::handle_connect : Set blocking mode")));
104 // Parse the addresses.
105 ACE_INET_Addr local_address
;
106 ACE_INET_Addr remote_address
;
108 (this->validate_new_connection_
|| this->pass_addresses_
))
109 this->parse_address (result
,
113 // Call validate_connection even if there was an error - it's the only
114 // way the application can learn the connect disposition.
115 if (this->validate_new_connection_
&&
116 this->validate_connection (result
, remote_address
, local_address
) == -1)
121 HANDLER
*new_handler
= 0;
124 // The Template method
125 new_handler
= this->make_handler ();
126 if (new_handler
== 0)
129 ACELIB_ERROR ((LM_ERROR
,
131 ACE_TEXT ("ACE_Asynch_Connector::handle_connect : Making of new handler failed")));
138 // Update the Proactor.
139 new_handler
->proactor (this->proactor ());
141 // Pass the addresses
142 if (this->pass_addresses_
)
143 new_handler
->addresses (remote_address
,
147 if (result
.act () != 0)
148 new_handler
->act (result
.act ());
150 // Set up the handler's new handle value
151 new_handler
->handle (result
.connect_handle ());
153 ACE_Message_Block mb
;
155 // Initiate the handler with empty message block;
156 new_handler
->open (result
.connect_handle (), mb
);
159 // On failure, no choice but to close the socket
161 result
.connect_handle() != ACE_INVALID_HANDLE
)
162 ACE_OS::closesocket (result
.connect_handle ());
165 template <class HANDLER
> int
166 ACE_Asynch_Connector
<HANDLER
>::validate_connection
167 (const ACE_Asynch_Connect::Result
&,
168 const ACE_INET_Addr
& /* remote_address */,
169 const ACE_INET_Addr
& /* local_address */)
171 // Default implementation always validates the remote address.
175 template <class HANDLER
> int
176 ACE_Asynch_Connector
<HANDLER
>::cancel (void)
178 return this->asynch_connect_
.cancel ();
181 template <class HANDLER
> void
182 ACE_Asynch_Connector
<HANDLER
>::parse_address (const ACE_Asynch_Connect::Result
&result
,
183 ACE_INET_Addr
&remote_address
,
184 ACE_INET_Addr
&local_address
)
186 #if defined (ACE_HAS_IPV6)
187 // Getting the addresses.
188 sockaddr_in6 local_addr
;
189 sockaddr_in6 remote_addr
;
191 // Getting the addresses.
192 sockaddr_in local_addr
;
193 sockaddr_in remote_addr
;
194 #endif /* ACE_HAS_IPV6 */
197 int local_size
= sizeof (local_addr
);
198 int remote_size
= sizeof (remote_addr
);
200 // Get the local address.
201 if (ACE_OS::getsockname (result
.connect_handle (),
202 reinterpret_cast<sockaddr
*> (&local_addr
),
204 ACELIB_ERROR ((LM_ERROR
,
206 ACE_TEXT("ACE_Asynch_Connector::<getsockname> failed")));
208 // Get the remote address.
209 if (ACE_OS::getpeername (result
.connect_handle (),
210 reinterpret_cast<sockaddr
*> (&remote_addr
),
212 ACELIB_ERROR ((LM_ERROR
,
214 ACE_TEXT("ACE_Asynch_Connector::<getpeername> failed")));
216 // Set the addresses.
217 local_address
.set (reinterpret_cast<sockaddr_in
*> (&local_addr
),
219 remote_address
.set (reinterpret_cast<sockaddr_in
*> (&remote_addr
),
226 template <class HANDLER
> ACE_Asynch_Connect
&
227 ACE_Asynch_Connector
<HANDLER
>::asynch_connect (void)
229 return this->asynch_connect_
;
232 template <class HANDLER
> HANDLER
*
233 ACE_Asynch_Connector
<HANDLER
>::make_handler (void)
236 HANDLER
*handler
= 0;
237 ACE_NEW_RETURN (handler
, HANDLER
, 0);
241 template <class HANDLER
> bool
242 ACE_Asynch_Connector
<HANDLER
>::pass_addresses (void) const
244 return this->pass_addresses_
;
247 template <class HANDLER
> void
248 ACE_Asynch_Connector
<HANDLER
>::pass_addresses (bool new_value
)
250 this->pass_addresses_
= new_value
;
253 template <class HANDLER
> bool
254 ACE_Asynch_Connector
<HANDLER
>::validate_new_connection (void) const
256 return this->validate_new_connection_
;
259 template <class HANDLER
> void
260 ACE_Asynch_Connector
<HANDLER
>::validate_new_connection (bool new_value
)
262 this->validate_new_connection_
= new_value
;
265 ACE_END_VERSIONED_NAMESPACE_DECL
267 #endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
268 #endif /* ACE_ASYNCH_CONNECTOR_CPP */