template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::register_handler (SVC_HANDLER *svc_handler, const ACE_Synch_Options &synch_options, int restart) { ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::register_handler"); // Can't do this if we don't have a Reactor. if (this->reactor () == 0) { errno = EINVAL; return -1; } else { this->svc_handler_ = svc_handler; this->restart_ = restart; ACE_Time_Value *tv = (ACE_Time_Value *) synch_options.time_value (); if (tv != 0 && this->reactor ()->schedule_timer (this, synch_options.arg (), *tv) == 0) return -1; else return this->reactor ()->register_handler (this, ACE_Event_Handler::ACCEPT_MASK); } }
void TAO_Blocked_Connect_Strategy::synch_options (ACE_Time_Value *timeout, ACE_Synch_Options &options) { if (timeout != 0) { // Blocking with a timeout options.set (ACE_Synch_Options::USE_TIMEOUT, *timeout); } else { // Making it sure it is blocking. options.set (0, ACE_Time_Value::zero); } }
void TAO_Reactive_Connect_Strategy::synch_options (ACE_Time_Value *timeout, ACE_Synch_Options &options) { if (timeout != 0) { options.set (ACE_Synch_Options::USE_REACTOR, *timeout); } else { // Making it sure it is blocking. options.set (ACE_Synch_Options::USE_REACTOR, ACE_Time_Value::zero); } }
int ACE_Name_Proxy::open (const ACE_INET_Addr &remote_addr, ACE_Synch_Options& options) { ACE_TRACE ("ACE_Name_Proxy::open"); ACE_Time_Value *timeout = 0; if (options[ACE_Synch_Options::USE_TIMEOUT]) timeout = const_cast<ACE_Time_Value *> (options.time_value ()); // Initiate the connection. return this->connector_.connect (this->peer_, remote_addr, timeout); }
template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept (SVC_HANDLER *svc_handler, ACE_PEER_ACCEPTOR_ADDR *remote_addr, const ACE_Synch_Options &synch_options, int restart, int reset_new_handle) { ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept"); // Note that if timeout == ACE_Time_Value (x, y) where (x > 0 || y > // 0) then this->connector_.connect() will block synchronously. If // <use_reactor> is set then we don't want this to happen (since we // want the ACE_Reactor to do the timeout asynchronously). // Therefore, we'll force this->connector_ to use ACE_Time_Value (0, // 0) in this case... ACE_Time_Value *timeout; int use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR]; if (use_reactor) timeout = (ACE_Time_Value *) &ACE_Time_Value::zero; else timeout = (ACE_Time_Value *) synch_options.time_value (); if (this->shared_accept (svc_handler, // stream remote_addr, // remote address timeout, // timeout restart, // restart reset_new_handle // reset new handler ) == -1) { if (use_reactor && errno == EWOULDBLOCK) // We couldn't accept right away, so let's wait in the // <ACE_Reactor>. this->register_handler (svc_handler, synch_options, restart); return -1; } return 0; }
int ACE_Token_Proxy::handle_options (ACE_Synch_Options &options, ACE_TOKEN_CONST::COND_VAR &cv) { // Some operation failed with EWOULDBLOCK. ACE_TRACE ("ACE_Token_Proxy::handle_options"); if (options[ACE_Synch_Options::USE_REACTOR] == 1) // Asynchronous. { // Save/restore errno. ACE_Errno_Guard error (errno); cv.mutex ().release (); ACE_RETURN (-1); } else // Synchronous. { // Block on condition variable. while (cv.wait ((ACE_Time_Value *) options.time_value ()) == -1) { // Note, this should obey whatever thread-specific // interrupt policy is currently in place... if (errno == EINTR) continue; // We come here if a timeout occurs or some serious // ACE_Condition object error. cv.mutex ().release (); ACELIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("condition variable wait") ACE_TEXT (" bombed.")), -1); } if (this->debug_) ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) unblocking %s.\n"), this->client_id ())); cv.mutex ().release (); return 0; // operation succeeded } }
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> 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... int result; 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; }
NNTDECL_SIGNALS_END void SocketClientAsync::connect_to(core::NetAddress const& addr, core::Timeout const& tm) { // connect. # ifdef USE_REACTOR_MODE ACE_Synch_Options opt = ACE_Synch_Options::synch; if (tm.infinate()) { opt.set(ACE_Synch_Options::USE_REACTOR, ACE_Time_Value::zero, 0); } else { opt.timeout(ace::type_cast<ACE_Time_Value>(tm)); } d_ptr->handler = new _aceasync_handler; # endif # ifdef USE_PROACTOR_MODE d_ptr->handler = new _ace_handler_async; d_ptr->handler->_owner = this; # endif // connect. # ifdef USE_REACTOR_MODE int ret = d_ptr->connector.connect(d_ptr->handler, ace::type_cast<ACE_INET_Addr>(addr), opt ); # endif # ifdef USE_PROACTOR_MODE int ret = d_ptr->connector.open(d_ptr->handler); if (ret == 0) { ret = d_ptr->connector.connect(ace::type_cast<ACE_INET_Addr>(addr)); } # endif if (ret == 0) { # ifdef USE_REACTOR_MODE emit(kSignalSuccess); # endif } else { emit(kSignalFailed); trace_msg("socketclient: failed to connect server."); } }