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)
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 ()
24 : pass_addresses_ (false),
25 validate_new_connection_ (false)
29 template <class HANDLER
> int
30 ACE_Asynch_Connector
<HANDLER
>::open (bool pass_addresses
,
31 ACE_Proactor
*proactor
,
32 bool validate_new_connection
)
34 this->proactor (proactor
);
35 this->pass_addresses_
= pass_addresses
;
36 this->validate_new_connection_
= validate_new_connection
;
38 // Initialize the ACE_Asynch_Connect
39 if (this->asynch_connect_
.open (*this,
42 this->proactor ()) == -1)
43 ACELIB_ERROR_RETURN ((LM_ERROR
,
45 ACE_TEXT ("ACE_Asynch_Connect::open")),
50 template <class HANDLER
> int
51 ACE_Asynch_Connector
<HANDLER
>::connect (const ACE_INET_Addr
& remote_sap
,
52 const ACE_INET_Addr
& local_sap
,
56 // Initiate asynchronous connect
57 if (this->asynch_connect_
.connect (ACE_INVALID_HANDLE
,
62 ACELIB_ERROR_RETURN ((LM_ERROR
,
64 ACE_TEXT ("ACE_Asynch_Connect::connect")),
69 template <class HANDLER
> void
70 ACE_Asynch_Connector
<HANDLER
>::handle_connect (const ACE_Asynch_Connect::Result
&result
)
72 // Variable for error tracking
75 // If the asynchronous connect fails.
76 if (!result
.success () ||
77 result
.connect_handle () == ACE_INVALID_HANDLE
)
82 if (result
.error () != 0)
90 (result
.connect_handle (), ACE_NONBLOCK
) != 0)
93 ACELIB_ERROR ((LM_ERROR
,
95 ACE_TEXT ("ACE_Asynch_Connector::handle_connect : Set blocking mode")));
98 // Parse the addresses.
99 ACE_INET_Addr local_address
;
100 ACE_INET_Addr remote_address
;
102 (this->validate_new_connection_
|| this->pass_addresses_
))
103 this->parse_address (result
,
107 // Call validate_connection even if there was an error - it's the only
108 // way the application can learn the connect disposition.
109 if (this->validate_new_connection_
&&
110 this->validate_connection (result
, remote_address
, local_address
) == -1)
115 HANDLER
*new_handler
= 0;
118 // The Template method
119 new_handler
= this->make_handler ();
120 if (new_handler
== 0)
123 ACELIB_ERROR ((LM_ERROR
,
125 ACE_TEXT ("ACE_Asynch_Connector::handle_connect : Making of new handler failed")));
132 // Update the Proactor.
133 new_handler
->proactor (this->proactor ());
135 // Pass the addresses
136 if (this->pass_addresses_
)
137 new_handler
->addresses (remote_address
,
141 if (result
.act () != 0)
142 new_handler
->act (result
.act ());
144 // Set up the handler's new handle value
145 new_handler
->handle (result
.connect_handle ());
147 ACE_Message_Block mb
;
149 // Initiate the handler with empty message block;
150 new_handler
->open (result
.connect_handle (), mb
);
153 // On failure, no choice but to close the socket
155 result
.connect_handle() != ACE_INVALID_HANDLE
)
156 ACE_OS::closesocket (result
.connect_handle ());
159 template <class HANDLER
> int
160 ACE_Asynch_Connector
<HANDLER
>::validate_connection
161 (const ACE_Asynch_Connect::Result
&,
162 const ACE_INET_Addr
& /* remote_address */,
163 const ACE_INET_Addr
& /* local_address */)
165 // Default implementation always validates the remote address.
169 template <class HANDLER
> int
170 ACE_Asynch_Connector
<HANDLER
>::cancel ()
172 return this->asynch_connect_
.cancel ();
175 template <class HANDLER
> void
176 ACE_Asynch_Connector
<HANDLER
>::parse_address (const ACE_Asynch_Connect::Result
&result
,
177 ACE_INET_Addr
&remote_address
,
178 ACE_INET_Addr
&local_address
)
180 #if defined (ACE_HAS_IPV6)
181 // Getting the addresses.
182 sockaddr_in6 local_addr
;
183 sockaddr_in6 remote_addr
;
185 // Getting the addresses.
186 sockaddr_in local_addr
;
187 sockaddr_in remote_addr
;
188 #endif /* ACE_HAS_IPV6 */
191 int local_size
= sizeof (local_addr
);
192 int remote_size
= sizeof (remote_addr
);
194 // Get the local address.
195 if (ACE_OS::getsockname (result
.connect_handle (),
196 reinterpret_cast<sockaddr
*> (&local_addr
),
198 ACELIB_ERROR ((LM_ERROR
,
200 ACE_TEXT("ACE_Asynch_Connector::<getsockname> failed")));
202 // Get the remote address.
203 if (ACE_OS::getpeername (result
.connect_handle (),
204 reinterpret_cast<sockaddr
*> (&remote_addr
),
206 ACELIB_ERROR ((LM_ERROR
,
208 ACE_TEXT("ACE_Asynch_Connector::<getpeername> failed")));
210 // Set the addresses.
211 local_address
.set (reinterpret_cast<sockaddr_in
*> (&local_addr
),
213 remote_address
.set (reinterpret_cast<sockaddr_in
*> (&remote_addr
),
220 template <class HANDLER
> ACE_Asynch_Connect
&
221 ACE_Asynch_Connector
<HANDLER
>::asynch_connect ()
223 return this->asynch_connect_
;
226 template <class HANDLER
> HANDLER
*
227 ACE_Asynch_Connector
<HANDLER
>::make_handler ()
230 HANDLER
*handler
= 0;
231 ACE_NEW_RETURN (handler
, HANDLER
, 0);
235 template <class HANDLER
> bool
236 ACE_Asynch_Connector
<HANDLER
>::pass_addresses () const
238 return this->pass_addresses_
;
241 template <class HANDLER
> void
242 ACE_Asynch_Connector
<HANDLER
>::pass_addresses (bool new_value
)
244 this->pass_addresses_
= new_value
;
247 template <class HANDLER
> bool
248 ACE_Asynch_Connector
<HANDLER
>::validate_new_connection () const
250 return this->validate_new_connection_
;
253 template <class HANDLER
> void
254 ACE_Asynch_Connector
<HANDLER
>::validate_new_connection (bool new_value
)
256 this->validate_new_connection_
= new_value
;
259 ACE_END_VERSIONED_NAMESPACE_DECL
261 #endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
262 #endif /* ACE_ASYNCH_CONNECTOR_CPP */