summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorcoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-03-21 01:24:34 +0000
committercoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-03-21 01:24:34 +0000
commit62eddb6c9a459b4b4dce956a2325559e7e92092c (patch)
tree165cfc1a241b144b5d4eba5ff53033ed181934ce /ace
parentf4a8227f3e86e6ba6c6e74efed6caef2493750eb (diff)
downloadATCD-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.cpp110
-rw-r--r--ace/Connector.h53
-rw-r--r--ace/Strategies_T.cpp182
-rw-r--r--ace/Strategies_T.h29
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,