diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-05-29 22:05:59 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-05-29 22:05:59 +0000 |
commit | 9f4b60aadddaa169aa8a7a981426ff72ee53a429 (patch) | |
tree | 06892196737aa7292430f1d45db17c2a6d06e6de | |
parent | 56cac35541517f786d6b52bb40d70872ea5036a7 (diff) | |
download | ATCD-9f4b60aadddaa169aa8a7a981426ff72ee53a429.tar.gz |
ChangeLogTag:Sat May 29 16:56:05 1999 Carlos O'Ryan <coryan@cs.wustl.edu>
-rw-r--r-- | TAO/ChangeLog-99c | 43 | ||||
-rw-r--r-- | TAO/tao/Connect.cpp | 564 | ||||
-rw-r--r-- | TAO/tao/Connect.h | 127 | ||||
-rw-r--r-- | TAO/tao/GIOP.cpp | 30 | ||||
-rw-r--r-- | TAO/tao/GIOP_Server_Request.cpp | 6 | ||||
-rw-r--r-- | TAO/tao/IIOP_Transport.cpp | 23 | ||||
-rw-r--r-- | TAO/tao/Request_Mux_Strategy.cpp | 5 | ||||
-rw-r--r-- | TAO/tao/Request_Mux_Strategy.h | 4 | ||||
-rw-r--r-- | TAO/tao/UIOP_Connect.cpp | 501 | ||||
-rw-r--r-- | TAO/tao/UIOP_Connect.h | 73 | ||||
-rw-r--r-- | TAO/tao/Wait_Strategy.cpp | 60 | ||||
-rw-r--r-- | TAO/tests/MT_Client/Makefile | 294 | ||||
-rw-r--r-- | TAO/tests/MT_Client/client.cpp | 14 | ||||
-rw-r--r-- | TAO/tests/MT_Client/server.conf | 2 | ||||
-rw-r--r-- | TAO/tests/MT_Client/simple-client.cpp | 97 |
15 files changed, 465 insertions, 1378 deletions
diff --git a/TAO/ChangeLog-99c b/TAO/ChangeLog-99c index 1669bfea8ae..ebcd43c2ae1 100644 --- a/TAO/ChangeLog-99c +++ b/TAO/ChangeLog-99c @@ -1,3 +1,46 @@ +Sat May 29 16:56:05 1999 Carlos O'Ryan <coryan@cs.wustl.edu> + + * tao/Connect.h: + * tao/Connect.cpp: + * tao/UIOP_Connect.h: + * tao/UIOP_Connect.cpp: + Removed unused classes, the RW, ST and MT variants for the + client connection handlers. + Also removed unused methods in the client connection handler. + + * tao/GIOP.cpp: + The GIOP::dump_msg() helper function prints out request id of + the message, this is useful when debugging complex interaction + between clients and servers. + + * tao/GIOP_Server_Request.cpp: + Minor cosmetic changes + + * tao/IIOP_Transport.cpp: + Return -1 in case of error from handle_client_input() + + * tao/Request_Mux_Strategy.h: + * tao/Request_Mux_Strategy.cpp: + Keep a separate variable to generate the request id numbers, and + actually generate a different request id for each request + + * tao/Wait_Strategy.cpp: + Track down if there was an error while receiving the reply, if + so then exit the event loop and return the error to the upper + layer. + Don't forget to register the handler for the + Wait_On_Leader_Follower strategy. + + * tests/MT_Client/Makefile: + * tests/MT_Client/client.cpp: + * tests/MT_Client/server.conf: + * tests/MT_Client/simple-client.cpp: + Added simple-client to the Makefile. + The server.conf file didn't have to use dynamic loading, the + service is statically configured. + Commented out debugging messages in client.cpp + Cleanup dead-code in simple-client.cpp + Sat May 29 14:02:41 1999 Alexander Babu Arulanthu <alex@cs.wustl.edu> * tao/Wait_Strategy.cpp: diff --git a/TAO/tao/Connect.cpp b/TAO/tao/Connect.cpp index 3083b339c90..aac5e5382b6 100644 --- a/TAO/tao/Connect.cpp +++ b/TAO/tao/Connect.cpp @@ -809,18 +809,15 @@ TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) // @@ For pluggable protocols, added a reference to the corresponding // transport obj. TAO_Client_Connection_Handler::TAO_Client_Connection_Handler (ACE_Thread_Manager *t) - : TAO_IIOP_Handler_Base (t == 0 ? TAO_ORB_Core_instance ()->thr_mgr () : t), - expecting_response_ (0), - input_available_ (0) + : TAO_IIOP_Handler_Base (t == 0 ? TAO_ORB_Core_instance ()->thr_mgr () : t) { // @@ Alex: Allocate this on-demand and use the orb_core to create - // the strategies. + // the strategies. TAO_ORB_Core *orb_core = TAO_ORB_Core_instance (); iiop_transport_ = new TAO_IIOP_Client_Transport (this, orb_core); } -// @@ Need to get rid of the Transport Objects! TAO_Client_Connection_Handler::~TAO_Client_Connection_Handler (void) { delete this->iiop_transport_; @@ -834,10 +831,18 @@ TAO_Client_Connection_Handler::transport (void) } // @@ Should I do something here to enable non-blocking?? (Alex). +// @@ Alex: I don't know if this is the place to do it, but the way to +// do it is: +// if (this->peer ().enable (ACE_NONBLOCK) == -1) +// return -1; +// Probably we will need to use the transport to decide if it is +// needed or not. int TAO_Client_Connection_Handler::open (void *) { + // @@ TODO: This flags should be set using the RT CORBA policies... + // Here is where we could enable all sorts of things such as // nonblock I/O, sock buf sizes, TCP no-delay, etc. @@ -883,70 +888,23 @@ TAO_Client_Connection_Handler::open (void *) } int -TAO_Client_Connection_Handler::send_request (TAO_ORB_Core *, - TAO_OutputCDR &, - int) -{ - errno = ENOTSUP; - return -1; -} - -int TAO_Client_Connection_Handler::handle_input (ACE_HANDLE) { // Call the waiter to handle the input. - return this->iiop_transport_->wait_strategy ()->handle_input (); -} - -int -TAO_Client_Connection_Handler::check_unexpected_data (void) -{ - // We're a client, so we're not expecting to see input. Still we - // better check what it is! - char ignored; - ssize_t ret = this->peer().recv (&ignored, - sizeof ignored, - MSG_PEEK); - switch (ret) - { - case 0: - case -1: - // 0 is a graceful shutdown - // -1 is a somewhat ugly shutdown - // - // Both will result in us returning -1 and this connection - // getting closed - // - if (TAO_orbdebug) - ACE_DEBUG ((LM_WARNING, - "Client_Connection_Handler::handle_input: " - "closing connection on fd %d\n", - this->peer().get_handle ())); - break; - - case 1: - // - // @@ Fix me!! - // - // This should be the close connection message. Since we don't - // handle this yet, log an error, and close the connection. - ACE_ERROR ((LM_WARNING, - "Client_Connection_Handler::handle_input received " - "input while not expecting a response; " - "closing connection on fd %d\n", - this->peer().get_handle ())); - break; - } - - // We're not expecting input at this time, so we'll always - // return -1 for now. - return -1; + return this->transport ()->wait_strategy ()->handle_input (); } int TAO_Client_Connection_Handler::handle_close (ACE_HANDLE handle, ACE_Reactor_Mask rm) { + // @@ Alex: we need to figure out if the transport decides to close + // us or something else. If it is something else (for example + // the cached connector trying to make room for other + // connections) then we should let the transport know, so it can + // in turn take appropiate action (such as sending exceptions to + // all waiting reply handlers). + if (TAO_orbdebug) ACE_DEBUG ((LM_DEBUG, "(%P|%t) TAO_Client_Connection_Handler::handle_close (%d, %d)\n", @@ -984,492 +942,6 @@ TAO_Client_Connection_Handler::close (u_long) // **************************************************************** -#if 0 -TAO_RW_Client_Connection_Handler::TAO_RW_Client_Connection_Handler (ACE_Thread_Manager *t) - : TAO_Client_Connection_Handler (t) -{ -} - -TAO_RW_Client_Connection_Handler::~TAO_RW_Client_Connection_Handler (void) -{ -} - -int -TAO_RW_Client_Connection_Handler::send_request (TAO_ORB_Core* orb_core, - TAO_OutputCDR &stream, - int is_twoway) -{ - TAO_FUNCTION_PP_TIMEPROBE (TAO_CLIENT_CONNECTION_HANDLER_SEND_REQUEST_START); - - // NOTE: Here would also be a fine place to calculate a digital - // signature for the message and place it into a preallocated slot - // in the "ServiceContext". Similarly, this is a good spot to - // encrypt messages (or just the message bodies) if that's needed in - // this particular environment and that isn't handled by the - // networking infrastructure (e.g. IPSEC). - // - // We could call a template method to do all this stuff, and if the - // connection handler were obtained from a factory, then this could - // be dynamically linked in (wouldn't that be cool/freaky?) - - // Send the request - int success = (int) TAO_GIOP::send_request (this->iiop_transport_, - stream, - orb_core); - TAO_MINIMAL_TIMEPROBE (GIOP_SEND_REQUEST_RETURN); - - if (!success) - return -1; - - return 0; -} - -int -TAO_RW_Client_Connection_Handler::resume_handler (ACE_Reactor *) -{ - // Since we don't suspend, we don't have to resume. - return 0; -} -#endif /* 0 */ - -// **************************************************************** - -#if 0 -TAO_ST_Client_Connection_Handler::TAO_ST_Client_Connection_Handler (ACE_Thread_Manager *t) - : TAO_Client_Connection_Handler (t) -{ -} - -TAO_ST_Client_Connection_Handler::~TAO_ST_Client_Connection_Handler (void) -{ -} - -int -TAO_ST_Client_Connection_Handler::open (void *something) -{ - int result = TAO_Client_Connection_Handler::open (something); - - if (result != 0) - return result; - - // Now we must register ourselves with the reactor for input events - // which will detect GIOP Reply messages and EOF conditions. - ACE_Reactor *r = TAO_ORB_Core_instance ()->reactor (); - return r->register_handler (this, - ACE_Event_Handler::READ_MASK); -} - -// @@ This seems odd that the connection handler would call methods in the -// GIOP object. Some of this mothod's functionality should be moved -// to GIOP. fredk -int -TAO_ST_Client_Connection_Handler::send_request (TAO_ORB_Core* orb_core, - TAO_OutputCDR &stream, - int is_twoway) -{ - TAO_FUNCTION_PP_TIMEPROBE (TAO_CLIENT_CONNECTION_HANDLER_SEND_REQUEST_START); - - // NOTE: Here would also be a fine place to calculate a digital - // signature for the message and place it into a preallocated slot - // in the "ServiceContext". Similarly, this is a good spot to - // encrypt messages (or just the message bodies) if that's needed in - // this particular environment and that isn't handled by the - // networking infrastructure (e.g. IPSEC). - // - // We could call a template method to do all this stuff, and if the - // connection handler were obtained from a factory, then this could - // be dynamically linked in (wouldn't that be cool/freaky?) - - // Send the request - int success = (int) TAO_GIOP::send_request (this->iiop_transport_, - stream, - orb_core); - TAO_MINIMAL_TIMEPROBE (GIOP_SEND_REQUEST_RETURN); - - if (!success) - return -1; - - return 0; - -#if 0 - // @@ I guess we can handle the case of handling unexpected input - // message in the Wait Strategy classes itself. (Alex). - - if (is_twoway) - { - // Set the state so that we know we're looking for a response. - this->expecting_response_ = 1; - - // Go into a loop, waiting until it's safe to try to read - // something on the socket. The handle_input() method doesn't - // actualy do the read, though, proper behavior based on what is - // read may be different if we're not using GIOP above here. - // So, we leave the reading of the response to the caller of - // this method, and simply insure that this method doesn't - // return until such time as doing a recv() on the socket would - // actually produce fruit. - ACE_Reactor *r = orb_core->reactor (); - - int ret = 0; - - while (ret != -1 && ! this->input_available_) - ret = r->handle_events (); - - this->input_available_ = 0; - // We can get events now, b/c we want them! - - // We're no longer expecting a response! - this->expecting_response_ = 0; - } - return 0; -#endif /* 0 */ -} - -int -TAO_ST_Client_Connection_Handler::handle_input (ACE_HANDLE) -{ - // Temporarily remove ourself from notification so that if - // another sub event loop is in effect still waiting for its - // response, it doesn't spin tightly gobbling up CPU. - - // @@ Why is this not transport_->orb_core ()?? (Alex). - ACE_Reactor *reactor = TAO_ORB_Core_instance ()->reactor (); - reactor->suspend_handler (this); - - // Handle the client input without blocking. - - // @@ Should nt we check the return value and if it is 0 (means all - // input is not yet read), then we should resume the handler - // right here , I guess. Is that right? (Alex). - - int result = this->transport ()->handle_client_input (0); - - // If message is not read fully, resume the handler. - if (result == 0) - reactor->resume_handler (this); - - return result; - -#if 0 - int retval = 0; - - if (this->expecting_response_) - { - this->input_available_ = 1; - // Temporarily remove ourself from notification so that if - // another sub event loop is in effect still waiting for its - // response, it doesn't spin tightly gobbling up CPU. - TAO_ORB_Core_instance ()->reactor ()->suspend_handler (this); - } - else - retval = this->check_unexpected_data (); - - return retval; -#endif /* 0 */ -} - -int -TAO_ST_Client_Connection_Handler::resume_handler (ACE_Reactor *reactor) -{ - return reactor->resume_handler (this); -} -#endif /* 0 */ - -// **************************************************************** - -#if 0 -TAO_MT_Client_Connection_Handler::TAO_MT_Client_Connection_Handler (ACE_Thread_Manager *t) - : TAO_Client_Connection_Handler (t), - calling_thread_ (ACE_OS::NULL_thread), - cond_response_available_ (0), - orb_core_ (0) -{ -} - -TAO_MT_Client_Connection_Handler::~TAO_MT_Client_Connection_Handler (void) -{ - delete this->cond_response_available_; -} - -int -TAO_MT_Client_Connection_Handler::open (void *something) -{ - int result = TAO_Client_Connection_Handler::open (something); - - if (result != 0) - return result; - - // Now we must register ourselves with the reactor for input events - // which will detect GIOP Reply messages and EOF conditions. - ACE_Reactor *r = TAO_ORB_Core_instance ()->reactor (); - return r->register_handler (this, - ACE_Event_Handler::READ_MASK); -} - -ACE_SYNCH_CONDITION* -TAO_MT_Client_Connection_Handler::cond_response_available (TAO_ORB_Core* orb_core) -{ - // @@ TODO This condition variable should per-ORB-per-thread, not - // per-connection, it is a waste to have more than one of this in - // the same thread. - if (this->cond_response_available_ == 0) - { - ACE_NEW_RETURN (this->cond_response_available_, - ACE_SYNCH_CONDITION (orb_core->leader_follower_lock ()), - 0); - } - return this->cond_response_available_; -} - -int -TAO_MT_Client_Connection_Handler::send_request (TAO_ORB_Core *orb_core, - TAO_OutputCDR &stream, - int is_twoway) -{ - TAO_FUNCTION_PP_TIMEPROBE (TAO_CLIENT_CONNECTION_HANDLER_SEND_REQUEST_START); - - // Save the ORB_Core for the handle_input callback... - this->orb_core_ = orb_core; - - // NOTE: Here would also be a find place to calculate a digital - // signature for the message and place it into a preallocated slot - // in the "ServiceContext". Similarly, this is a good spot to - // encrypt messages (or just the message bodies) if that's needed in - // this particular environment and that isn't handled by the - // networking infrastructure (e.g. IPSEC). - // - // We could call a template method to do all this stuff, and if the - // connection handler were obtained from a factory, then this could - // be dynamically linked in (wouldn't that be cool/freaky?) - - if (!is_twoway) - { - // Send the request - int success = (int) TAO_GIOP::send_request (this->iiop_transport_, - stream, - this->orb_core_); - - TAO_MINIMAL_TIMEPROBE (GIOP_SEND_REQUEST_RETURN); - - if (!success) - return -1; - } - else // is_twoway - { - ACE_Reactor *r = this->orb_core_->reactor (); - - if (this->reactor () != r) - { - ACE_Reactor_Mask mask = - ACE_Event_Handler::ALL_EVENTS_MASK | ACE_Event_Handler::DONT_CALL; - this->reactor ()->remove_handler (this, mask); - - r->register_handler (this, - ACE_Event_Handler::READ_MASK); - } - - if (this->orb_core_->leader_follower_lock ().acquire() == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::send_request: " - "Failed to get the lock.\n"), - -1); - - // Set the state so that we know we're looking for a response. - this->expecting_response_ = 1; - // remember in which thread the client connection handler was running - this->calling_thread_ = ACE_Thread::self (); - - // Send the request - int success = (int) TAO_GIOP::send_request (this->iiop_transport_, - stream, - orb_core); - - TAO_MINIMAL_TIMEPROBE (GIOP_SEND_REQUEST_RETURN); - - if (!success) - { - this->orb_core_->leader_follower_lock ().release (); - return -1; - } - - // check if there is a leader, but the leader is not us - if (this->orb_core_->leader_available () && - !this->orb_core_->I_am_the_leader_thread ()) - { - // wait as long as no input is available and/or - // no leader is available - while (!this->input_available_ && - this->orb_core_->leader_available ()) - { - ACE_SYNCH_CONDITION* cond = - this->cond_response_available (orb_core); - if (this->orb_core_->add_follower (cond) == -1) - ACE_ERROR ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::send_request: " - "Failed to add a follower thread\n")); - cond->wait (); - } - // now somebody woke us up to become a leader or to handle - // our input. We are already removed from the follower queue - if (this->input_available_) - { - // there is input waiting for me - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::send_request: " - "Failed to release the lock.\n"), - -1); - // The following variables are safe, because we are not - // registered with the reactor any more. - this->input_available_ = 0; - this->expecting_response_ = 0; - this->calling_thread_ = ACE_OS::NULL_thread; - return 0; - } - } - - // Become a leader, because there is no leader or we have to - // update to a leader or we are doing nested upcalls in this - // case we do increase the refcount on the leader in - // TAO_ORB_Core. - - this->orb_core_->set_leader_thread (); - // this might increase the refcount of the leader - - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::send_request: " - "Failed to release the lock.\n"), - -1); - - r->owner (ACE_Thread::self ()); - - int ret = 0; - - while (ret != -1 && !this->input_available_) - ret = r->handle_events (); - - if (ret == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::send_request: " - "handle_events failed.\n"), - -1); - - // Wake up the next leader, we cannot do that in handle_input, - // because the woken up thread would try to get into - // handle_events, which is at the time in handle_input still - // occupied. - - if (this->orb_core_->unset_leader_wake_up_follower () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::send_request: " - "Failed to unset the leader and wake up a new follower.\n"), - -1); - // Make use reusable - this->input_available_ = 0; - this->expecting_response_ = 0; - this->calling_thread_ = ACE_OS::NULL_thread; - } - - return 0; -} - -int -TAO_MT_Client_Connection_Handler::handle_input (ACE_HANDLE) -{ - if (this->orb_core_ == 0) - this->orb_core_ = TAO_ORB_Core_instance (); - - if (this->orb_core_->leader_follower_lock ().acquire () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::handle_input: " - "Failed to get the lock.\n"), - -1); - - if (!this->expecting_response_) - { - // we got something, but did not want. - // @@ wake up an other thread, we are lost - - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::handle_input: " - "Failed to release the lock.\n"), - -1); - return this->check_unexpected_data (); - } - - if (ACE_OS::thr_equal (this->calling_thread_, - ACE_Thread::self ())) - { - // We are now a leader getting its response. - this->input_available_ = 1; - - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::handle_input: " - "Failed to release the lock.\n"), - -1); - this->orb_core_->reactor ()->suspend_handler (this); - // resume_handler is called in TAO_GIOP_Invocation::invoke - return 0; - } - else - { - // We are a leader, which got a response for one of the - // followers, which means we are now a thread running the wrong - // Client_Connection_Handler - - // At this point we might fail to remove the follower, because - // it has been already chosen to become the leader, so it is - // awake and will get this too. - ACE_SYNCH_CONDITION* cond = - this->cond_response_available (this->orb_core_); - - this->orb_core_->remove_follower (cond); - - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::handle_input: " - "Failed to release the lock.\n"), - -1); - - this->orb_core_->reactor ()->suspend_handler (this); - // We should wake suspend the thread before we wake him up. - // resume_handler is called in TAO_GIOP_Invocation::invoke - - // @@ TODO (Michael): We might be able to optimize this in - // doing the suspend_handler as last thing, but I am not sure - // if a race condition would occur. - - if (this->orb_core_->leader_follower_lock ().acquire () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::handle_input: " - "Failed to acquire the lock.\n"), - -1); - // The thread was already selected to become a leader, so we - // will be called again. - this->input_available_ = 1; - cond->signal (); - - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_Client_Connection_Handler::handle_input: " - "Failed to release the lock.\n"), - -1); - return 0; - } -} - -int -TAO_MT_Client_Connection_Handler::resume_handler (ACE_Reactor *reactor) -{ - return reactor->resume_handler (this); -} -#endif /* 0 */ - -// **************************************************************** - #define TAO_SVC_TUPLE ACE_Svc_Tuple<TAO_Client_Connection_Handler> #define CACHED_CONNECT_STRATEGY ACE_Cached_Connect_Strategy<TAO_Client_Connection_Handler, TAO_SOCK_CONNECTOR, TAO_Cached_Connector_Lock> #define REFCOUNTED_HASH_RECYCLABLE_ADDR ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr> diff --git a/TAO/tao/Connect.h b/TAO/tao/Connect.h index 56b9f58e0de..f905285b979 100644 --- a/TAO/tao/Connect.h +++ b/TAO/tao/Connect.h @@ -40,6 +40,8 @@ class TAO_ORB_Core; typedef ACE_Svc_Handler<TAO_SOCK_STREAM, ACE_NULL_SYNCH> TAO_SVC_HANDLER; +// **************************************************************** + class TAO_IIOP_Handler_Base : public TAO_SVC_HANDLER { public: @@ -67,15 +69,6 @@ public: virtual int open (void *); // Activation template method. - virtual int send_request (TAO_ORB_Core* orb_core, - TAO_OutputCDR &stream, - int is_twoway); - // Send the request in <stream>. If it is a twoway invocation, then - // this re-enters the reactor event loop so that incoming requests - // can continue to be serviced. This insures that a nested upcall, - // i.e., an invocation coming back from the remote during this - // invocation, will still be handled and deadlock averted. - // = Event Handler overloads virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); @@ -89,127 +82,15 @@ public: // Object termination hook. virtual TAO_Transport *transport (void); + // Return the transport objects protected: - TAO_IIOP_Client_Transport *iiop_transport_; - // @@ New transport object reference. - // The handler is responsible for creating this object when - // it is instantiated. fredk - - int check_unexpected_data (void); - // This method checks for unexpected data - - int expecting_response_; - // State flag which, if non-zero, indicates that this handler is - // looking to get input. Otherwise, any input received is - // unexpected. - - int input_available_; - // Flag indicating whether or not input is available. Only valid - // when <expecting_response_> is non-zero. -}; - -#if 0 -// @@ Getting rid of this Connection Handler. one step at a time. -class TAO_Export TAO_RW_Client_Connection_Handler : public TAO_Client_Connection_Handler -{ -public: - TAO_RW_Client_Connection_Handler (ACE_Thread_Manager *t = 0); - - virtual ~TAO_RW_Client_Connection_Handler (void); - - virtual int send_request (TAO_ORB_Core* orb_core, - TAO_OutputCDR &stream, - int is_twoway); - // Send the request in <stream>. Since this class simply - // reads/writes from a socket (and does not handle nested upcalls), - // there is no need to register with a reactor. - - virtual int resume_handler (ACE_Reactor *reactor); - // Resume the handler. - -protected: - -}; -#endif /* 0 */ - -#if 0 -class TAO_Export TAO_ST_Client_Connection_Handler : public TAO_Client_Connection_Handler -{ -public: - TAO_ST_Client_Connection_Handler (ACE_Thread_Manager *t = 0); - - virtual ~TAO_ST_Client_Connection_Handler (void); - - virtual int open (void *); - // Initialize the handler. - - virtual int send_request (TAO_ORB_Core* orb_core, - TAO_OutputCDR &stream, - int is_twoway); - // Send the request in <stream>. If it is a twoway invocation, then - // this re-enters the reactor event loop so that incoming requests - // can continue to be serviced. This insures that a nested upcall, - // i.e., an invocation coming back from the remote during this - // invocation, will still be handled and deadlock averted. - - virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); - // Called when a a response from a twoway invocation is available. - - virtual int resume_handler (ACE_Reactor *reactor); - // Resume the handler. - -protected: - + // Reference to the transport object, it is owned by this class. }; -#endif /* 0 */ - -#if 0 -class TAO_Export TAO_MT_Client_Connection_Handler : public TAO_Client_Connection_Handler -{ -public: - TAO_MT_Client_Connection_Handler (ACE_Thread_Manager *t = 0); - - virtual ~TAO_MT_Client_Connection_Handler (void); - - virtual int open (void *); - // Initialize the handler. - - virtual int send_request (TAO_ORB_Core* orb_core, - TAO_OutputCDR &stream, - int is_twoway); - // Send the request in <stream>. If it is a twoway invocation, then - // this re-enters the reactor event loop so that incoming requests - // can continue to be serviced. This insures that a nested upcall, - // i.e., an invocation coming back from the remote during this - // invocation, will still be handled and deadlock averted. - - virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); - // Called when a a response from a twoway invocation is available. - - virtual int resume_handler (ACE_Reactor *reactor); - // Resume the handler. - -protected: - ACE_SYNCH_CONDITION* cond_response_available (TAO_ORB_Core* orb_core); - // Return the cond_response_available, initializing it if necessary. - - ACE_thread_t calling_thread_; - // the thread ID of the thread we were running in. - - ACE_SYNCH_CONDITION* cond_response_available_; - // wait on reponse if the leader-follower model is active - - TAO_ORB_Core* orb_core_; - // The ORB core where we are executing a request. -}; -#endif /* 0 */ // **************************************************************** -class TAO_ORB_Core; - class TAO_Export TAO_Server_Connection_Handler : public TAO_IIOP_Handler_Base { // = TITLE diff --git a/TAO/tao/GIOP.cpp b/TAO/tao/GIOP.cpp index 9a69934d26d..76cd8b7f6ed 100644 --- a/TAO/tao/GIOP.cpp +++ b/TAO/tao/GIOP.cpp @@ -126,7 +126,7 @@ TAO_GIOP::dump_msg (const char *label, if (TAO_debug_level >= 2) { ACE_DEBUG ((LM_DEBUG, - "%s GIOP v%c.%c msg, %d data bytes, %s endian, %s\n", + "%s GIOP v%c.%c msg, %d data bytes, %s endian, %s", label, digits[ptr[4]], digits[ptr[5]], @@ -135,11 +135,29 @@ TAO_GIOP::dump_msg (const char *label, (ptr[7] <= TAO_GIOP::Fragment) ? names [ptr[7] + TAO_GIOP::tao_specific_message_types] : "UNKNOWN TYPE")); + if (ptr[7] == TAO_GIOP::Request) + { + // @@ Only works if ServiceContextList is empty.... + const CORBA::ULong *request_id = + ACE_reinterpret_cast(const CORBA::ULong*, + ptr + TAO_GIOP_HEADER_LEN + 4); + ACE_DEBUG ((LM_DEBUG, " = %d\n", *request_id)); + } + else if (ptr[7] == TAO_GIOP::Reply) + { + const CORBA::ULong *request_id = + ACE_reinterpret_cast(const CORBA::ULong*, + ptr + TAO_GIOP_HEADER_LEN + 4); + ACE_DEBUG ((LM_DEBUG, " = %d\n", *request_id)); + } + else + ACE_DEBUG ((LM_DEBUG, "\n")); + if (TAO_debug_level >= 4) ACE_HEX_DUMP ((LM_DEBUG, (const char*)ptr, len, - "\n")); + "GIOP message")); } } @@ -469,7 +487,9 @@ TAO_GIOP::recv_message (TAO_Transport *transport, // Default header length. ssize_t header_len = TAO_GIOP_HEADER_LEN; - TAO_GIOP::Message_Type retval; + // @@ Alex&Carlos: we need to figure out what is the right value to + // initialize this thing... + TAO_GIOP::Message_Type retval = TAO_GIOP::ShortRead; CORBA::ULong message_size; ssize_t len; char *header = 0; @@ -629,11 +649,11 @@ TAO_GIOP::recv_message (TAO_Transport *transport, { // Reset. transport->message_size (0); - + // Current message is received fully. transport->message_received (1); } - + return retval; } diff --git a/TAO/tao/GIOP_Server_Request.cpp b/TAO/tao/GIOP_Server_Request.cpp index 35d5f0cce36..00999340c19 100644 --- a/TAO/tao/GIOP_Server_Request.cpp +++ b/TAO/tao/GIOP_Server_Request.cpp @@ -155,7 +155,7 @@ GIOP_ServerRequest::parse_header_lite (CORBA::Environment &ACE_TRY_ENV) CORBA::Long length; hdr_status = hdr_status && input.read_long (length); if (hdr_status) - { + { // Do not include NULL character at the end. this->operation_.set (input.rd_ptr (), length - 1, @@ -567,8 +567,8 @@ GIOP_ServerRequest::init_reply (CORBA::Environment &env) { // Construct a REPLY header. TAO_GIOP::start_message (TAO_GIOP::Reply, - *this->outgoing_, - this->orb_core_); + *this->outgoing_, + this->orb_core_); TAO_GIOP_ServiceContextList resp_ctx; resp_ctx.length (0); diff --git a/TAO/tao/IIOP_Transport.cpp b/TAO/tao/IIOP_Transport.cpp index 79b6cf11a59..b76c4bdeeee 100644 --- a/TAO/tao/IIOP_Transport.cpp +++ b/TAO/tao/IIOP_Transport.cpp @@ -128,7 +128,6 @@ void TAO_IIOP_Transport::resume_connection (ACE_Reactor *reactor) { this->ws_->resume_handler (reactor); - // this->handler_->resume_handler (reactor); } void @@ -150,7 +149,7 @@ TAO_IIOP_Client_Transport::send_request (TAO_ORB_Core *orb_core, { ACE_FUNCTION_TIMEPROBE (TAO_IIOP_CLIENT_TRANSPORT_SEND_REQUEST_START); - return this->ws_->send_request (orb_core, + return this->ws_->send_request (orb_core, stream, two_way); } @@ -166,7 +165,7 @@ TAO_IIOP_Client_Transport::send_request (TAO_ORB_Core *orb_core, int TAO_IIOP_Client_Transport::handle_client_input (int block) { - // @@ Alex: it should be possible to make this code generic and move + // @@ Alex: it should be possible to make this code generic and move // it to the GIOP class or something similar.... // When we multiplex several invocations over a connection we need @@ -182,7 +181,7 @@ TAO_IIOP_Client_Transport::handle_client_input (int block) // factory returns a pointer to the pre-allocated CDR. // // @@ Alex: I thought some more about this, and here is how i would - // like to do it: this class keeps a CDR stream for the "current" + // like to do it: this class keeps a CDR stream for the "current" // message beign received. Initially the CDR is 0, when the // handle_client_input() is called the first time then we go to // the muxer to obtain the CDR stream. @@ -246,11 +245,11 @@ TAO_IIOP_Client_Transport::handle_client_input (int block) case TAO_GIOP::MessageError: // Handle errors like these. // @@ this->reply_handler_->error (); - return 1; + return -1; case TAO_GIOP::Fragment: // Handle this. - return 1; + return -1; case TAO_GIOP::Request: // In GIOP 1.0 and GIOP 1.1 this is an error, but it is @@ -258,14 +257,14 @@ TAO_IIOP_Client_Transport::handle_client_input (int block) // on the firt iteration, leave it for the nearby future... // ERROR too. // @@ this->reply_handler_->error (); - return 1; + return -1; case TAO_GIOP::CancelRequest: case TAO_GIOP::LocateRequest: case TAO_GIOP::CloseConnection: // @@ Errors for the time being. // @@ this->reply_handler_->error (); - return 1; + return -1; case TAO_GIOP::LocateReply: case TAO_GIOP::Reply: @@ -363,6 +362,14 @@ TAO_IIOP_Client_Transport::resume_handler (void) int TAO_IIOP_Client_Transport::check_unexpected_data (void) { + // @@ Alex: This should *not* be part of the client connection + // handler, we should treat any incoming data as a GIOP message. + // The server can always send the "CloseConnection" message and + // we should act accordingly. + // Finally: in the future the server may send requests though + // GIOP 1.2 connections, we shouldn't hard-code the current GIOP + // state machine at this level... + // We're a client, so we're not expecting to see input. Still we // better check what it is! char ignored; diff --git a/TAO/tao/Request_Mux_Strategy.cpp b/TAO/tao/Request_Mux_Strategy.cpp index a71994d264b..d7836021186 100644 --- a/TAO/tao/Request_Mux_Strategy.cpp +++ b/TAO/tao/Request_Mux_Strategy.cpp @@ -80,7 +80,8 @@ TAO_Muxed_RMS::destroy_cdr_stream (void) // ********************************************************************* TAO_Exclusive_RMS::TAO_Exclusive_RMS (void) - : request_id_ (931232), // @@ Hardcoding. + : request_id_generator_ (0), + request_id_ (0), rd_ (0) { } @@ -95,7 +96,7 @@ TAO_Exclusive_RMS::~TAO_Exclusive_RMS (void) CORBA::ULong TAO_Exclusive_RMS::request_id (void) { - return this->request_id_; + return this->request_id_generator_++; } // Bind the handler with the request id. diff --git a/TAO/tao/Request_Mux_Strategy.h b/TAO/tao/Request_Mux_Strategy.h index 7a0555fb7f2..363b6539873 100644 --- a/TAO/tao/Request_Mux_Strategy.h +++ b/TAO/tao/Request_Mux_Strategy.h @@ -163,6 +163,10 @@ public: // NO-OP function. protected: + CORBA::ULong request_id_generator_; + // Used to generate a different request_id on each call to + // request_id() + CORBA::ULong request_id_; // Request id for the current request. diff --git a/TAO/tao/UIOP_Connect.cpp b/TAO/tao/UIOP_Connect.cpp index fceff511557..e1bc7a1ab75 100644 --- a/TAO/tao/UIOP_Connect.cpp +++ b/TAO/tao/UIOP_Connect.cpp @@ -35,6 +35,8 @@ TAO_UIOP_Handler_Base::resume_handler (ACE_Reactor *) return -1; } +// **************************************************************** + // @@ For pluggable protocols, added a reference to // the corresponding transport obj. TAO_UIOP_Server_Connection_Handler::TAO_UIOP_Server_Connection_Handler (ACE_Thread_Manager *t) @@ -743,6 +745,8 @@ TAO_UIOP_Server_Connection_Handler::handle_input (ACE_HANDLE) return result; } +// **************************************************************** + // @@ For pluggable protocols, added a reference to the corresponding // transport obj. TAO_UIOP_Client_Connection_Handler::TAO_UIOP_Client_Connection_Handler (ACE_Thread_Manager *t) @@ -818,51 +822,6 @@ TAO_UIOP_Client_Connection_Handler::handle_input (ACE_HANDLE) } int -TAO_UIOP_Client_Connection_Handler::check_unexpected_data (void) -{ - // We're a client, so we're not expecting to see input. Still we - // better check what it is! - char ignored; - ssize_t ret = this->peer().recv (&ignored, - sizeof ignored, - MSG_PEEK); - switch (ret) - { - case 0: - case -1: - // 0 is a graceful shutdown - // -1 is a somewhat ugly shutdown - // - // Both will result in us returning -1 and this connection - // getting closed - // - if (TAO_orbdebug) - ACE_DEBUG ((LM_WARNING, - "UIOP_Client_Connection_Handler::handle_input: " - "closing connection on fd %d\n", - this->peer().get_handle ())); - break; - - case 1: - // - // @@ Fix me!! - // - // This should be the close connection message. Since we don't - // handle this yet, log an error, and close the connection. - ACE_ERROR ((LM_WARNING, - "UIOP_Client_Connection_Handler::handle_input received " - "input while not expecting a response; " - "closing connection on fd %d\n", - this->peer().get_handle ())); - break; - } - - // We're not expecting input at this time, so we'll always - // return -1 for now. - return -1; -} - -int TAO_UIOP_Client_Connection_Handler::handle_close (ACE_HANDLE handle, ACE_Reactor_Mask rm) { @@ -904,458 +863,6 @@ TAO_UIOP_Client_Connection_Handler::close (u_long) // **************************************************************** -TAO_RW_Client_Connection_Handler::TAO_RW_Client_Connection_Handler (ACE_Thread_Manager *t) - : TAO_UIOP_Client_Connection_Handler (t) -{ -} - -TAO_RW_Client_Connection_Handler::~TAO_RW_Client_Connection_Handler (void) -{ -} - -int -TAO_RW_Client_Connection_Handler::send_request (TAO_ORB_Core* orb_core, - TAO_OutputCDR &stream, - int is_twoway) -{ - TAO_FUNCTION_PP_TIMEPROBE (TAO_CLIENT_CONNECTION_HANDLER_SEND_REQUEST_START); - - // NOTE: Here would also be a fine place to calculate a digital - // signature for the message and place it into a preallocated slot - // in the "ServiceContext". Similarly, this is a good spot to - // encrypt messages (or just the message bodies) if that's needed in - // this particular environment and that isn't handled by the - // networking infrastructure (e.g. IPSEC). - // - // We could call a template method to do all this stuff, and if the - // connection handler were obtained from a factory, then this could - // be dynamically linked in (wouldn't that be cool/freaky?) - - // Send the request - int success = - ACE_static_cast (int, TAO_GIOP::send_request (this->uiop_transport_, - stream, - orb_core)); - - TAO_MINIMAL_TIMEPROBE (GIOP_SEND_REQUEST_RETURN); - - if (!success) - return -1; - - return 0; -} - -int -TAO_RW_Client_Connection_Handler::resume_handler (ACE_Reactor *) -{ - // Since we don't suspend, we don't have to resume. - return 0; -} - -// **************************************************************** - -TAO_ST_Client_Connection_Handler::TAO_ST_Client_Connection_Handler (ACE_Thread_Manager *t) - : TAO_UIOP_Client_Connection_Handler (t) -{ -} - -TAO_ST_Client_Connection_Handler::~TAO_ST_Client_Connection_Handler (void) -{ -} - -int -TAO_ST_Client_Connection_Handler::open (void *something) -{ - int result = TAO_UIOP_Client_Connection_Handler::open (something); - - if (result != 0) - return result; - - // Now we must register ourselves with the reactor for input events - // which will detect GIOP Reply messages and EOF conditions. - ACE_Reactor *r = TAO_ORB_Core_instance ()->reactor (); - return r->register_handler (this, - ACE_Event_Handler::READ_MASK); -} - -// @@ this seems odd that the connection handler would call methods in the -// GIOP object. Some of this mothod's functionality should be moved -// to GIOP. fredk -int -TAO_ST_Client_Connection_Handler::send_request (TAO_ORB_Core* orb_core, - TAO_OutputCDR &stream, - int is_twoway) -{ - TAO_FUNCTION_PP_TIMEPROBE (TAO_CLIENT_CONNECTION_HANDLER_SEND_REQUEST_START); - - // NOTE: Here would also be a fine place to calculate a digital - // signature for the message and place it into a preallocated slot - // in the "ServiceContext". Similarly, this is a good spot to - // encrypt messages (or just the message bodies) if that's needed in - // this particular environment and that isn't handled by the - // networking infrastructure (e.g. IPSEC). - // - // We could call a template method to do all this stuff, and if the - // connection handler were obtained from a factory, then this could - // be dynamically linked in (wouldn't that be cool/freaky?) - - // Send the request - int success = (int) TAO_GIOP::send_request (this->uiop_transport_, - stream, - orb_core); - TAO_MINIMAL_TIMEPROBE (GIOP_SEND_REQUEST_RETURN); - - if (!success) - return -1; - - if (is_twoway) - { - // Set the state so that we know we're looking for a response. - this->expecting_response_ = 1; - - // Go into a loop, waiting until it's safe to try to read - // something on the socket. The handle_input() method doesn't - // actualy do the read, though, proper behavior based on what is - // read may be different if we're not using GIOP above here. - // So, we leave the reading of the response to the caller of - // this method, and simply insure that this method doesn't - // return until such time as doing a recv() on the socket would - // actually produce fruit. - ACE_Reactor *r = orb_core->reactor (); - - int ret = 0; - - while (ret != -1 && ! this->input_available_) - ret = r->handle_events (); - - this->input_available_ = 0; - // We can get events now, b/c we want them! - - // We're no longer expecting a response! - this->expecting_response_ = 0; - } - - return 0; -} - -int -TAO_ST_Client_Connection_Handler::handle_input (ACE_HANDLE) -{ - int retval = 0; - - if (this->expecting_response_) - { - this->input_available_ = 1; - // Temporarily remove ourself from notification so that if - // another sub event loop is in effect still waiting for its - // response, it doesn't spin tightly gobbling up CPU. - TAO_ORB_Core_instance ()->reactor ()->suspend_handler (this); - } - else - retval = this->check_unexpected_data (); - - return retval; -} - -int -TAO_ST_Client_Connection_Handler::resume_handler (ACE_Reactor *reactor) -{ - return reactor->resume_handler (this); -} - -// **************************************************************** - -TAO_MT_UIOP_Client_Connection_Handler::TAO_MT_UIOP_Client_Connection_Handler (ACE_Thread_Manager *t) - : TAO_UIOP_Client_Connection_Handler (t), - calling_thread_ (ACE_OS::NULL_thread), - cond_response_available_ (0), - orb_core_ (0) -{ -} - -TAO_MT_UIOP_Client_Connection_Handler::~TAO_MT_UIOP_Client_Connection_Handler (void) -{ - delete this->cond_response_available_; -} - -int -TAO_MT_UIOP_Client_Connection_Handler::open (void *something) -{ - int result = TAO_UIOP_Client_Connection_Handler::open (something); - - if (result != 0) - return result; - - // Now we must register ourselves with the reactor for input events - // which will detect GIOP Reply messages and EOF conditions. - ACE_Reactor *r = TAO_ORB_Core_instance ()->reactor (); - return r->register_handler (this, - ACE_Event_Handler::READ_MASK); -} - -ACE_SYNCH_CONDITION* -TAO_MT_UIOP_Client_Connection_Handler::cond_response_available (TAO_ORB_Core* orb_core) -{ - // @@ TODO This condition variable should per-ORB-per-thread, not - // per-connection, it is a waste to have more than one of this in - // the same thread. - if (this->cond_response_available_ == 0) - { - ACE_NEW_RETURN (this->cond_response_available_, - ACE_SYNCH_CONDITION (orb_core->leader_follower_lock ()), - 0); - } - return this->cond_response_available_; -} - -int -TAO_MT_UIOP_Client_Connection_Handler::send_request (TAO_ORB_Core *orb_core, - TAO_OutputCDR &stream, - int is_twoway) -{ - TAO_FUNCTION_PP_TIMEPROBE (TAO_CLIENT_CONNECTION_HANDLER_SEND_REQUEST_START); - - // Save the ORB_Core for the handle_input callback... - this->orb_core_ = orb_core; - - // NOTE: Here would also be a fine place to calculate a digital - // signature for the message and place it into a preallocated slot - // in the "ServiceContext". Similarly, this is a good spot to - // encrypt messages (or just the message bodies) if that's needed in - // this particular environment and that isn't handled by the - // networking infrastructure (e.g. IPSEC). - // - // We could call a template method to do all this stuff, and if the - // connection handler were obtained from a factory, then this could - // be dynamically linked in (wouldn't that be cool/freaky?) - - if (!is_twoway) - { - // Send the request - int success = (int) TAO_GIOP::send_request (this->uiop_transport_, - stream, - this->orb_core_); - - TAO_MINIMAL_TIMEPROBE (GIOP_SEND_REQUEST_RETURN); - - if (!success) - return -1; - } - else // is_twoway - { - ACE_Reactor *r = this->orb_core_->reactor (); - - if (this->reactor () != r) - { - ACE_Reactor_Mask mask = - ACE_Event_Handler::ALL_EVENTS_MASK | ACE_Event_Handler::DONT_CALL; - this->reactor ()->remove_handler (this, mask); - - r->register_handler (this, - ACE_Event_Handler::READ_MASK); - } - - if (this->orb_core_->leader_follower_lock ().acquire() == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::send_request: " - "Failed to get the lock.\n"), - -1); - - // Set the state so that we know we're looking for a response. - this->expecting_response_ = 1; - // remember in which thread the client connection handler was running - this->calling_thread_ = ACE_Thread::self (); - - // Send the request - int success = (int) TAO_GIOP::send_request (this->uiop_transport_, - stream, - orb_core); - - TAO_MINIMAL_TIMEPROBE (GIOP_SEND_REQUEST_RETURN); - - if (!success) - { - this->orb_core_->leader_follower_lock ().release (); - return -1; - } - - // check if there is a leader, but the leader is not us - if (this->orb_core_->leader_available () && - !this->orb_core_->I_am_the_leader_thread ()) - { - // wait as long as no input is available and/or - // no leader is available - while (!this->input_available_ && - this->orb_core_->leader_available ()) - { - ACE_SYNCH_CONDITION* cond = - this->cond_response_available (orb_core); - if (this->orb_core_->add_follower (cond) == -1) - ACE_ERROR ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::send_request: " - "Failed to add a follower thread\n")); - cond->wait (); - } - // now somebody woke us up to become a leader or to handle - // our input. We are already removed from the follower queue - if (this->input_available_) - { - // there is input waiting for me - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::send_request: " - "Failed to release the lock.\n"), - -1); - // The following variables are safe, because we are not - // registered with the reactor any more. - this->input_available_ = 0; - this->expecting_response_ = 0; - this->calling_thread_ = ACE_OS::NULL_thread; - return 0; - } - } - - // Become a leader, because there is no leader or we have to - // update to a leader or we are doing nested upcalls in this - // case we do increase the refcount on the leader in - // TAO_ORB_Core. - - this->orb_core_->set_leader_thread (); - // this might increase the recount of the leader - - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::send_request: " - "Failed to release the lock.\n"), - -1); - - r->owner (ACE_Thread::self ()); - - int ret = 0; - - while (ret != -1 && !this->input_available_) - ret = r->handle_events (); - - if (ret == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::send_request: " - "handle_events failed.\n"), - -1); - - // Wake up the next leader, we cannot do that in handle_input, - // because the woken up thread would try to get into - // handle_events, which is at the time in handle_input still - // occupied. - - if (this->orb_core_->unset_leader_wake_up_follower () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::send_request: " - "Failed to unset the leader and wake up a new follower.\n"), - -1); - // Make use reusable - this->input_available_ = 0; - this->expecting_response_ = 0; - this->calling_thread_ = ACE_OS::NULL_thread; - } - - return 0; -} - -int -TAO_MT_UIOP_Client_Connection_Handler::handle_input (ACE_HANDLE) -{ - if (this->orb_core_ == 0) - this->orb_core_ = TAO_ORB_Core_instance (); - - if (this->orb_core_->leader_follower_lock ().acquire () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::handle_input: " - "Failed to get the lock.\n"), - -1); - - if (!this->expecting_response_) - { - // we got something, but did not want - // @@ wake up an other thread, we are lost - - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::handle_input: " - "Failed to release the lock.\n"), - -1); - return this->check_unexpected_data (); - } - - if (ACE_OS::thr_equal (this->calling_thread_, - ACE_Thread::self ())) - { - // We are now a leader getting its response. - this->input_available_ = 1; - - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::handle_input: " - "Failed to release the lock.\n"), - -1); - this->orb_core_->reactor ()->suspend_handler (this); - // resume_handler is called in TAO_GIOP_Invocation::invoke - return 0; - } - else - { - // We are a leader, which got a response for one of the - // followers, which means we are now a thread running the wrong - // Client_Connection_Handler - - // At this point we might fail to remove the follower, because - // it has been already chosen to become the leader, so it is - // awake and will get this too. - ACE_SYNCH_CONDITION* cond = - this->cond_response_available (this->orb_core_); - - this->orb_core_->remove_follower (cond); - - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::handle_input: " - "Failed to release the lock.\n"), - -1); - - this->orb_core_->reactor ()->suspend_handler (this); - // We should wake suspend the thread before we wake him up. - // resume_handler is called in TAO_GIOP_Invocation::invoke - - // @@ TODO (Michael): We might be able to optimize this in - // doing the suspend_handler as last thing, but I am not sure - // if a race condition would occur. - - if (this->orb_core_->leader_follower_lock ().acquire () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::handle_input: " - "Failed to acquire the lock.\n"), - -1); - // The thread was already selected to become a leader, so we - // will be called again. - this->input_available_ = 1; - cond->signal (); - - if (this->orb_core_->leader_follower_lock ().release () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) TAO_UIOP_Client_Connection_Handler::handle_input: " - "Failed to release the lock.\n"), - -1); - return 0; - } -} - -int -TAO_MT_UIOP_Client_Connection_Handler::resume_handler (ACE_Reactor *reactor) -{ - return reactor->resume_handler (this); -} - -// **************************************************************** - #define TAO_UIOP_SVC_TUPLE ACE_Svc_Tuple<TAO_UIOP_Client_Connection_Handler> #define UIOP_CACHED_CONNECT_STRATEGY ACE_Cached_Connect_Strategy<TAO_UIOP_Client_Connection_Handler, ACE_LSOCK_CONNECTOR, TAO_Cached_Connector_Lock> #define UIOP_REFCOUNTED_HASH_RECYCLABLE_ADDR ACE_Refcounted_Hash_Recyclable<ACE_UNIX_Addr> diff --git a/TAO/tao/UIOP_Connect.h b/TAO/tao/UIOP_Connect.h index c7c6694353d..e0eb98aabc7 100644 --- a/TAO/tao/UIOP_Connect.h +++ b/TAO/tao/UIOP_Connect.h @@ -39,6 +39,7 @@ class TAO_ORB_Core; class TAO_UIOP_Transport; class TAO_UIOP_Client_Transport; class TAO_UIOP_Server_Transport; +class TAO_ORB_Core; typedef ACE_Svc_Handler<ACE_LSOCK_STREAM, ACE_NULL_SYNCH> TAO_UIOP_SVC_HANDLER; @@ -54,6 +55,8 @@ public: // Resume the handler. }; +// **************************************************************** + class TAO_Export TAO_UIOP_Client_Connection_Handler : public TAO_UIOP_Handler_Base { // = TITLE @@ -133,78 +136,8 @@ protected: }; -class TAO_Export TAO_ST_UIOP_Client_Connection_Handler : public TAO_UIOP_Client_Connection_Handler -{ -public: - TAO_ST_UIOP_Client_Connection_Handler (ACE_Thread_Manager *t = 0); - - virtual ~TAO_ST_UIOP_Client_Connection_Handler (void); - - virtual int open (void *); - // Initialize the handler. - - virtual int send_request (TAO_ORB_Core* orb_core, - TAO_OutputCDR &stream, - int is_twoway); - // Send the request in <stream>. If it is a twoway invocation, then - // this re-enters the reactor event loop so that incoming requests - // can continue to be serviced. This insures that a nested upcall, - // i.e., an invocation coming back from the remote during this - // invocation, will still be handled and deadlock averted. - - virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); - // Called when a a response from a twoway invocation is available. - - virtual int resume_handler (ACE_Reactor *reactor); - // Resume the handler. - -protected: - -}; - -class TAO_Export TAO_MT_UIOP_Client_Connection_Handler : public TAO_UIOP_Client_Connection_Handler -{ -public: - TAO_MT_UIOP_Client_Connection_Handler (ACE_Thread_Manager *t = 0); - - virtual ~TAO_MT_UIOP_Client_Connection_Handler (void); - - virtual int open (void *); - // Initialize the handler. - - virtual int send_request (TAO_ORB_Core* orb_core, - TAO_OutputCDR &stream, - int is_twoway); - // Send the request in <stream>. If it is a twoway invocation, then - // this re-enters the reactor event loop so that incoming requests - // can continue to be serviced. This insures that a nested upcall, - // i.e., an invocation coming back from the remote during this - // invocation, will still be handled and deadlock averted. - - virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); - // Called when a a response from a twoway invocation is available. - - virtual int resume_handler (ACE_Reactor *reactor); - // Resume the handler. - -protected: - ACE_SYNCH_CONDITION* cond_response_available (TAO_ORB_Core* orb_core); - // Return the cond_response_available, initializing it if necessary. - - ACE_thread_t calling_thread_; - // the thread ID of the thread we were running in. - - ACE_SYNCH_CONDITION* cond_response_available_; - // wait on reponse if the leader-follower model is active - - TAO_ORB_Core* orb_core_; - // The ORB core where we are executing a request. -}; - // **************************************************************** -class TAO_ORB_Core; - class TAO_Export TAO_UIOP_Server_Connection_Handler : public TAO_UIOP_Handler_Base { // = TITLE diff --git a/TAO/tao/Wait_Strategy.cpp b/TAO/tao/Wait_Strategy.cpp index cb538d47ea9..80325d120a7 100644 --- a/TAO/tao/Wait_Strategy.cpp +++ b/TAO/tao/Wait_Strategy.cpp @@ -22,14 +22,14 @@ TAO_Wait_Strategy::send_request (TAO_ORB_Core *orb_core, TAO_OutputCDR &stream, int /* two_way */) { - int success = success = (int) TAO_GIOP::send_request (this->transport_, - stream, - this->transport_->orb_core ()); - + int success = (int) TAO_GIOP::send_request (this->transport_, + stream, + this->transport_->orb_core ()); + if (!success) return -1; else - return 0; + return 0; } // ********************************************************************* @@ -56,11 +56,12 @@ TAO_Wait_On_Reactor::wait (void) this->transport_->orb_core ()->reactor (); // @@ Carlos: Can we rely on <reply_received> flag in the AMI case? - // It depends on whether we are expecting replies or not, right? + // It depends on whether we are expecting replies or not, right? // So, I think we can simply return from this loop, when some // event occurs, and the invocation guy can call us again, if it // wants to. (AMI will call, if it is expecting replies, SMI will // call if the reply is not arrived) (Alex). + // @@ Alex: I think you are right, let's fix it later.... // Do the event loop, till there are no events and no errors. @@ -124,7 +125,7 @@ TAO_Wait_On_Leader_Follower::~TAO_Wait_On_Leader_Follower (void) } -// @@ Why do we need <orb_core> and the <two_way> flag? <orb_core> is +// @@ Why do we need <orb_core> and the <two_way> flag? <orb_core> is // with the <Transport> object and <two_way> flag wont make sense // at this level since this is common for AMI also. (Alex). int @@ -141,25 +142,25 @@ TAO_Wait_On_Leader_Follower::send_request (TAO_ORB_Core *orb_core, else { // = Two way call. - + // @@ Should we do here that checking for the difference in the // Reactor used??? (Alex). // Register the handler. this->transport_->register_handler (); // @@ Carlos: We do this only if the reactor is different right? - // (Alex) - + // (Alex) + // Obtain the lock. ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, orb_core->leader_follower_lock (), -1); - + // Set the state so that we know we're looking for a response. this->expecting_response_ = 1; - + // remember in which thread the client connection handler was running this->calling_thread_ = ACE_Thread::self (); - + // Send the request return TAO_Wait_Strategy::send_request (orb_core, stream, @@ -171,17 +172,17 @@ int TAO_Wait_On_Leader_Follower::wait (void) { // @@ Do we need this code (checking for the difference in the - // Reactor)? (Alex). + // Reactor)? (Alex). // @@ Alex: yes, the same connection may be used in multiple // threads, each with its own reactor. // @@ Carlos: But, where is that code now? I cant see it here now? - // (Alex). + // (Alex). // Cache the ORB core, it won't change and is used multiple times // below: - TAO_ORB_Core* orb_core = + TAO_ORB_Core* orb_core = this->transport_->orb_core (); - + // Set the state so that we know we're looking for a response. // @@ Alex: maybe this should be managed by the Demux strategy? @@ -197,11 +198,11 @@ TAO_Wait_On_Leader_Follower::wait (void) // @@ Carlos: I have done this: There is a <send_request> method for // this class now. (Alex). - + // Obtain the lock. ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, orb_core->leader_follower_lock (), -1); - + // Check if there is a leader, but the leader is not us if (orb_core->leader_available () && !orb_core->I_am_the_leader_thread ()) { @@ -270,7 +271,7 @@ TAO_Wait_On_Leader_Follower::wait (void) int result = 0; - while (result == 0 && !this->reply_received_) + while (result >= 0 && this->reply_received_ == 0) result = orb_core->reactor ()->handle_events (); // Wake up the next leader, we cannot do that in handle_input, @@ -291,12 +292,17 @@ TAO_Wait_On_Leader_Follower::wait (void) "handle_events failed.\n"), -1); + // Return an error if there was a problem receiving the reply... + result = 0; + if (this->reply_received_ == -1) + result = -1; + // Make us reusable this->reply_received_ = 0; this->expecting_response_ = 0; this->calling_thread_ = ACE_OS::NULL_thread; - return 0; + return result; } // Handle the input. Return -1 on error, 0 on success. @@ -322,9 +328,13 @@ TAO_Wait_On_Leader_Follower::handle_input (void) // Severe error, abort.... if (result == -1) - return -1; + { + this->reply_received_ = -1; + return -1; + } + - // Bata was read, but there the reply has not been completely + // Data was read, but there the reply has not been completely // received... if (result == 0) return 0; @@ -336,7 +346,7 @@ TAO_Wait_On_Leader_Follower::handle_input (void) { // We are the leader thread, simply return 1 to terminate the // event loop.... - return 1; + return 0; } // We are not the leader thread, but we have our data, wake up @@ -365,7 +375,7 @@ TAO_Wait_On_Leader_Follower::handle_input (void) int TAO_Wait_On_Leader_Follower::register_handler (void) { - return 0; + return this->transport_->register_handler (); } // Resume the connection handler. diff --git a/TAO/tests/MT_Client/Makefile b/TAO/tests/MT_Client/Makefile index 329cc324aeb..ef03f34ca3d 100644 --- a/TAO/tests/MT_Client/Makefile +++ b/TAO/tests/MT_Client/Makefile @@ -15,11 +15,12 @@ endif # ! TAO_ROOT LDLIBS = -lTAO IDLFILES = testC testS -BIN = client server orb_creation +BIN = client server orb_creation simple-client SRC = $(addsuffix .cpp, $(BIN) $(IDLFILES) test_i) CLIENT_OBJS = client.o $(addsuffix .o, $(IDLFILES)) +SIMPLE_CLIENT_OBJS = simple-client.o $(addsuffix .o, $(IDLFILES)) ORB_CREATION_OBJS = orb_creation.o $(addsuffix .o, $(IDLFILES)) SERVER_OBJS = server.o test_i.o $(addsuffix .o, $(IDLFILES)) @@ -56,6 +57,9 @@ client: $(addprefix $(VDIR),$(CLIENT_OBJS)) orb_creation: $(addprefix $(VDIR),$(ORB_CREATION_OBJS)) $(LINK.cc) $(LDFLAGS) -o $@ $^ $(VLDLIBS) $(POSTLINK) +simple-client: $(addprefix $(VDIR),$(SIMPLE_CLIENT_OBJS)) + $(LINK.cc) $(LDFLAGS) -o $@ $^ $(VLDLIBS) $(POSTLINK) + realclean: clean -$(RM) testC.* testS.* testS_T.* @@ -182,8 +186,7 @@ realclean: clean $(ACE_ROOT)/ace/Stream_Modules.h \ $(ACE_ROOT)/ace/Stream_Modules.i \ $(ACE_ROOT)/ace/Stream_Modules.cpp \ - testC.h \ - $(TAO_ROOT)/tao/corba.h \ + testC.h $(TAO_ROOT)/tao/corba.h \ $(TAO_ROOT)/tao/corbafwd.h \ $(ACE_ROOT)/ace/CDR_Stream.h \ $(ACE_ROOT)/ace/CDR_Stream.i \ @@ -325,6 +328,7 @@ realclean: clean $(TAO_ROOT)/tao/Operation_Table.h \ $(TAO_ROOT)/tao/Client_Strategy_Factory.h \ $(TAO_ROOT)/tao/Invocation.h \ + $(TAO_ROOT)/tao/Reply_Dispatcher.h \ $(TAO_ROOT)/tao/Invocation.i \ $(TAO_ROOT)/tao/InconsistentTypeCodeC.h \ $(TAO_ROOT)/tao/DynAny_i.h \ @@ -352,8 +356,8 @@ realclean: clean $(ACE_ROOT)/ace/SString.i \ $(ACE_ROOT)/ace/Malloc_Base.h \ $(ACE_ROOT)/ace/Log_Record.i \ - $(ACE_ROOT)/ace/Get_Opt.i \ - test_i.h testS.h testC.h \ + $(ACE_ROOT)/ace/Get_Opt.i test_i.h \ + testS.h testC.h \ $(TAO_ROOT)/tao/corba.h \ $(TAO_ROOT)/tao/corbafwd.h \ $(ACE_ROOT)/ace/CDR_Stream.h \ @@ -597,6 +601,7 @@ realclean: clean $(TAO_ROOT)/tao/Operation_Table.h \ $(TAO_ROOT)/tao/Client_Strategy_Factory.h \ $(TAO_ROOT)/tao/Invocation.h \ + $(TAO_ROOT)/tao/Reply_Dispatcher.h \ $(TAO_ROOT)/tao/Invocation.i \ $(TAO_ROOT)/tao/InconsistentTypeCodeC.h \ $(TAO_ROOT)/tao/DynAny_i.h \ @@ -726,8 +731,279 @@ realclean: clean $(ACE_ROOT)/ace/Stream_Modules.h \ $(ACE_ROOT)/ace/Stream_Modules.i \ $(ACE_ROOT)/ace/Stream_Modules.cpp \ - testC.h \ - $(TAO_ROOT)/tao/corba.h \ + testC.h $(TAO_ROOT)/tao/corba.h \ + $(TAO_ROOT)/tao/corbafwd.h \ + $(ACE_ROOT)/ace/CDR_Stream.h \ + $(ACE_ROOT)/ace/CDR_Stream.i \ + $(TAO_ROOT)/tao/try_macros.h \ + $(TAO_ROOT)/tao/orbconf.h \ + $(ACE_ROOT)/ace/CORBA_macros.h \ + $(TAO_ROOT)/tao/Environment.h \ + $(TAO_ROOT)/tao/Environment.i \ + $(TAO_ROOT)/tao/ORB.h \ + $(TAO_ROOT)/tao/Exception.h \ + $(TAO_ROOT)/tao/Exception.i \ + $(TAO_ROOT)/tao/IOR_LookupTable.h \ + $(TAO_ROOT)/tao/ORB.i \ + $(TAO_ROOT)/tao/Any.h \ + $(TAO_ROOT)/tao/CDR.h \ + $(TAO_ROOT)/tao/Typecode.h \ + $(TAO_ROOT)/tao/Typecode.i \ + $(TAO_ROOT)/tao/CDR.i \ + $(TAO_ROOT)/tao/Object.h \ + $(TAO_ROOT)/tao/Object.i \ + $(TAO_ROOT)/tao/Any.i \ + $(TAO_ROOT)/tao/NVList.h \ + $(TAO_ROOT)/tao/NVList.i \ + $(TAO_ROOT)/tao/Principal.h \ + $(TAO_ROOT)/tao/Sequence.h \ + $(TAO_ROOT)/tao/Managed_Types.h \ + $(TAO_ROOT)/tao/Managed_Types.i \ + $(TAO_ROOT)/tao/Sequence.i \ + $(TAO_ROOT)/tao/Principal.i \ + $(TAO_ROOT)/tao/Request.h \ + $(TAO_ROOT)/tao/Context.h \ + $(TAO_ROOT)/tao/Context.i \ + $(TAO_ROOT)/tao/Request.i \ + $(TAO_ROOT)/tao/Server_Request.h \ + $(TAO_ROOT)/tao/Object_KeyC.h \ + $(TAO_ROOT)/tao/Object_KeyC.i \ + $(TAO_ROOT)/tao/GIOP.h \ + $(TAO_ROOT)/tao/Sequence_T.h \ + $(TAO_ROOT)/tao/Sequence_T.i \ + $(TAO_ROOT)/tao/Sequence_T.cpp \ + $(TAO_ROOT)/tao/GIOP.i \ + $(TAO_ROOT)/tao/Server_Request.i \ + $(TAO_ROOT)/tao/varout.h \ + $(TAO_ROOT)/tao/varout.i \ + $(TAO_ROOT)/tao/varout.cpp \ + $(TAO_ROOT)/tao/Marshal.h \ + $(TAO_ROOT)/tao/Marshal.i \ + $(TAO_ROOT)/tao/singletons.h \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Singleton.cpp \ + $(TAO_ROOT)/tao/PolicyC.h \ + $(TAO_ROOT)/tao/CurrentC.h \ + $(TAO_ROOT)/tao/CurrentC.i \ + $(TAO_ROOT)/tao/PolicyC.i \ + $(TAO_ROOT)/tao/POA.h \ + $(TAO_ROOT)/tao/POAC.h \ + $(TAO_ROOT)/tao/POAC.i \ + $(TAO_ROOT)/tao/Servant_Base.h \ + $(TAO_ROOT)/tao/Servant_Base.i \ + $(TAO_ROOT)/tao/POAS.h \ + $(TAO_ROOT)/tao/POA_CORBA.h \ + $(TAO_ROOT)/tao/DynAnyC.h \ + $(TAO_ROOT)/tao/DynAnyC.i \ + $(TAO_ROOT)/tao/POAS.i \ + $(TAO_ROOT)/tao/Active_Object_Map.h \ + $(TAO_ROOT)/tao/Key_Adapters.h \ + $(ACE_ROOT)/ace/Map.h \ + $(ACE_ROOT)/ace/Map.i \ + $(ACE_ROOT)/ace/Map_T.h \ + $(ACE_ROOT)/ace/Pair.h \ + $(ACE_ROOT)/ace/Pair.i \ + $(ACE_ROOT)/ace/Pair_T.h \ + $(ACE_ROOT)/ace/Pair_T.i \ + $(ACE_ROOT)/ace/Pair_T.cpp \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Map_Manager.cpp \ + $(ACE_ROOT)/ace/Active_Map_Manager.h \ + $(ACE_ROOT)/ace/Active_Map_Manager.i \ + $(ACE_ROOT)/ace/Active_Map_Manager_T.h \ + $(ACE_ROOT)/ace/Active_Map_Manager_T.i \ + $(ACE_ROOT)/ace/Active_Map_Manager_T.cpp \ + $(ACE_ROOT)/ace/Map_T.i \ + $(ACE_ROOT)/ace/Map_T.cpp \ + $(TAO_ROOT)/tao/Key_Adapters.i \ + $(TAO_ROOT)/tao/Server_Strategy_Factory.h \ + $(TAO_ROOT)/tao/Connect.h \ + $(ACE_ROOT)/ace/Acceptor.h \ + $(ACE_ROOT)/ace/Svc_Handler.h \ + $(ACE_ROOT)/ace/Svc_Handler.i \ + $(ACE_ROOT)/ace/Svc_Handler.cpp \ + $(ACE_ROOT)/ace/Dynamic.h \ + $(ACE_ROOT)/ace/Dynamic.i \ + $(ACE_ROOT)/ace/Acceptor.i \ + $(ACE_ROOT)/ace/Acceptor.cpp \ + $(ACE_ROOT)/ace/SOCK_Acceptor.h \ + $(ACE_ROOT)/ace/SOCK_Stream.h \ + $(ACE_ROOT)/ace/SOCK_IO.h \ + $(ACE_ROOT)/ace/SOCK.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/IPC_SAP.h \ + $(ACE_ROOT)/ace/IPC_SAP.i \ + $(ACE_ROOT)/ace/SOCK.i \ + $(ACE_ROOT)/ace/SOCK_IO.i \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/SOCK_Stream.i \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/SOCK_Acceptor.i \ + $(TAO_ROOT)/tao/Connect.i \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/Active_Object_Map.i \ + $(TAO_ROOT)/tao/POAManager.h \ + $(TAO_ROOT)/tao/poa_macros.h \ + $(TAO_ROOT)/tao/POAManager.i \ + $(TAO_ROOT)/tao/Object_Adapter.h \ + $(TAO_ROOT)/tao/Object_Adapter.i \ + $(TAO_ROOT)/tao/POA.i \ + $(TAO_ROOT)/tao/Stub.h \ + $(TAO_ROOT)/tao/Pluggable.h \ + $(TAO_ROOT)/tao/MProfile.h \ + $(TAO_ROOT)/tao/MProfile.i \ + $(TAO_ROOT)/tao/Stub.i \ + $(TAO_ROOT)/tao/ORB_Core.h \ + $(TAO_ROOT)/tao/Policy_Manager.h \ + $(TAO_ROOT)/tao/Resource_Factory.h \ + $(TAO_ROOT)/tao/IIOP_Connector.h \ + $(ACE_ROOT)/ace/Connector.h \ + $(ACE_ROOT)/ace/Connector.i \ + $(ACE_ROOT)/ace/Connector.cpp \ + $(ACE_ROOT)/ace/SOCK_Connector.h \ + $(ACE_ROOT)/ace/SOCK_Connector.i \ + $(TAO_ROOT)/tao/ORB_Core.i \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(ACE_ROOT)/ace/Dynamic_Service.cpp \ + $(TAO_ROOT)/tao/Operation_Table.h \ + $(TAO_ROOT)/tao/Client_Strategy_Factory.h \ + $(TAO_ROOT)/tao/Invocation.h \ + $(TAO_ROOT)/tao/Reply_Dispatcher.h \ + $(TAO_ROOT)/tao/Invocation.i \ + $(TAO_ROOT)/tao/InconsistentTypeCodeC.h \ + $(TAO_ROOT)/tao/DynAny_i.h \ + $(TAO_ROOT)/tao/Union.h \ + $(TAO_ROOT)/tao/ValueBase.h \ + $(TAO_ROOT)/tao/ValueBase.i \ + $(TAO_ROOT)/tao/ValueFactory.h \ + $(TAO_ROOT)/tao/ValueFactory.i \ + testC.i +.obj/simple-client.o .obj/simple-client.so .shobj/simple-client.o .shobj/simple-client.so: simple-client.cpp \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/inc_user_config.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/Malloc_Base.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(ACE_ROOT)/ace/Task.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Synch_T.cpp \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Containers_T.h \ + $(ACE_ROOT)/ace/Containers_T.i \ + $(ACE_ROOT)/ace/Containers_T.cpp \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Free_List.cpp \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Malloc_T.cpp \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Managed_Object.cpp \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Task.i \ + $(ACE_ROOT)/ace/Task_T.h \ + $(ACE_ROOT)/ace/Message_Queue.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/Message_Block_T.h \ + $(ACE_ROOT)/ace/Message_Block_T.i \ + $(ACE_ROOT)/ace/Message_Block_T.cpp \ + $(ACE_ROOT)/ace/IO_Cntl_Msg.h \ + $(ACE_ROOT)/ace/Message_Queue_T.h \ + $(ACE_ROOT)/ace/Message_Queue_T.i \ + $(ACE_ROOT)/ace/Message_Queue_T.cpp \ + $(ACE_ROOT)/ace/Strategies.h \ + $(ACE_ROOT)/ace/Strategies_T.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.cpp \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Synch_Options.h \ + $(ACE_ROOT)/ace/Synch_Options.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(ACE_ROOT)/ace/Functor.h \ + $(ACE_ROOT)/ace/Functor.i \ + $(ACE_ROOT)/ace/Functor_T.h \ + $(ACE_ROOT)/ace/Functor_T.i \ + $(ACE_ROOT)/ace/Functor_T.cpp \ + $(ACE_ROOT)/ace/Hash_Map_Manager.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.h \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.cpp \ + $(ACE_ROOT)/ace/Strategies_T.i \ + $(ACE_ROOT)/ace/Strategies_T.cpp \ + $(ACE_ROOT)/ace/Service_Repository.h \ + $(ACE_ROOT)/ace/Service_Types.h \ + $(ACE_ROOT)/ace/Service_Types.i \ + $(ACE_ROOT)/ace/Service_Repository.i \ + $(ACE_ROOT)/ace/WFMO_Reactor.h \ + $(ACE_ROOT)/ace/WFMO_Reactor.i \ + $(ACE_ROOT)/ace/Strategies.i \ + $(ACE_ROOT)/ace/Message_Queue.i \ + $(ACE_ROOT)/ace/Task_T.i \ + $(ACE_ROOT)/ace/Task_T.cpp \ + $(ACE_ROOT)/ace/Module.h \ + $(ACE_ROOT)/ace/Module.i \ + $(ACE_ROOT)/ace/Module.cpp \ + $(ACE_ROOT)/ace/Stream_Modules.h \ + $(ACE_ROOT)/ace/Stream_Modules.i \ + $(ACE_ROOT)/ace/Stream_Modules.cpp \ + testC.h $(TAO_ROOT)/tao/corba.h \ $(TAO_ROOT)/tao/corbafwd.h \ $(ACE_ROOT)/ace/CDR_Stream.h \ $(ACE_ROOT)/ace/CDR_Stream.i \ @@ -869,6 +1145,7 @@ realclean: clean $(TAO_ROOT)/tao/Operation_Table.h \ $(TAO_ROOT)/tao/Client_Strategy_Factory.h \ $(TAO_ROOT)/tao/Invocation.h \ + $(TAO_ROOT)/tao/Reply_Dispatcher.h \ $(TAO_ROOT)/tao/Invocation.i \ $(TAO_ROOT)/tao/InconsistentTypeCodeC.h \ $(TAO_ROOT)/tao/DynAny_i.h \ @@ -1138,6 +1415,7 @@ realclean: clean $(TAO_ROOT)/tao/Operation_Table.h \ $(TAO_ROOT)/tao/Client_Strategy_Factory.h \ $(TAO_ROOT)/tao/Invocation.h \ + $(TAO_ROOT)/tao/Reply_Dispatcher.h \ $(TAO_ROOT)/tao/Invocation.i \ $(TAO_ROOT)/tao/InconsistentTypeCodeC.h \ $(TAO_ROOT)/tao/DynAny_i.h \ @@ -1407,6 +1685,7 @@ realclean: clean $(TAO_ROOT)/tao/Operation_Table.h \ $(TAO_ROOT)/tao/Client_Strategy_Factory.h \ $(TAO_ROOT)/tao/Invocation.h \ + $(TAO_ROOT)/tao/Reply_Dispatcher.h \ $(TAO_ROOT)/tao/Invocation.i \ $(TAO_ROOT)/tao/InconsistentTypeCodeC.h \ $(TAO_ROOT)/tao/DynAny_i.h \ @@ -1676,6 +1955,7 @@ realclean: clean $(TAO_ROOT)/tao/Operation_Table.h \ $(TAO_ROOT)/tao/Client_Strategy_Factory.h \ $(TAO_ROOT)/tao/Invocation.h \ + $(TAO_ROOT)/tao/Reply_Dispatcher.h \ $(TAO_ROOT)/tao/Invocation.i \ $(TAO_ROOT)/tao/InconsistentTypeCodeC.h \ $(TAO_ROOT)/tao/DynAny_i.h \ diff --git a/TAO/tests/MT_Client/client.cpp b/TAO/tests/MT_Client/client.cpp index 8ef8b987e28..d9680c0d511 100644 --- a/TAO/tests/MT_Client/client.cpp +++ b/TAO/tests/MT_Client/client.cpp @@ -141,19 +141,19 @@ Client::svc (void) ACE_TRY_CHECK; CORBA::Long number = 0; - + for (int i = 0; i < this->niterations_; ++i) { number = server_->get_number (ACE_TRY_ENV); ACE_TRY_CHECK; - - ACE_DEBUG ((LM_DEBUG, - "get_number = %d\n", - number)); - + + // ACE_DEBUG ((LM_DEBUG, + // "get_number = %d\n", + // number)); + server_->test_method (ACE_TRY_ENV); ACE_TRY_CHECK; - + if (TAO_debug_level > 0 && i % 100 == 0) ACE_DEBUG ((LM_DEBUG, "(%P|%t) iteration = %d\n", i)); } diff --git a/TAO/tests/MT_Client/server.conf b/TAO/tests/MT_Client/server.conf index f56feb1f8d0..faf9c6c874b 100644 --- a/TAO/tests/MT_Client/server.conf +++ b/TAO/tests/MT_Client/server.conf @@ -1,3 +1,3 @@ # $Id$ # -dynamic Server_Strategy_Factory Service_Object * TAO:_make_TAO_Default_Server_Strategy_Factory() "-ORBconcurrency thread-per-connection" +static Server_Strategy_Factory "-ORBconcurrency thread-per-connection" diff --git a/TAO/tests/MT_Client/simple-client.cpp b/TAO/tests/MT_Client/simple-client.cpp index 5334c4a97e2..629708beb12 100644 --- a/TAO/tests/MT_Client/simple-client.cpp +++ b/TAO/tests/MT_Client/simple-client.cpp @@ -7,13 +7,12 @@ ACE_RCSID(MT_Client, client, "$Id$") const char *ior = "file://test.ior"; -int nthreads = 5; int niterations = 5; int parse_args (int argc, char *argv[]) { - ACE_Get_Opt get_opts (argc, argv, "k:n:i:"); + ACE_Get_Opt get_opts (argc, argv, "k:i:"); int c; while ((c = get_opts ()) != -1) @@ -22,9 +21,6 @@ parse_args (int argc, char *argv[]) case 'k': ior = get_opts.optarg; break; - case 'n': - nthreads = ACE_OS::atoi (get_opts.optarg); - break; case 'i': niterations = ACE_OS::atoi (get_opts.optarg); break; @@ -33,7 +29,6 @@ parse_args (int argc, char *argv[]) ACE_ERROR_RETURN ((LM_ERROR, "usage: %s " "-k <ior> " - "-n <nthreads> " "-i <niterations> " "\n", argv [0]), @@ -43,29 +38,6 @@ parse_args (int argc, char *argv[]) return 0; } -class Client : public ACE_Task_Base -{ - // = TITLE - // Run the client thread - // - // = DESCRIPTION - // Use the ACE_Task_Base class to run the client threads. - // -public: - Client (Simple_Server_ptr server, int niterations); - // ctor - - virtual int svc (void); - // The thread entry point. - -private: - Simple_Server_var server_; - // The server. - - int niterations_; - // The number of iterations on each client thread. -}; - int main (int argc, char *argv[]) { @@ -94,26 +66,22 @@ main (int argc, char *argv[]) 1); } - CORBA::Long number = 0; + for (int i = 0; i != niterations; ++i) + { + CORBA::Long number = 0; - number = server->get_number (ACE_TRY_ENV); - ACE_TRY_CHECK; + number = server->get_number (ACE_TRY_ENV); + ACE_TRY_CHECK; - ACE_DEBUG ((LM_DEBUG, - "get_number = %d\n", - number)); - - number = server->get_number (ACE_TRY_ENV); - ACE_TRY_CHECK; - - ACE_DEBUG ((LM_DEBUG, - "get_number = %d\n", - number)); + ACE_DEBUG ((LM_DEBUG, + "get_number = %d\n", + number)); - server->test_method (ACE_TRY_ENV); - ACE_TRY_CHECK; + server->test_method (ACE_TRY_ENV); + ACE_TRY_CHECK; + } - server->shutdown (ACE_TRY_ENV); + server->shutdown (ACE_TRY_ENV); } ACE_CATCHANY { @@ -125,42 +93,3 @@ main (int argc, char *argv[]) return 0; } - -// **************************************************************** - -Client::Client (Simple_Server_ptr server, - int niterations) - : server_ (Simple_Server::_duplicate (server)), - niterations_ (niterations) -{ -} - -int -Client::svc (void) -{ - ACE_TRY_NEW_ENV - { - // If we are using a global ORB this is a nop, otherwise it - // initializes the ORB resources for this thread. - int argc = 0; - char* argv[] = { "" }; - CORBA::ORB_var orb = - CORBA::ORB_init (argc, argv, "", ACE_TRY_ENV); - ACE_TRY_CHECK; - - for (int i = 0; i < this->niterations_; ++i) - { - this->server_->test_method (ACE_TRY_ENV); - ACE_TRY_CHECK; - if (TAO_debug_level > 0 && i % 100 == 0) - ACE_DEBUG ((LM_DEBUG, "(%P|%t) iteration = %d\n", i)); - } - } - ACE_CATCHANY - { - ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, - "MT_Client: exception raised"); - } - ACE_ENDTRY; - return 0; -} |