mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-01 18:13:48 +00:00
restructured repository based on following standards:
https://github.com/HW-Core/directory-structure
This commit is contained in:
999
modules/dep/acelite/ace/Connector.cpp
Normal file
999
modules/dep/acelite/ace/Connector.cpp
Normal file
@@ -0,0 +1,999 @@
|
||||
#ifndef ACE_CONNECTOR_CPP
|
||||
#define ACE_CONNECTOR_CPP
|
||||
|
||||
#include "ace/Connector.h"
|
||||
#include "ace/ACE.h"
|
||||
#include "ace/OS_NS_stdio.h"
|
||||
#include "ace/OS_NS_string.h"
|
||||
#include "ace/os_include/os_fcntl.h" /* Has ACE_NONBLOCK */
|
||||
|
||||
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_ALLOC_HOOK_DEFINE(ACE_Connector)
|
||||
|
||||
template <typename SVC_HANDLER>
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::ACE_NonBlocking_Connect_Handler (ACE_Connector_Base<SVC_HANDLER> &connector,
|
||||
SVC_HANDLER *sh,
|
||||
long id)
|
||||
: connector_ (connector),
|
||||
svc_handler_ (sh),
|
||||
cleanup_svc_handler_ (0),
|
||||
timer_id_ (id)
|
||||
{
|
||||
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::ACE_NonBlocking_Connect_Handler");
|
||||
|
||||
this->reference_counting_policy ().value
|
||||
(ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
|
||||
|
||||
if (this->svc_handler_ != 0 &&
|
||||
this->svc_handler_->reference_counting_policy ().value () ==
|
||||
ACE_Event_Handler::Reference_Counting_Policy::ENABLED)
|
||||
{
|
||||
// If SVC_HANDLER is reference counted then NBCH holds a reference
|
||||
// in cleanup_svc_handle_ which is both a pointer to SVC_HANDLER
|
||||
// and a flag that triggers remove_reference in NBCH destructor.
|
||||
this->cleanup_svc_handler_ = sh;
|
||||
this->cleanup_svc_handler_->add_reference ();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER>
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::~ACE_NonBlocking_Connect_Handler (void)
|
||||
{
|
||||
if (this->cleanup_svc_handler_)
|
||||
this->cleanup_svc_handler_->remove_reference ();
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER> SVC_HANDLER *
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::svc_handler (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::svc_handler");
|
||||
return this->svc_handler_;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER> long
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id");
|
||||
return this->timer_id_;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER> void
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id (long id)
|
||||
{
|
||||
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::timer_id");
|
||||
this->timer_id_ = id;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER> void
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::dump (void) const
|
||||
{
|
||||
#if defined (ACE_HAS_DUMP)
|
||||
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::dump");
|
||||
|
||||
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
|
||||
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("svc_handler_ = %x"), this->svc_handler_));
|
||||
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntimer_id_ = %d"), this->timer_id_));
|
||||
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
|
||||
#endif /* ACE_HAS_DUMP */
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER> bool
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::close (SVC_HANDLER *&sh)
|
||||
{
|
||||
// Make sure that we haven't already initialized the Svc_Handler.
|
||||
if (!this->svc_handler_)
|
||||
return false;
|
||||
|
||||
{
|
||||
// Exclusive access to the Reactor.
|
||||
ACE_GUARD_RETURN (ACE_Lock,
|
||||
ace_mon,
|
||||
this->reactor ()->lock (),
|
||||
0);
|
||||
|
||||
// Double check.
|
||||
if (!this->svc_handler_)
|
||||
return false;
|
||||
|
||||
// Remember the Svc_Handler.
|
||||
sh = this->svc_handler_;
|
||||
ACE_HANDLE h = sh->get_handle ();
|
||||
this->svc_handler_ = 0;
|
||||
|
||||
// Remove this handle from the set of non-blocking handles
|
||||
// in the Connector.
|
||||
this->connector_.non_blocking_handles ().remove (h);
|
||||
|
||||
// Cancel timer.
|
||||
if (this->reactor ()->cancel_timer (this->timer_id (),
|
||||
0,
|
||||
0) == -1)
|
||||
return false;
|
||||
|
||||
// Remove from Reactor.
|
||||
if (-1 == this->reactor ()->remove_handler (
|
||||
h,
|
||||
ACE_Event_Handler::ALL_EVENTS_MASK | ACE_Event_Handler::DONT_CALL))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename SVC_HANDLER> int
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_timeout
|
||||
(const ACE_Time_Value &tv,
|
||||
const void *arg)
|
||||
{
|
||||
// This method is called if a connection times out before completing.
|
||||
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_timeout");
|
||||
|
||||
SVC_HANDLER *svc_handler = 0;
|
||||
int const retval = this->close (svc_handler) ? 0 : -1;
|
||||
|
||||
// Forward to the SVC_HANDLER the <arg> that was passed in as a
|
||||
// magic cookie during ACE_Connector::connect(). This gives the
|
||||
// SVC_HANDLER an opportunity to take corrective action (e.g., wait
|
||||
// a few milliseconds and try to reconnect again.
|
||||
if (svc_handler != 0 && svc_handler->handle_timeout (tv, arg) == -1)
|
||||
svc_handler->handle_close (svc_handler->get_handle (),
|
||||
ACE_Event_Handler::TIMER_MASK);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
template <typename SVC_HANDLER> int
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input (ACE_HANDLE)
|
||||
{
|
||||
// Called when a failure occurs during asynchronous connection
|
||||
// establishment.
|
||||
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input");
|
||||
|
||||
SVC_HANDLER *svc_handler = 0;
|
||||
int const retval = this->close (svc_handler) ? 0 : -1;
|
||||
|
||||
// Close Svc_Handler.
|
||||
if (svc_handler != 0)
|
||||
{
|
||||
svc_handler->close (NORMAL_CLOSE_OPERATION);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER> int
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_close (ACE_HANDLE handle,
|
||||
ACE_Reactor_Mask m)
|
||||
{
|
||||
// epoll on Linux will, at least sometimes, return EPOLLERR when a connect
|
||||
// fails, triggering a total removal from the reactor. This is different from
|
||||
// select()-based systems which select the fd for read on a connect failure.
|
||||
// So just call handle_input() to rejoin common handling for a failed
|
||||
// connect.
|
||||
if (m == ACE_Event_Handler::ALL_EVENTS_MASK)
|
||||
return this->handle_input (handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER> int
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output (ACE_HANDLE handle)
|
||||
{
|
||||
// Called when a connection is establishment asynchronous.
|
||||
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output");
|
||||
|
||||
// Grab the connector ref before smashing ourselves in close().
|
||||
ACE_Connector_Base<SVC_HANDLER> &connector = this->connector_;
|
||||
SVC_HANDLER *svc_handler = 0;
|
||||
int const retval = this->close (svc_handler) ? 0 : -1;
|
||||
|
||||
if (svc_handler != 0)
|
||||
{
|
||||
connector.initialize_svc_handler (handle, svc_handler);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER> int
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_exception (ACE_HANDLE h)
|
||||
{
|
||||
// On Win32, the except mask must also be set for asynchronous
|
||||
// connects.
|
||||
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_exception");
|
||||
return this->handle_output (h);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER> int
|
||||
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::resume_handler (void)
|
||||
{
|
||||
return ACE_Event_Handler::ACE_EVENT_HANDLER_NOT_RESUMED;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> void
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::dump (void) const
|
||||
{
|
||||
#if defined (ACE_HAS_DUMP)
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::dump");
|
||||
|
||||
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
|
||||
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nflags_ = %d"), this->flags_));
|
||||
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
|
||||
#endif /* ACE_HAS_DUMP */
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::make_svc_handler (SVC_HANDLER *&sh)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::make_svc_handler");
|
||||
|
||||
if (sh == 0)
|
||||
ACE_NEW_RETURN (sh,
|
||||
SVC_HANDLER,
|
||||
-1);
|
||||
|
||||
// Set the reactor of the newly created <SVC_HANDLER> to the same
|
||||
// reactor that this <Connector> is using.
|
||||
sh->reactor (this->reactor ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::activate_svc_handler (SVC_HANDLER *svc_handler)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::activate_svc_handler");
|
||||
// No errors initially
|
||||
int error = 0;
|
||||
|
||||
// See if we should enable non-blocking I/O on the <svc_handler>'s
|
||||
// peer.
|
||||
if (ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK) != 0)
|
||||
{
|
||||
if (svc_handler->peer ().enable (ACE_NONBLOCK) == -1)
|
||||
error = 1;
|
||||
}
|
||||
// Otherwise, make sure it's disabled by default.
|
||||
else if (svc_handler->peer ().disable (ACE_NONBLOCK) == -1)
|
||||
error = 1;
|
||||
|
||||
// We are connected now, so try to open things up.
|
||||
if (error || svc_handler->open ((void *) this) == -1)
|
||||
{
|
||||
// Make sure to close down the <svc_handler> to avoid descriptor
|
||||
// leaks.
|
||||
// The connection was already made; so this close is a "normal"
|
||||
// close operation.
|
||||
svc_handler->close (NORMAL_CLOSE_OPERATION);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> PEER_CONNECTOR &
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::connector (void) const
|
||||
{
|
||||
return const_cast<PEER_CONNECTOR &> (this->connector_);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect_svc_handler
|
||||
(SVC_HANDLER *&svc_handler,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
|
||||
ACE_Time_Value *timeout,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
|
||||
int reuse_addr,
|
||||
int flags,
|
||||
int perms)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect_svc_handler");
|
||||
|
||||
return this->connector_.connect (svc_handler->peer (),
|
||||
remote_addr,
|
||||
timeout,
|
||||
local_addr,
|
||||
reuse_addr,
|
||||
flags,
|
||||
perms);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect_svc_handler
|
||||
(SVC_HANDLER *&svc_handler,
|
||||
SVC_HANDLER *&sh_copy,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
|
||||
ACE_Time_Value *timeout,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
|
||||
int reuse_addr,
|
||||
int flags,
|
||||
int perms)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect_svc_handler");
|
||||
|
||||
sh_copy = svc_handler;
|
||||
return this->connector_.connect (svc_handler->peer (),
|
||||
remote_addr,
|
||||
timeout,
|
||||
local_addr,
|
||||
reuse_addr,
|
||||
flags,
|
||||
perms);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::open (ACE_Reactor *r, int flags)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::open");
|
||||
this->reactor (r);
|
||||
this->flags_ = flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR>
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::ACE_Connector (ACE_Reactor *r,
|
||||
int flags)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::ACE_Connector");
|
||||
(void) this->open (r, flags);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect
|
||||
(SVC_HANDLER *&sh,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
|
||||
const ACE_Synch_Options &synch_options,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
|
||||
int reuse_addr,
|
||||
int flags,
|
||||
int perms)
|
||||
{
|
||||
// Initiate connection to peer.
|
||||
return this->connect_i (sh,
|
||||
0,
|
||||
remote_addr,
|
||||
synch_options,
|
||||
local_addr,
|
||||
reuse_addr,
|
||||
flags,
|
||||
perms);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect
|
||||
(SVC_HANDLER *&sh,
|
||||
SVC_HANDLER *&sh_copy,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
|
||||
const ACE_Synch_Options &synch_options,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
|
||||
int reuse_addr,
|
||||
int flags,
|
||||
int perms)
|
||||
{
|
||||
// Initiate connection to peer.
|
||||
return this->connect_i (sh,
|
||||
&sh_copy,
|
||||
remote_addr,
|
||||
synch_options,
|
||||
local_addr,
|
||||
reuse_addr,
|
||||
flags,
|
||||
perms);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect_i
|
||||
(SVC_HANDLER *&sh,
|
||||
SVC_HANDLER **sh_copy,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
|
||||
const ACE_Synch_Options &synch_options,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
|
||||
int reuse_addr,
|
||||
int flags,
|
||||
int perms)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect_i");
|
||||
|
||||
// If the user hasn't supplied us with a <SVC_HANDLER> we'll use the
|
||||
// factory method to create one. Otherwise, things will remain as
|
||||
// they are...
|
||||
if (this->make_svc_handler (sh) == -1)
|
||||
return -1;
|
||||
|
||||
ACE_Time_Value *timeout = 0;
|
||||
int const use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR];
|
||||
|
||||
if (use_reactor)
|
||||
timeout = const_cast<ACE_Time_Value *> (&ACE_Time_Value::zero);
|
||||
else
|
||||
timeout = const_cast<ACE_Time_Value *> (synch_options.time_value ());
|
||||
|
||||
int result;
|
||||
if (sh_copy == 0)
|
||||
result = this->connect_svc_handler (sh,
|
||||
remote_addr,
|
||||
timeout,
|
||||
local_addr,
|
||||
reuse_addr,
|
||||
flags,
|
||||
perms);
|
||||
else
|
||||
result = this->connect_svc_handler (sh,
|
||||
*sh_copy,
|
||||
remote_addr,
|
||||
timeout,
|
||||
local_addr,
|
||||
reuse_addr,
|
||||
flags,
|
||||
perms);
|
||||
|
||||
// Activate immediately if we are connected.
|
||||
if (result != -1)
|
||||
return this->activate_svc_handler (sh);
|
||||
|
||||
// Delegate to connection strategy.
|
||||
if (use_reactor && ACE_OS::last_error () == EWOULDBLOCK)
|
||||
{
|
||||
// If the connection hasn't completed and we are using
|
||||
// non-blocking semantics then register
|
||||
// ACE_NonBlocking_Connect_Handler with the ACE_Reactor so that
|
||||
// it will call us back when the connection is complete or we
|
||||
// timeout, whichever comes first...
|
||||
if (sh_copy == 0)
|
||||
result = this->nonblocking_connect (sh, synch_options);
|
||||
else
|
||||
result = this->nonblocking_connect (*sh_copy, synch_options);
|
||||
|
||||
// If for some reason the <nonblocking_connect> call failed, then <errno>
|
||||
// will be set to the new error. If the call succeeds, however,
|
||||
// we need to make sure that <errno> remains set to
|
||||
// <EWOULDBLOCK>.
|
||||
if (result == 0)
|
||||
errno = EWOULDBLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Save/restore errno.
|
||||
ACE_Errno_Guard error (errno);
|
||||
// Make sure to close down the service handler to avoid handle
|
||||
// leaks.
|
||||
if (sh_copy == 0)
|
||||
{
|
||||
if (sh)
|
||||
sh->close (CLOSE_DURING_NEW_CONNECTION);
|
||||
}
|
||||
else if (*sh_copy)
|
||||
(*sh_copy)->close (CLOSE_DURING_NEW_CONNECTION);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect_n
|
||||
(size_t n,
|
||||
SVC_HANDLER *sh[],
|
||||
typename PEER_CONNECTOR::PEER_ADDR remote_addrs[],
|
||||
ACE_TCHAR *failed_svc_handlers,
|
||||
const ACE_Synch_Options &synch_options)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
if (this->connect (sh[i], remote_addrs[i], synch_options) == -1
|
||||
&& !(synch_options[ACE_Synch_Options::USE_REACTOR]
|
||||
&& errno == EWOULDBLOCK))
|
||||
{
|
||||
result = -1;
|
||||
if (failed_svc_handlers != 0)
|
||||
// Mark this entry as having failed.
|
||||
failed_svc_handlers[i] = 1;
|
||||
}
|
||||
else if (failed_svc_handlers != 0)
|
||||
// Mark this entry as having succeeded.
|
||||
failed_svc_handlers[i] = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Cancel a <svc_handler> that was started asynchronously.
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::cancel (SVC_HANDLER *sh)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::cancel");
|
||||
|
||||
ACE_Event_Handler *handler =
|
||||
this->reactor ()->find_handler (sh->get_handle ());
|
||||
|
||||
if (handler == 0)
|
||||
return -1;
|
||||
|
||||
// find_handler() increments handler's refcount; ensure we decrement it.
|
||||
ACE_Event_Handler_var safe_handler (handler);
|
||||
|
||||
NBCH *nbch =
|
||||
dynamic_cast<NBCH *> (handler);
|
||||
|
||||
if (nbch == 0)
|
||||
return -1;
|
||||
|
||||
SVC_HANDLER *tmp_sh = 0;
|
||||
|
||||
if (nbch->close (tmp_sh) == false)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::nonblocking_connect
|
||||
(SVC_HANDLER *sh,
|
||||
const ACE_Synch_Options &synch_options)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::nonblocking_connect");
|
||||
|
||||
// Must have a valid Reactor for non-blocking connects to work.
|
||||
if (this->reactor () == 0)
|
||||
return -1;
|
||||
|
||||
// Register the pending SVC_HANDLER so that it can be activated
|
||||
// later on when the connection completes.
|
||||
|
||||
ACE_HANDLE handle = sh->get_handle ();
|
||||
long timer_id = -1;
|
||||
ACE_Time_Value *tv = 0;
|
||||
NBCH *nbch = 0;
|
||||
|
||||
ACE_NEW_RETURN (nbch,
|
||||
NBCH (*this,
|
||||
sh,
|
||||
-1),
|
||||
-1);
|
||||
|
||||
ACE_Event_Handler_var safe_nbch (nbch);
|
||||
|
||||
// Exclusive access to the Reactor.
|
||||
ACE_GUARD_RETURN (ACE_Lock, ace_mon, this->reactor ()->lock (), -1);
|
||||
|
||||
// Register handle with the reactor for connection events.
|
||||
ACE_Reactor_Mask mask = ACE_Event_Handler::CONNECT_MASK;
|
||||
if (this->reactor ()->register_handler (handle,
|
||||
nbch,
|
||||
mask) == -1)
|
||||
goto reactor_registration_failure;
|
||||
|
||||
// Add handle to non-blocking handle set.
|
||||
this->non_blocking_handles ().insert (handle);
|
||||
|
||||
// If we're starting connection under timer control then we need to
|
||||
// schedule a timeout with the ACE_Reactor.
|
||||
tv = const_cast<ACE_Time_Value *> (synch_options.time_value ());
|
||||
if (tv != 0)
|
||||
{
|
||||
timer_id =
|
||||
this->reactor ()->schedule_timer (nbch,
|
||||
synch_options.arg (),
|
||||
*tv);
|
||||
if (timer_id == -1)
|
||||
goto timer_registration_failure;
|
||||
|
||||
// Remember timer id.
|
||||
nbch->timer_id (timer_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
// Undo previous actions using the ol' "goto label and fallthru"
|
||||
// trick...
|
||||
timer_registration_failure:
|
||||
|
||||
// Remove from Reactor.
|
||||
this->reactor ()->remove_handler (handle, mask);
|
||||
|
||||
// Remove handle from the set of non-blocking handles.
|
||||
this->non_blocking_handles ().remove (handle);
|
||||
|
||||
/* FALLTHRU */
|
||||
|
||||
reactor_registration_failure:
|
||||
// Close the svc_handler
|
||||
|
||||
sh->close (CLOSE_DURING_NEW_CONNECTION);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR>
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::~ACE_Connector (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::~ACE_Connector");
|
||||
|
||||
this->close ();
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> void
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::initialize_svc_handler
|
||||
(ACE_HANDLE handle,
|
||||
SVC_HANDLER *svc_handler)
|
||||
{
|
||||
// Try to find out if the reactor uses event associations for the
|
||||
// handles it waits on. If so we need to reset it.
|
||||
bool reset_new_handle =
|
||||
this->reactor ()->uses_event_associations ();
|
||||
|
||||
if (reset_new_handle)
|
||||
this->connector_.reset_new_handle (handle);
|
||||
|
||||
// Transfer ownership of the ACE_HANDLE to the SVC_HANDLER.
|
||||
svc_handler->set_handle (handle);
|
||||
|
||||
typename PEER_CONNECTOR::PEER_ADDR raddr;
|
||||
|
||||
// Check to see if we're connected.
|
||||
if (svc_handler->peer ().get_remote_addr (raddr) != -1)
|
||||
this->activate_svc_handler (svc_handler);
|
||||
else // Somethings gone wrong, so close down...
|
||||
{
|
||||
#if defined (ACE_WIN32)
|
||||
// Win32 (at least prior to Windows 2000) has a timing problem.
|
||||
// If you check to see if the connection has completed too fast,
|
||||
// it will fail - so wait 35 milliseconds to let it catch up.
|
||||
ACE_Time_Value tv (0, ACE_NON_BLOCKING_BUG_DELAY);
|
||||
ACE_OS::sleep (tv);
|
||||
if (svc_handler->peer ().get_remote_addr (raddr) != -1)
|
||||
this->activate_svc_handler (svc_handler);
|
||||
else // do the svc handler close below...
|
||||
#endif /* ACE_WIN32 */
|
||||
svc_handler->close (NORMAL_CLOSE_OPERATION);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> void
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::reactor (ACE_Reactor *reactor)
|
||||
{
|
||||
this->reactor_ = reactor;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> ACE_Reactor *
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::reactor (void) const
|
||||
{
|
||||
return this->reactor_;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> ACE_Unbounded_Set<ACE_HANDLE> &
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::non_blocking_handles (void)
|
||||
{
|
||||
return this->non_blocking_handles_;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::close (void)
|
||||
{
|
||||
// If there are no non-blocking handle pending, return immediately.
|
||||
if (this->non_blocking_handles ().size () == 0)
|
||||
return 0;
|
||||
|
||||
// Exclusive access to the Reactor.
|
||||
ACE_GUARD_RETURN (ACE_Lock, ace_mon, this->reactor ()->lock (), -1);
|
||||
|
||||
// Go through all the non-blocking handles. It is necessary to
|
||||
// create a new iterator each time because we remove from the handle
|
||||
// set when we cancel the Svc_Handler.
|
||||
ACE_HANDLE *handle = 0;
|
||||
while (1)
|
||||
{
|
||||
ACE_Unbounded_Set_Iterator<ACE_HANDLE>
|
||||
iterator (this->non_blocking_handles ());
|
||||
if (!iterator.next (handle))
|
||||
break;
|
||||
|
||||
ACE_Event_Handler *handler =
|
||||
this->reactor ()->find_handler (*handle);
|
||||
if (handler == 0)
|
||||
{
|
||||
ACELIB_ERROR ((LM_ERROR,
|
||||
ACE_TEXT ("%t: Connector::close h %d, no handler\n"),
|
||||
*handle));
|
||||
// Remove handle from the set of non-blocking handles.
|
||||
this->non_blocking_handles ().remove (*handle);
|
||||
continue;
|
||||
}
|
||||
|
||||
// find_handler() incremented handler's refcount; ensure it's decremented
|
||||
ACE_Event_Handler_var safe_handler (handler);
|
||||
NBCH *nbch = dynamic_cast<NBCH *> (handler);
|
||||
if (nbch == 0)
|
||||
{
|
||||
ACELIB_ERROR ((LM_ERROR,
|
||||
ACE_TEXT ("%t: Connector::close h %d handler %@ ")
|
||||
ACE_TEXT ("not a legit handler\n"),
|
||||
*handle,
|
||||
handler));
|
||||
// Remove handle from the set of non-blocking handles.
|
||||
this->non_blocking_handles ().remove (*handle);
|
||||
continue;
|
||||
}
|
||||
SVC_HANDLER *svc_handler = nbch->svc_handler ();
|
||||
|
||||
// Cancel the non-blocking connection.
|
||||
this->cancel (svc_handler);
|
||||
|
||||
// Close the associated Svc_Handler.
|
||||
svc_handler->close (NORMAL_CLOSE_OPERATION);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::fini (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::fini");
|
||||
|
||||
return this->close ();
|
||||
}
|
||||
|
||||
// Hook called by the explicit dynamic linking facility.
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::init (int, ACE_TCHAR *[])
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::init");
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::suspend (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::suspend");
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::resume (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::resume");
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::info (ACE_TCHAR **strp, size_t length) const
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::info");
|
||||
ACE_TCHAR buf[BUFSIZ];
|
||||
|
||||
ACE_OS::sprintf (buf,
|
||||
ACE_TEXT ("%s\t %s"),
|
||||
ACE_TEXT ("ACE_Connector"),
|
||||
ACE_TEXT ("# connector factory\n"));
|
||||
|
||||
if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
|
||||
return -1;
|
||||
else
|
||||
ACE_OS::strsncpy (*strp, buf, length);
|
||||
return static_cast<int> (ACE_OS::strlen (buf));
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::open (ACE_Reactor *r,
|
||||
int flags)
|
||||
{
|
||||
ACE_TRACE ("ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::open");
|
||||
return this->open (r, 0, 0, 0, flags);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::open
|
||||
(ACE_Reactor *r,
|
||||
ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
|
||||
ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR> *conn_s,
|
||||
ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
|
||||
int flags)
|
||||
{
|
||||
ACE_TRACE ("ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::open");
|
||||
|
||||
this->reactor (r);
|
||||
|
||||
// @@ Not implemented yet.
|
||||
// this->flags_ = flags;
|
||||
ACE_UNUSED_ARG (flags);
|
||||
|
||||
// Initialize the creation strategy.
|
||||
|
||||
// First we decide if we need to clean up.
|
||||
if (this->creation_strategy_ != 0 &&
|
||||
this->delete_creation_strategy_ &&
|
||||
cre_s != 0)
|
||||
{
|
||||
delete this->creation_strategy_;
|
||||
this->creation_strategy_ = 0;
|
||||
this->delete_creation_strategy_ = false;
|
||||
}
|
||||
|
||||
if (cre_s != 0)
|
||||
this->creation_strategy_ = cre_s;
|
||||
else if (this->creation_strategy_ == 0)
|
||||
{
|
||||
ACE_NEW_RETURN (this->creation_strategy_,
|
||||
CREATION_STRATEGY (0, r),
|
||||
-1);
|
||||
this->delete_creation_strategy_ = true;
|
||||
}
|
||||
|
||||
|
||||
// Initialize the accept strategy.
|
||||
|
||||
if (this->connect_strategy_ != 0 &&
|
||||
this->delete_connect_strategy_ &&
|
||||
conn_s != 0)
|
||||
{
|
||||
delete this->connect_strategy_;
|
||||
this->connect_strategy_ = 0;
|
||||
this->delete_connect_strategy_ = false;
|
||||
}
|
||||
|
||||
if (conn_s != 0)
|
||||
this->connect_strategy_ = conn_s;
|
||||
else if (this->connect_strategy_ == 0)
|
||||
{
|
||||
ACE_NEW_RETURN (this->connect_strategy_,
|
||||
CONNECT_STRATEGY,
|
||||
-1);
|
||||
this->delete_connect_strategy_ = true;
|
||||
}
|
||||
|
||||
// Initialize the concurrency strategy.
|
||||
|
||||
if (this->concurrency_strategy_ != 0 &&
|
||||
this->delete_concurrency_strategy_ &&
|
||||
con_s != 0)
|
||||
{
|
||||
delete this->concurrency_strategy_;
|
||||
this->concurrency_strategy_ = 0;
|
||||
this->delete_concurrency_strategy_ = false;
|
||||
}
|
||||
|
||||
if (con_s != 0)
|
||||
this->concurrency_strategy_ = con_s;
|
||||
else if (this->concurrency_strategy_ == 0)
|
||||
{
|
||||
ACE_NEW_RETURN (this->concurrency_strategy_,
|
||||
CONCURRENCY_STRATEGY,
|
||||
-1);
|
||||
this->delete_concurrency_strategy_ = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR>
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::ACE_Strategy_Connector
|
||||
(ACE_Reactor *reactor,
|
||||
ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
|
||||
ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR> *conn_s,
|
||||
ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
|
||||
int flags)
|
||||
: base_type (reactor),
|
||||
creation_strategy_ (0),
|
||||
delete_creation_strategy_ (false),
|
||||
connect_strategy_ (0),
|
||||
delete_connect_strategy_ (false),
|
||||
concurrency_strategy_ (0),
|
||||
delete_concurrency_strategy_ (false)
|
||||
{
|
||||
ACE_TRACE ("ACE_Connector<SVC_HANDLER, PEER_CONNECTOR>::ACE_Strategy_Connector");
|
||||
|
||||
if (this->open (reactor, cre_s, conn_s, con_s, flags) == -1)
|
||||
ACELIB_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_Strategy_Connector::ACE_Strategy_Connector")));
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR>
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::~ACE_Strategy_Connector (void)
|
||||
{
|
||||
ACE_TRACE ("ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::~ACE_Strategy_Connector");
|
||||
|
||||
// Close down
|
||||
this->close ();
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::close (void)
|
||||
{
|
||||
if (this->delete_creation_strategy_)
|
||||
delete this->creation_strategy_;
|
||||
this->delete_creation_strategy_ = false;
|
||||
this->creation_strategy_ = 0;
|
||||
|
||||
if (this->delete_connect_strategy_)
|
||||
delete this->connect_strategy_;
|
||||
this->delete_connect_strategy_ = false;
|
||||
this->connect_strategy_ = 0;
|
||||
|
||||
if (this->delete_concurrency_strategy_)
|
||||
delete this->concurrency_strategy_;
|
||||
this->delete_concurrency_strategy_ = false;
|
||||
this->concurrency_strategy_ = 0;
|
||||
|
||||
return SUPER::close ();
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::make_svc_handler (SVC_HANDLER *&sh)
|
||||
{
|
||||
return this->creation_strategy_->make_svc_handler (sh);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect_svc_handler
|
||||
(SVC_HANDLER *&sh,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
|
||||
ACE_Time_Value *timeout,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
|
||||
int reuse_addr,
|
||||
int flags,
|
||||
int perms)
|
||||
{
|
||||
return this->connect_strategy_->connect_svc_handler (sh,
|
||||
remote_addr,
|
||||
timeout,
|
||||
local_addr,
|
||||
reuse_addr,
|
||||
flags,
|
||||
perms);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect_svc_handler
|
||||
(SVC_HANDLER *&sh,
|
||||
SVC_HANDLER *&sh_copy,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
|
||||
ACE_Time_Value *timeout,
|
||||
const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
|
||||
int reuse_addr,
|
||||
int flags,
|
||||
int perms)
|
||||
{
|
||||
return this->connect_strategy_->connect_svc_handler (sh,
|
||||
sh_copy,
|
||||
remote_addr,
|
||||
timeout,
|
||||
local_addr,
|
||||
reuse_addr,
|
||||
flags,
|
||||
perms);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> int
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::activate_svc_handler (SVC_HANDLER *svc_handler)
|
||||
{
|
||||
return this->concurrency_strategy_->activate_svc_handler (svc_handler, this);
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> ACE_Creation_Strategy<SVC_HANDLER> *
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::creation_strategy (void) const
|
||||
{
|
||||
return this->creation_strategy_;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR> *
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::connect_strategy (void) const
|
||||
{
|
||||
return this->connect_strategy_;
|
||||
}
|
||||
|
||||
template <typename SVC_HANDLER, typename PEER_CONNECTOR> ACE_Concurrency_Strategy<SVC_HANDLER> *
|
||||
ACE_Strategy_Connector<SVC_HANDLER, PEER_CONNECTOR>::concurrency_strategy (void) const
|
||||
{
|
||||
return this->concurrency_strategy_;
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
#endif /* ACE_CONNECTOR_C */
|
||||
Reference in New Issue
Block a user