diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-03-21 01:24:34 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-03-21 01:24:34 +0000 |
commit | 62eddb6c9a459b4b4dce956a2325559e7e92092c (patch) | |
tree | 165cfc1a241b144b5d4eba5ff53033ed181934ce /ace | |
parent | f4a8227f3e86e6ba6c6e74efed6caef2493750eb (diff) | |
download | ATCD-62eddb6c9a459b4b4dce956a2325559e7e92092c.tar.gz |
ChangeLogTag:Sat Mar 20 19:10:37 1999 Carlos O'Ryan <coryan@cs.wustl.edu>
Diffstat (limited to 'ace')
-rw-r--r-- | ace/Connector.cpp | 110 | ||||
-rw-r--r-- | ace/Connector.h | 53 | ||||
-rw-r--r-- | ace/Strategies_T.cpp | 182 | ||||
-rw-r--r-- | ace/Strategies_T.h | 29 |
4 files changed, 324 insertions, 50 deletions
diff --git a/ace/Connector.cpp b/ace/Connector.cpp index cccd932ac52..1d43c5e6e74 100644 --- a/ace/Connector.cpp +++ b/ace/Connector.cpp @@ -102,6 +102,28 @@ ACE_Connector<SH, PR_CO_2>::connect_svc_handler (SVC_HANDLER *&svc_handler, } template <class SH, PR_CO_1> int +ACE_Connector<SH, PR_CO_2>::connect_svc_handler (SVC_HANDLER *&svc_handler, + SVC_HANDLER *&sh_copy, + const PR_AD &remote_addr, + ACE_Time_Value *timeout, + const PR_AD &local_addr, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::connect_svc_handler"); + + sh_copy = svc_handler; + return this->connector_.connect (svc_handler->peer (), + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); +} + +template <class SH, PR_CO_1> int ACE_Connector<SH, PR_CO_2>::open (ACE_Reactor *r, int flags) { ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::open"); @@ -338,6 +360,46 @@ ACE_Connector<SH, PR_CO_2>::connect (SH *&sh, int flags, int perms) { + return this->connect_i (sh, + 0, + remote_addr, + synch_options, + local_addr, + reuse_addr, + flags, + perms); +} + +template <class SH, PR_CO_1> int +ACE_Connector<SH, PR_CO_2>::connect (SH *&sh, + SH *&sh_copy, + const PR_AD &remote_addr, + const ACE_Synch_Options &synch_options, + const PR_AD &local_addr, + int reuse_addr, + int flags, + int perms) +{ + return this->connect_i (sh, + &sh_copy, + remote_addr, + synch_options, + local_addr, + reuse_addr, + flags, + perms); +} + +template <class SH, PR_CO_1> int +ACE_Connector<SH, PR_CO_2>::connect_i (SH *&sh, + SH **sh_copy, + const PR_AD &remote_addr, + const ACE_Synch_Options &synch_options, + const PR_AD &local_addr, + int reuse_addr, + int flags, + int perms) +{ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::connect"); SH* new_sh = sh; @@ -355,14 +417,27 @@ ACE_Connector<SH, PR_CO_2>::connect (SH *&sh, else timeout = (ACE_Time_Value *) synch_options.time_value (); + int result; + if (sh_copy == 0) + result = this->connect_svc_handler (new_sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); + else + result = this->connect_svc_handler (new_sh, + *sh_copy, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); + // Delegate to connection strategy. - if (this->connect_svc_handler (new_sh, - remote_addr, - timeout, - local_addr, - reuse_addr, - flags, - perms) == -1) + if (result == -1) { if (use_reactor && errno == EWOULDBLOCK) { @@ -804,6 +879,27 @@ ACE_Strategy_Connector<SH, PR_CO_2>::connect_svc_handler } template <class SH, PR_CO_1> int +ACE_Strategy_Connector<SH, PR_CO_2>::connect_svc_handler + (SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_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 <class SH, PR_CO_1> int ACE_Strategy_Connector<SH, PR_CO_2>::activate_svc_handler (SVC_HANDLER *svc_handler) { return this->concurrency_strategy_->activate_svc_handler (svc_handler, this); diff --git a/ace/Connector.h b/ace/Connector.h index 27cf59d711e..eac69ebc942 100644 --- a/ace/Connector.h +++ b/ace/Connector.h @@ -142,6 +142,16 @@ public: int reuse_addr = 0, int flags = O_RDWR, int perms = 0); + + virtual int connect (SVC_HANDLER *&svc_handler, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults, + const ACE_PEER_CONNECTOR_ADDR &local_addr + = (ACE_PEER_CONNECTOR_ADDR &) ACE_PEER_CONNECTOR_ADDR_ANY, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); // Initiate connection of <svc_handler> to peer at <remote_addr> // using <synch_options>. If the caller wants to designate the // selected <local_addr> they can (and can also insist that the @@ -180,14 +190,14 @@ public: protected: // = Helpful typedefs. - typedef ACE_Svc_Tuple<SVC_HANDLER> + typedef ACE_Svc_Tuple<SVC_HANDLER> AST; - typedef ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_SYNCH_RW_MUTEX> + typedef ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_SYNCH_RW_MUTEX> MAP_MANAGER; - typedef ACE_Map_Iterator<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_SYNCH_RW_MUTEX> + typedef ACE_Map_Iterator<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_SYNCH_RW_MUTEX> MAP_ITERATOR; - typedef ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *> + typedef ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *> MAP_ENTRY; // = The following two methods define the Connector's strategies for @@ -209,6 +219,14 @@ protected: int reuse_addr, int flags, int perms); + virtual int connect_svc_handler (SVC_HANDLER *&svc_handler, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); // Bridge method for connecting the <svc_handler> to the // <remote_addr>. The default behavior delegates to the // <PEER_CONNECTOR::connect>. @@ -274,6 +292,16 @@ protected: // Cleanup the <handler_map_> and returns the appropriate // ACE_Svc_Tuple (which is 0 if there is no associated tuple). + virtual int connect_i (SVC_HANDLER *&svc_handler, + SVC_HANDLER **sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + const ACE_Synch_Options &synch_options, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); + // Implementation the connect() methods + MAP_MANAGER handler_map_; // Lookup table that maps an I/O handle to a SVC_HANDLER *. @@ -385,6 +413,23 @@ protected: // <SVC_HANDLER>. The default behavior delegates to the // <PEER_CONNECTOR::connect> in the <Connect_Strategy>. + virtual int connect_svc_handler (SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); + // Bridge method for connecting the new connection into the + // <SVC_HANDLER>. The default behavior delegates to the + // <PEER_CONNECTOR::connect> in the <Connect_Strategy>. + // <sh_copy> is used to obtain a copy of the <sh> pointer, but that + // can be kept in the stack; the motivation is a bit too long to + // include here, but basically we want to modify <sh> safely, using + // the internal locks in the Connect_Strategy, while saving a TSS + // copy in <sh_copy>, usually located in the stack. + virtual int activate_svc_handler (SVC_HANDLER *svc_handler); // Bridge method for activating a <SVC_HANDLER> with the appropriate // concurrency strategy. The default behavior of this method is to diff --git a/ace/Strategies_T.cpp b/ace/Strategies_T.cpp index d9c8c3a8843..916fafdc17d 100644 --- a/ace/Strategies_T.cpp +++ b/ace/Strategies_T.cpp @@ -291,6 +291,31 @@ ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler perms); } +template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int +ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler + (SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler"); + + int result = + this->connector_.connect (sh->peer (), + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms); + sh_copy = sh; + return result; +} + template <class SVC_HANDLER> int ACE_Process_Strategy<SVC_HANDLER>::open (size_t n_processes, ACE_Event_Handler *acceptor, @@ -622,51 +647,75 @@ ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_s // lock *before* registering the newly created handler with the // Reactor. { - CONNECTION_MAP_ENTRY *entry = 0; + // Synchronization is required here as the setting of the + // recyclable state must be done atomically with the finding and + // binding of the service handler in the cache. + ACE_GUARD_RETURN (MUTEX, ace_mon, this->lock_, -1); + + int result = this->connect_svc_handler_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + found); + if (result != 0) + return result; + + } + + // If it is a new connection, activate it. + // + // Note: This activation is outside the scope of the lock of the + // cached connector. This is necessary to avoid subtle deadlock + // conditions with this lock and the Reactor lock. + // + // @@ If an error occurs on activation, we should try to remove this + // entry from the internal table. + + if (!found) + if (this->activate_svc_handler (sh)) + return -1; + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_svc_handler + (SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms) +{ + int found = 0; + // This artificial scope is required since we need to let go of the + // lock *before* registering the newly created handler with the + // Reactor. + { // Synchronization is required here as the setting of the // recyclable state must be done atomically with the finding and // binding of the service handler in the cache. ACE_GUARD_RETURN (MUTEX, ace_mon, this->lock_, -1); - // Check if the user passed a hint svc_handler - if (sh != 0) - { - int result = this->check_hint_i (sh, - remote_addr, - timeout, - local_addr, - reuse_addr, - flags, - perms, - entry, - found); - if (result != 0) - return result; - } - - // If not found - if (!found) - { - int result = this->find_or_create_svc_handler_i (sh, - remote_addr, - timeout, - local_addr, - reuse_addr, - flags, - perms, - entry, - found); - if (result != 0) - return result; - } - - // For all successful cases: mark the <svc_handler> in the cache - // as being <in_use>. Therefore recyclable is BUSY. - entry->ext_id_.state (ACE_Recyclable::BUSY); - - // And increment the refcount - entry->ext_id_.increment (); + int result = this->connect_svc_handler_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + found); + sh_copy = sh; + + if (result != 0) + return result; + } // If it is a new connection, activate it. @@ -686,6 +735,61 @@ ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_s } template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int +ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_svc_handler_i + (SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + int& found) +{ + CONNECTION_MAP_ENTRY *entry = 0; + + // Check if the user passed a hint svc_handler + if (sh != 0) + { + int result = this->check_hint_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + entry, + found); + if (result != 0) + return result; + } + + // If not found + if (!found) + { + int result = this->find_or_create_svc_handler_i (sh, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms, + entry, + found); + if (result != 0) + return result; + } + + // For all successful cases: mark the <svc_handler> in the cache + // as being <in_use>. Therefore recyclable is BUSY. + entry->ext_id_.state (ACE_Recyclable::BUSY); + + // And increment the refcount + entry->ext_id_.increment (); + + return 0; +} + +template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cache (const void *recycling_act) { // Synchronization is required here as the setting of the recyclable diff --git a/ace/Strategies_T.h b/ace/Strategies_T.h index d8703ce1b47..4dab6f2c292 100644 --- a/ace/Strategies_T.h +++ b/ace/Strategies_T.h @@ -483,6 +483,18 @@ public: // The default behavior delegates to the <connect> method of the // <PEER_CONNECTOR::connect>. + virtual int connect_svc_handler (SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); + // The default behavior delegates to the <connect> method of the + // <PEER_CONNECTOR::connect>. + // Please check the documentation in Connector.h for more details. + void dump (void) const; // Dump the state of an object. @@ -766,6 +778,14 @@ public: int reuse_addr, int flags, int perms); + virtual int connect_svc_handler (SVC_HANDLER *&sh, + SVC_HANDLER *&sh_copy, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); // Checks to see if there is already a <SVC_HANDLER> in the cache // connected to the <remote_addr>. If so, we return this pointer. // Otherwise we establish the connection, put it into the cache, and @@ -843,6 +863,15 @@ protected: ACE_Hash_Map_Entry<ACE_Refcounted_Hash_Recyclable<ACE_PEER_CONNECTOR_ADDR>, SVC_HANDLER *> *&entry, int &found); + int connect_svc_handler_i (SVC_HANDLER *&sh, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + ACE_Time_Value *timeout, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms, + int &found); + int find_or_create_svc_handler_i (SVC_HANDLER *&sh, const ACE_PEER_CONNECTOR_ADDR &remote_addr, ACE_Time_Value *timeout, |