www.pudn.com > ACE-5.3 > Asynch_Connector.cpp, change:2002-06-15,size:8796b
/* -*- C++ -*- */
// Asynch_Connector.cpp,v 1.4 2002/06/16 00:32:32 shuston Exp
#ifndef ACE_ASYNCH_CONNECTOR_C
#define ACE_ASYNCH_CONNECTOR_C
#include "ace/Asynch_Connector.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
ACE_RCSID(ace, Asynch_Connector, "Asynch_Connector.cpp,v 1.4 2002/06/16 00:32:32 shuston Exp")
#if defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)
// This only works on platforms that support async I/O.
#include "ace/Flag_Manip.h"
#include "ace/Log_Msg.h"
#include "ace/Message_Block.h"
#include "ace/INET_Addr.h"
template <class HANDLER>
ACE_Asynch_Connector<HANDLER>::ACE_Asynch_Connector (void)
: pass_addresses_ (0),
validate_new_connection_ (0)
{
}
template <class HANDLER>
ACE_Asynch_Connector<HANDLER>::~ACE_Asynch_Connector (void)
{
//this->asynch_connect_.close ();
}
template <class HANDLER> int
ACE_Asynch_Connector<HANDLER>::open (int pass_addresses,
ACE_Proactor *proactor,
int validate_new_connection)
{
this->proactor (proactor);
this->pass_addresses_ = pass_addresses;
this->validate_new_connection_ = validate_new_connection;
// Initialize the ACE_Asynch_Connect
if (this->asynch_connect_.open (*this,
ACE_INVALID_HANDLE,
0,
this->proactor ()) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_LIB_TEXT ("%p\n"),
ACE_LIB_TEXT ("ACE_Asynch_Connect::open")),
-1);
return 0;
}
template <class HANDLER> int
ACE_Asynch_Connector<HANDLER>::connect (const ACE_INET_Addr & remote_sap,
const ACE_INET_Addr & local_sap,
int reuse_addr,
const void *act)
{
// Initiate asynchronous connect
if (this->asynch_connect_.connect (ACE_INVALID_HANDLE,
remote_sap,
local_sap,
reuse_addr,
act) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_LIB_TEXT ("%p\n"),
ACE_LIB_TEXT ("ACE_Asynch_Connect::connect")),
-1);
return 0;
}
template <class HANDLER> void
ACE_Asynch_Connector<HANDLER>::handle_connect (const ACE_Asynch_Connect::Result &result)
{
// Variable for error tracking
int error = 0;
// If the asynchronous connect fails.
if (!result.success () ||
result.connect_handle () == ACE_INVALID_HANDLE)
{
error = 1;
}
if (result.error () != 0)
{
error = 1;
}
// set blocking mode
if (!error &&
ACE_Flag_Manip::clr_flags
(result.connect_handle (), ACE_NONBLOCK) != 0)
{
error = 1;
ACE_ERROR ((LM_ERROR,
ACE_LIB_TEXT ("%p\n"),
ACE_LIB_TEXT ("ACE_Asynch_Connector::handle_connect : Set blocking mode")));
}
// Parse the addresses.
ACE_INET_Addr local_address;
ACE_INET_Addr remote_address;
if (!error &&
(this->validate_new_connection_ || this->pass_addresses_))
this->parse_address (result,
remote_address,
local_address);
// Call validate_connection even if there was an error - it's the only
// way the application can learn the connect disposition.
if (this->validate_new_connection_ &&
this->validate_connection (result, remote_address, local_address) == -1)
{
error = 1;
}
HANDLER *new_handler = 0;
if (!error)
{
// The Template method
new_handler = this->make_handler ();
if (new_handler == 0)
{
error = 1;
ACE_ERROR ((LM_ERROR,
ACE_LIB_TEXT ("%p\n"),
ACE_LIB_TEXT ("ACE_Asynch_Connector::handle_connect : Making of new handler failed")));
}
}
// If no errors
if (!error)
{
// Update the Proactor.
new_handler->proactor (this->proactor ());
// Pass the addresses
if (this->pass_addresses_)
new_handler->addresses (remote_address,
local_address);
// Pass the ACT
if (result.act () != 0)
new_handler->act (result.act ());
// Set up the handler's new handle value
new_handler->handle (result.connect_handle ());
ACE_Message_Block mb;
// Initiate the handler with empty message block;
new_handler->open (result.connect_handle (), mb);
}
// On failure, no choice but to close the socket
if (error &&
result.connect_handle() != ACE_INVALID_HANDLE)
ACE_OS::closesocket (result.connect_handle ());
}
template <class HANDLER> int
ACE_Asynch_Connector<HANDLER>::validate_connection
(const ACE_Asynch_Connect::Result &,
const ACE_INET_Addr & /* remote_address */,
const ACE_INET_Addr & /* local_address */)
{
// Default implementation always validates the remote address.
return 0;
}
template <class HANDLER> int
ACE_Asynch_Connector<HANDLER>::cancel (void)
{
return this->asynch_connect_.cancel ();
}
template <class HANDLER> void
ACE_Asynch_Connector<HANDLER>::parse_address (const ACE_Asynch_Connect::Result &result,
ACE_INET_Addr &remote_address,
ACE_INET_Addr &local_address)
{
// Getting the addresses.
sockaddr_in local_addr;
sockaddr_in remote_addr;
// Get the length.
int local_size = sizeof (local_addr);
int remote_size = sizeof (remote_addr);
// Get the local address.
if (ACE_OS::getsockname (result.connect_handle (),
ACE_reinterpret_cast (sockaddr *,
&local_addr),
&local_size) 0)
ACE_ERROR ((LM_ERROR,
ACE_LIB_TEXT("%p\n"),
ACE_LIB_TEXT("ACE_Asynch_Connector::<getsockname> failed")));
// Get the remote address.
if (ACE_OS::getpeername (result.connect_handle (),
ACE_reinterpret_cast (sockaddr *,
&remote_addr),
&remote_size) 0)
ACE_ERROR ((LM_ERROR,
ACE_LIB_TEXT("%p\n"),
ACE_LIB_TEXT("ACE_Asynch_Connector::<getpeername> failed")));
// Set the addresses.
local_address.set (&local_addr, local_size);
remote_address.set (&remote_addr, remote_size);
#if 0
// @@ Just debugging.
char local_address_buf [BUFSIZ];
char remote_address_buf [BUFSIZ];
if (local_address.addr_to_string (local_address_buf,
sizeof local_address_buf) == -1)
ACE_ERROR ((LM_ERROR,
"Error:%p:can't obtain local_address's address string"));
ACE_DEBUG ((LM_DEBUG,
"ACE_Asynch_Connector<HANDLER>::parse_address : "\
"Local address %s\n",
local_address_buf));
if (remote_address.addr_to_string (remote_address_buf,
sizeof remote_address_buf) == -1)
ACE_ERROR ((LM_ERROR,
"Error:%p:can't obtain remote_address's address string"));
ACE_DEBUG ((LM_DEBUG,
"ACE_Asynch_Connector<HANDLER>::parse_address : "\
"Remote address %s\n",
remote_address_buf));
#endif /* 0 */
return;
}
template <class HANDLER> ACE_Asynch_Connect &
ACE_Asynch_Connector<HANDLER>::asynch_connect (void)
{
return this->asynch_connect_;
}
template <class HANDLER> HANDLER *
ACE_Asynch_Connector<HANDLER>::make_handler (void)
{
// Default behavior
HANDLER *handler = 0;
ACE_NEW_RETURN (handler, HANDLER, 0);
return handler;
}
template <class HANDLER> int
ACE_Asynch_Connector<HANDLER>::pass_addresses (void) const
{
return this->pass_addresses_;
}
template <class HANDLER> void
ACE_Asynch_Connector<HANDLER>::pass_addresses (int new_value)
{
this->pass_addresses_ = new_value;
}
template <class HANDLER> int
ACE_Asynch_Connector<HANDLER>::validate_new_connection (void) const
{
return this->validate_new_connection_;
}
template <class HANDLER> void
ACE_Asynch_Connector<HANDLER>::validate_new_connection (int new_value)
{
this->validate_new_connection_ = new_value;
}
#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
#endif /* ACE_ASYNCH_CONNECTOR_C */