diff options
author | mk1 <mk1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-06-12 02:18:02 +0000 |
---|---|---|
committer | mk1 <mk1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-06-12 02:18:02 +0000 |
commit | 48dfd3ac0bbaaa5091260859e2e79ae01b176664 (patch) | |
tree | 6947004db5f4bc6b78119c9cc0ea93fd822bd179 /TAO/tao | |
parent | a01d0b8ea55bedb117b5f9786f7733f54482f352 (diff) | |
download | ATCD-48dfd3ac0bbaaa5091260859e2e79ae01b176664.tar.gz |
ChangeLog entry: Thu Jun 11 21:15:00 1998 Michael Kircher <mk1@cs.wustl.edu>
Diffstat (limited to 'TAO/tao')
-rw-r--r-- | TAO/tao/Connect.cpp | 159 | ||||
-rw-r--r-- | TAO/tao/Connect.h | 14 | ||||
-rw-r--r-- | TAO/tao/GIOP.cpp | 219 | ||||
-rw-r--r-- | TAO/tao/GIOP.h | 5 | ||||
-rw-r--r-- | TAO/tao/IIOP_ORB.cpp | 7 | ||||
-rw-r--r-- | TAO/tao/IIOP_Object.cpp | 20 | ||||
-rw-r--r-- | TAO/tao/IIOP_Object.h | 37 | ||||
-rw-r--r-- | TAO/tao/IIOP_Object.i | 45 | ||||
-rw-r--r-- | TAO/tao/Server_Request.cpp | 61 | ||||
-rw-r--r-- | TAO/tao/Server_Request.h | 7 | ||||
-rw-r--r-- | TAO/tao/Server_Request.i | 6 |
11 files changed, 333 insertions, 247 deletions
diff --git a/TAO/tao/Connect.cpp b/TAO/tao/Connect.cpp index 73864dd1bce..cefcd34e9b0 100644 --- a/TAO/tao/Connect.cpp +++ b/TAO/tao/Connect.cpp @@ -176,11 +176,14 @@ TAO_Server_Connection_Handler::svc (void) // non-zero if for a two-way and <output> to any necessary response // (including errors). In case of errors, -1 is returned and // additional information carried in <env>. +// The request ID is needed by handle_input, so a it is passed back +// as reference. int TAO_Server_Connection_Handler::handle_message (TAO_InputCDR &input, TAO_OutputCDR &output, int &response_required, + CORBA::ULong &request_id, CORBA::Environment &env) { TAO_POA *the_poa = TAO_ORB_Core_instance ()->root_poa (); @@ -192,6 +195,11 @@ TAO_Server_Connection_Handler::handle_message (TAO_InputCDR &input, TAO_ORB_Core_instance ()->orb (), the_poa, env); + + // The request_id_ field in request will be 0 if something went + // wrong before it got a chance to read it out. + request_id = request.request_id (); + if (env.exception ()) return -1; @@ -213,16 +221,21 @@ TAO_Server_Connection_Handler::handle_message (TAO_InputCDR &input, request, 0, env); + // Need to check for any errors present in <env> and set the return // code appropriately. - return 0; + if (env.exception () != 0) + return -1; + else + return 0; } int TAO_Server_Connection_Handler::handle_locate (TAO_InputCDR &input, TAO_OutputCDR &output, int &response_required, + CORBA::ULong &request_id, CORBA::Environment &env) { // This will extract the request header, set <response_required> as @@ -233,9 +246,12 @@ TAO_Server_Connection_Handler::handle_locate (TAO_InputCDR &input, if (! req.init (input, env)) { // @@ FIXME! Need to set <env>. + request_id = req.request_id; response_required = 0; return -1; } + // Copy the request ID to be able to respond in case of an exception + request_id = req.request_id; response_required = 1; // Be optimistic @@ -253,8 +269,11 @@ TAO_Server_Connection_Handler::handle_locate (TAO_InputCDR &input, // not found, report unknown status = TAO_GIOP_UNKNOWN_OBJECT; - // Remove the exception - env.clear (); + // @@ Michael: Now we marshall the exceptions here + // and send them over the wire. I think we don't need + // to remove the exception here. + // // Remove the exception + // env.clear (); } // Create the response. @@ -262,9 +281,12 @@ TAO_Server_Connection_Handler::handle_locate (TAO_InputCDR &input, output.write_ulong (req.request_id); output.write_ulong (status); - // Need to check for any errors present in <env> and set the return - // code appropriately. - return 0; + if (env.exception () != 0) + // An exception was thrown + return -1; + else + // Everything is ok. + return 0; } void @@ -276,6 +298,96 @@ TAO_Server_Connection_Handler::send_response (TAO_OutputCDR &output) TAO_GIOP::send_request (this_ptr, output); } +// This method is designed to return system exceptions to the caller +void +TAO_Server_Connection_Handler::send_error (CORBA::ULong request_id, + CORBA::Environment &env) +{ + ACE_FUNCTION_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_SEND_RESPONSE_START); + + // The request_id is going to be not 0, if it was sucessfully read + if (request_id != 0) + { + // Create a new output CDR stream + TAO_OutputCDR output; + + // Construct a REPLY header. + TAO_GIOP::start_message (TAO_GIOP::Reply, output); + + // A new envrionment, if something goes wrong now -> no hope! + CORBA::Environment env2; + + // create and write a dummy context + TAO_GIOP_ServiceContextList resp_ctx; + resp_ctx.length (0); + output.encode (TC_ServiceContextList, + &resp_ctx, + 0, + env2); + + if (env2.exception() == 0) + { + // Write the request ID + output.write_ulong (request_id); + + // Write the exception + CORBA::Exception *x = env.exception (); + CORBA::TypeCode_ptr except_tc = x->_type (); + + // Now we check for Forwarding *************************** + + // Try to narrow to ForwardRequest + PortableServer::ForwardRequest_ptr forward_request_ptr = + PortableServer::ForwardRequest::_narrow (env.exception()); + + // If narrowing of exception succeeded + if (forward_request_ptr != 0 && + !CORBA::is_nil (forward_request_ptr->forward_reference)) + { + // write the reply_status + output.write_ulong (TAO_GIOP_LOCATION_FORWARD); + + // write the object reference into the stream + CORBA::Object_ptr object_ptr = forward_request_ptr->forward_reference; + + output.encode (CORBA::_tc_Object, + &object_ptr, + 0, + env2); + } + // end of the forwarding code **************************** + else + { + // write the reply_status + output.write_ulong (TAO_GIOP_SYSTEM_EXCEPTION); + + // write the actual exception + output.encode (except_tc, x, 0, env2); + } + + // exception handling for both alternatives + if (env2.exception() == 0) + { + // hand it to the next lower layer + TAO_SVC_HANDLER *this_ptr = this; + TAO_GIOP::send_request (this_ptr, output); + // now we have done all what was possible, + // send_request might have had an error + // and closed the connection, but we are done. + return; + } + } + } + // now we know, that while handling the error an other + // error happened -> no hope, close connection. + + // close the handle + ACE_DEBUG ((LM_DEBUG,"(%P|%t) closing conn %d after fault %p\n", + this->peer().get_handle (), "TAO_Server_ConnectionHandler::send_error")); + this->close (); +} + + int TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) { @@ -303,6 +415,7 @@ TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) int response_required; TAO_SVC_HANDLER *this_ptr = this; CORBA::Environment env; + CORBA::ULong request_id; switch (TAO_GIOP::recv_request (this_ptr, input)) { @@ -310,12 +423,20 @@ TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) // Message was successfully read, so handle it. If we encounter // any errors, <output> will be set appropriately by the called // code, and -1 will be returned. - if (this->handle_message (input, output, response_required, env) == -1) + if (this->handle_message (input, + output, + response_required, + request_id, + env) == -1) error_encountered = 1; break; case TAO_GIOP::LocateRequest: - if (this->handle_locate (input, output, response_required, env) == -1) + if (this->handle_locate (input, + output, + response_required, + request_id, + env) == -1) error_encountered = 1; break; @@ -343,13 +464,21 @@ TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) break; } - // Message was successfully read, so handle it. If we encounter - // any errors, <output> will be set appropriately by the called - // code, and -1 will be returned. - - if (response_required || error_encountered) - this->send_response (output); - + if (response_required && !error_encountered) + // Normal response + this->send_response (output); + else if (error_encountered && (env.exception() != 0)) + // Something happened and we know why + this->send_error (request_id, env); + else + { + // Now we are completely lost + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) closing conn %d after fault %p\n", + this->peer().get_handle (), + "TAO_Server_ConnectionHandler::handle_input")); + this->close (); + } return result; } diff --git a/TAO/tao/Connect.h b/TAO/tao/Connect.h index 3ae64a73762..024a9ff7218 100644 --- a/TAO/tao/Connect.h +++ b/TAO/tao/Connect.h @@ -113,8 +113,9 @@ public: virtual int handle_message (TAO_InputCDR &msg, TAO_OutputCDR &response, - int &response_required, - CORBA::Environment &env); + int &response_required, + CORBA::ULong &request_id, + CORBA::Environment &env); // Handle processing of the request residing in <msg>, setting // <response_required> to zero if the request is for a oneway or // non-zero if for a two-way and <response> to any necessary @@ -124,8 +125,9 @@ public: protected: virtual int handle_locate (TAO_InputCDR &msg, TAO_OutputCDR &response, - int &response_required, - CORBA::Environment &env); + int &response_required, + CORBA::ULong &request_id, + CORBA::Environment &env); // Handle processing of the location request residing in <msg>, // setting <response_required> to one if no errors are encountered. // The LocateRequestReply is placed into <response>. In case of @@ -134,6 +136,10 @@ protected: virtual void send_response (TAO_OutputCDR &response); // Send <response> to the client on the other end. + + void send_error (CORBA::ULong request_id, CORBA::Environment &env); + // Send <error> to the client on the other end, which + // means basically sending the exception. // = Event Handler overloads diff --git a/TAO/tao/GIOP.cpp b/TAO/tao/GIOP.cpp index b58de1289f6..a8bd37fb558 100644 --- a/TAO/tao/GIOP.cpp +++ b/TAO/tao/GIOP.cpp @@ -633,23 +633,8 @@ TAO_GIOP_Invocation::start (CORBA::Environment &env) // connection. ACE_INET_Addr *server_addr_p = 0; - { - // Begin a new scope so we keep this lock only as long as - // necessary -#if 0 /* Keep this around for when forwarding might be implemented (if ever) */ - ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, guard, data_->fwd_profile_lock ())); -#endif - if (data_->fwd_profile_i () != 0) - { - key = &data_->fwd_profile_i ()->object_key; - server_addr_p = &data_->fwd_profile_i ()->object_addr (); - } - else - { - key = &data_->profile.object_key; - server_addr_p = &data_->profile.object_addr (); - } - } + key = &data_->profile.object_key; + server_addr_p = &data_->profile.object_addr (); if (server_addr_p == 0) { @@ -874,19 +859,21 @@ TAO_GIOP_Invocation::invoke (CORBA::ExceptionList &exceptions, // resource being reclaimed might also have been the process, // not just the connection. Without reinitializing, we'd give // false error reports to applications. + // @@ Michael + /* { -#if 0 /* Keep this around in case forwarding is ever implemented */ - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, data_->fwd_profile_lock (), TAO_GIOP_SYSTEM_EXCEPTION)); -#endif + + // Keep this around in case forwarding is ever implemented + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, data_->fwd_profile_lock (), TAO_GIOP_SYSTEM_EXCEPTION)); IIOP::Profile *old = data_->fwd_profile_i (0); delete old; - this->handler_->close (); - this->handler_ = 0; - return TAO_GIOP_LOCATION_FORWARD; - } - + */ + this->handler_->close (); + this->handler_ = 0; + return TAO_GIOP_LOCATION_FORWARD; + case TAO_GIOP::Request: case TAO_GIOP::CancelRequest: case TAO_GIOP::LocateRequest: @@ -1074,54 +1061,7 @@ TAO_GIOP_Invocation::invoke (CORBA::ExceptionList &exceptions, // NOTREACHED case TAO_GIOP_LOCATION_FORWARD: - { - CORBA::Object_ptr obj; - IIOP_Object *obj2; - - // Unmarshal the object we _should_ be calling. We know that - // one of the facets of this object will be an IIOP invocation - // profile. - - if (this->inp_stream_.decode (CORBA::_tc_Object, - &obj, 0, - env) != CORBA::TypeCode::TRAVERSE_CONTINUE - || obj->QueryInterface (IID_IIOP_Object, - (void **) &obj2) != TAO_NOERROR) - { - dexc (env, "invoke, location forward"); - TAO_GIOP::send_error (this->handler_); - return TAO_GIOP_SYSTEM_EXCEPTION; - } - CORBA::release (obj); - - // Make a copy of the IIOP profile in the forwarded objref, - // reusing memory where practical. Then delete the forwarded - // objref, retaining only its profile. - // - // @@ add and use a "forward count", to prevent loss of data - // in forwarding chains during concurrent calls -- only a - // forward that's a response to the current fwd_profile should - // be recorded here. (This is just an optimization, and is not - // related to correctness.) - -#if 0 /* Keep this around in case forwarding is ever implemented. */ - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, data_->fwd_profile_lock (), TAO_GIOP_SYSTEM_EXCEPTION); -#endif - - IIOP::Profile *old = data_->fwd_profile_i (new IIOP::Profile (obj2->profile)); - delete old; - - obj2->Release (); - - env.clear (); - - // Make sure a new connection is used next time. - this->handler_->close (); - this->handler_ = 0; - // We may not need to do this since TAO_GIOP_Invocations - // get created on a per-call basis. For now we'll play it safe. - } - break; + return (this->location_forward (env)); } // All standard exceptions from here on in the call path know for @@ -1132,6 +1072,76 @@ TAO_GIOP_Invocation::invoke (CORBA::ExceptionList &exceptions, return (TAO_GIOP_ReplyStatusType) reply_status; } +// Handle the GIOP Reply with status = LOCATION_FORWARD +// Replace the IIOP Profile. The call is then automatically +// reinvoked by the IIOP_Object::do_static_call method. + +TAO_GIOP_ReplyStatusType +TAO_GIOP_Invocation::location_forward (CORBA::Environment &env) +{ + // It can be assumed that the GIOP header and the reply header + // are already handled. Further it can be assumed that the + // reply body contains and object reference to the new object. + // This object pointer will be now extracted. + + // @@ Memory leak examination: Michael + CORBA::Object_ptr object_ptr = 0; + //CORBA::Object_ptr object_ptr = object_var.inout(); + + if (this->inp_stream_.decode (CORBA::_tc_Object, + &(object_ptr), + 0, + env) != CORBA::TypeCode::TRAVERSE_CONTINUE) + { + dexc (env, "invoke, location forward (decode)"); + TAO_GIOP::send_error (this->handler_); + return TAO_GIOP_SYSTEM_EXCEPTION; + } + + // The object pointer has to be changed to a IIOP_Object pointer + // in order to extract the profile. + + IIOP_Object *iIOP_Object_ptr = 0; + + if (object_ptr->QueryInterface (IID_IIOP_Object, + (void **) &iIOP_Object_ptr) != TAO_NOERROR) + { + dexc (env, "invoke, location forward (QueryInterface)"); + TAO_GIOP::send_error (this->handler_); + return TAO_GIOP_SYSTEM_EXCEPTION; + } + + // The object is no longer needed, because we have now the IIOP_Object + CORBA::release (object_ptr); + CORBA::release (object_ptr); + + // Make a copy of the IIOP profile in the forwarded objref, + // reusing memory where practical. Then delete the forwarded + // objref, retaining only its profile. + // + // @@ add and use a "forward count", to prevent loss of data + // in forwarding chains during concurrent calls -- only a + // forward that's a response to the current fwd_profile should + // be recorded here. (This is just an optimization, and is not + // related to correctness.) + + // a copy operator for IIOP::Profile is defined, so don't worry + data_->profile = iIOP_Object_ptr->profile; + + + // Release the IIOP_Object + iIOP_Object_ptr->Release (); + + env.clear (); + + + // We may not need to do this since TAO_GIOP_Invocations + // get created on a per-call basis. For now we'll play it safe. + + return TAO_GIOP_LOCATION_FORWARD; +} + + // Send request, block until any reply comes back, and unmarshal reply // parameters as appropriate. // @@ -1225,18 +1235,20 @@ TAO_GIOP_Invocation::invoke (TAO_Exception_Data *excepts, // resource being reclaimed might also have been the process, // not just the connection. Without reinitializing, we'd give // false error reports to applications. + // @@ Michael + /* { -#if 0 /* Keep this around in case forwarding is ever implemented */ + // Keep this around in case forwarding is ever implemented ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, data_->fwd_profile_lock (), TAO_GIOP_SYSTEM_EXCEPTION)); -#endif + IIOP::Profile *old = data_->fwd_profile_i (0); delete old; + */ - this->handler_->close (); - this->handler_ = 0; - return TAO_GIOP_LOCATION_FORWARD; - } + this->handler_->close (); + this->handler_ = 0; + return TAO_GIOP_LOCATION_FORWARD; case TAO_GIOP::Request: case TAO_GIOP::CancelRequest: @@ -1457,54 +1469,7 @@ TAO_GIOP_Invocation::invoke (TAO_Exception_Data *excepts, // NOTREACHED case TAO_GIOP_LOCATION_FORWARD: - { - CORBA::Object_ptr obj; - IIOP_Object *obj2; - - // Unmarshal the object we _should_ be calling. We know that - // one of the facets of this object will be an IIOP invocation - // profile. - - if (this->inp_stream_.decode (CORBA::_tc_Object, - &obj, 0, - env) != CORBA::TypeCode::TRAVERSE_CONTINUE - || obj->QueryInterface (IID_IIOP_Object, - (void **) &obj2) != TAO_NOERROR) - { - dexc (env, "invoke, location forward"); - TAO_GIOP::send_error (this->handler_); - return TAO_GIOP_SYSTEM_EXCEPTION; - } - CORBA::release (obj); - - // Make a copy of the IIOP profile in the forwarded objref, - // reusing memory where practical. Then delete the forwarded - // objref, retaining only its profile. - // - // @@ add and use a "forward count", to prevent loss of data - // in forwarding chains during concurrent calls -- only a - // forward that's a response to the current fwd_profile should - // be recorded here. (This is just an optimization, and is not - // related to correctness.) - -#if 0 /* Keep this around in case forwarding is ever implemented. */ - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, data_->fwd_profile_lock (), TAO_GIOP_SYSTEM_EXCEPTION); -#endif - - IIOP::Profile *old = data_->fwd_profile_i (new IIOP::Profile (obj2->profile)); - delete old; - - obj2->Release (); - - env.clear (); - - // Make sure a new connection is used next time. - this->handler_->close (); - this->handler_ = 0; - // We may not need to do this since TAO_GIOP_Invocations - // get created on a per-call basis. For now we'll play it safe. - } - break; + return (this->location_forward (env)); } // All standard exceptions from here on in the call path know for diff --git a/TAO/tao/GIOP.h b/TAO/tao/GIOP.h index a20daf56c15..8e952804682 100644 --- a/TAO/tao/GIOP.h +++ b/TAO/tao/GIOP.h @@ -337,6 +337,11 @@ private: TAO_Client_Connection_Handler *handler_; // The handler for the client's connection. + + + TAO_GIOP_ReplyStatusType + TAO_GIOP_Invocation::location_forward (CORBA::Environment &env); + // do the location forwarding, which means exchanging the profile }; class TAO_Export TAO_GIOP diff --git a/TAO/tao/IIOP_ORB.cpp b/TAO/tao/IIOP_ORB.cpp index fba16e00ddb..94dc771fd1d 100644 --- a/TAO/tao/IIOP_ORB.cpp +++ b/TAO/tao/IIOP_ORB.cpp @@ -275,11 +275,12 @@ iiop_string_to_object (CORBA::String string, TAO_ServantBase *servant = TAO_ORB_Core_instance ()->orb ()->_get_collocated_servant (data); + // This will increase the ref_count on data by one CORBA_Object *obj = new CORBA_Object (data, servant, servant != 0); - // Clean up in case of error - if (obj == 0) - data->Release (); + // Set the ref_count on data to 1, which is correct, because only + // obj has now a reference to it. + data->Release (); return obj; } diff --git a/TAO/tao/IIOP_Object.cpp b/TAO/tao/IIOP_Object.cpp index d3fa2cacd0b..a1f14996ea6 100644 --- a/TAO/tao/IIOP_Object.cpp +++ b/TAO/tao/IIOP_Object.cpp @@ -204,6 +204,19 @@ IIOP::Profile::Profile (const ACE_INET_Addr &addr, (void) this->set (addr, key); } + +IIOP::Profile +&IIOP::Profile::operator = (const IIOP::Profile &src) +{ + this->set (src.host, + src.port, + src.object_key, + &src.object_addr_); + return *this; +} + + + // Quick'n'dirty hash of objref data, for partitioning objrefs into // sets. // @@ -360,8 +373,7 @@ IIOP_Object::IIOP_Object (const char *host, char *repository_id) : STUB_Object (repository_id), profile (host, port, objkey), - refcount_ (1), - fwd_profile_ (0) + refcount_ (1) { } @@ -371,8 +383,7 @@ IIOP_Object::IIOP_Object (char *repository_id, const char *objkey) : STUB_Object (repository_id), profile (addr, objkey), - refcount_ (1), - fwd_profile_ (0) + refcount_ (1) { } @@ -848,3 +859,4 @@ IIOP_Object::do_dynamic_call (const char *opname, // operation nam assert (status == TAO_GIOP_LOCATION_FORWARD); } } + diff --git a/TAO/tao/IIOP_Object.h b/TAO/tao/IIOP_Object.h index 5c4d070a49b..253ce73c7af 100644 --- a/TAO/tao/IIOP_Object.h +++ b/TAO/tao/IIOP_Object.h @@ -90,6 +90,9 @@ public: ACE_INET_Addr &object_addr (void); // Returns the <ACE_INET_Addr> for this profile. + Profile &operator = (const Profile &src); + // copy operator + private: int set (const char *host, const CORBA::UShort port, @@ -116,9 +119,6 @@ public: const TAO_opaque &object_key); // Called by client or server. - Profile &operator = (const Profile &src); - // Disallow copy constructor. - ACE_INET_Addr object_addr_; // Cached instance of <ACE_INET_Addr> for use in making // invocations, etc. @@ -177,26 +177,7 @@ public: // IIOP engine does not need to worry about such issues since it // only supports one protocol -- the problem won't show up. // "Multiprotocol ORBs" will need to solve that problem though. ] - - // = Thread-safe accessors for the forwarding profile - IIOP::Profile *fwd_profile (void); - // THREAD-SAFE. Returns the current forwarding profile. - - IIOP::Profile *fwd_profile (IIOP::Profile *new_profile); - // THREAD-SAFE. Sets a new value for the forwarding profile and - // returns the current value. - - // = Non-thread-safe accessors for the forwarding profile - ACE_SYNCH_MUTEX &fwd_profile_lock (void); - // Gives reference to the lock guarding the forwarding profile. - - IIOP::Profile *fwd_profile_i (void); - // THREAD-SAFE. Returns the current forwarding profile. - - IIOP::Profile *fwd_profile_i (IIOP::Profile *new_profile); - // THREAD-SAFE. Sets a new value for the forwarding profile and - // returns the current value. - + // = Construction IIOP_Object (char *repository_id); // Construct from a repository (type) ID. @@ -237,16 +218,6 @@ private: u_int refcount_; // Number of outstanding references to this object. - ACE_SYNCH_MUTEX fwd_profile_lock_; - // This lock covers the mutable info in all IIOP objref data, - // namely the forwarded-to objref. It must be held when a client - // thread is reading or modifying that data, to prevent one from - // overwriting data the other's reading or writing. - - IIOP::Profile *fwd_profile_; - // This is a pointer to a profile used if the object is not - // collocated in the current process. - ~IIOP_Object (void); // Destructor is to be called only through Release() diff --git a/TAO/tao/IIOP_Object.i b/TAO/tao/IIOP_Object.i index 333b1fb95aa..eb104d2ad1c 100644 --- a/TAO/tao/IIOP_Object.i +++ b/TAO/tao/IIOP_Object.i @@ -38,14 +38,12 @@ ACE_INLINE IIOP_Object::~IIOP_Object (void) { assert (this->refcount_ == 0); - delete this->fwd_profile_; } ACE_INLINE IIOP_Object::IIOP_Object (char *repository_id) : STUB_Object (repository_id), - refcount_ (0), - fwd_profile_ (0) + refcount_ (0) { } @@ -54,46 +52,7 @@ IIOP_Object::IIOP_Object (char *repository_id, const IIOP::Profile &a_profile) : STUB_Object (repository_id), profile (a_profile), - refcount_ (0), - fwd_profile_ (0) + refcount_ (0) { } -ACE_INLINE -IIOP::Profile * -IIOP_Object::fwd_profile_i (void) -{ - return this->fwd_profile_; -} - -ACE_INLINE -IIOP::Profile * -IIOP_Object::fwd_profile_i (IIOP::Profile *new_profile) -{ - IIOP::Profile *old = this->fwd_profile_; - this->fwd_profile_ = new_profile; - return old; -} - -ACE_INLINE -IIOP::Profile * -IIOP_Object::fwd_profile (void) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, this->fwd_profile_lock_, 0)); - return this->fwd_profile_i (); -} - -ACE_INLINE -IIOP::Profile * -IIOP_Object::fwd_profile (IIOP::Profile *new_profile) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, this->fwd_profile_lock_, 0)); - return this->fwd_profile_i (new_profile); -} - -ACE_INLINE -ACE_SYNCH_MUTEX & -IIOP_Object::fwd_profile_lock (void) -{ - return fwd_profile_lock_; -} diff --git a/TAO/tao/Server_Request.cpp b/TAO/tao/Server_Request.cpp index aa419b2f246..f64b038e4ec 100644 --- a/TAO/tao/Server_Request.cpp +++ b/TAO/tao/Server_Request.cpp @@ -297,18 +297,32 @@ IIOP_ServerRequest::set_exception (const CORBA::Any &value, if (this->retval_ || this->exception_) env.exception (new CORBA::BAD_INV_ORDER (CORBA::COMPLETED_NO)); else + { + // Try to narrow to ForwardRequest + PortableServer::ForwardRequest_ptr forward_request = + PortableServer::ForwardRequest::_narrow ((CORBA::Exception *) value.value ()); + + // If narrowing of exception succeeded + if (forward_request != 0) { - this->exception_ = new CORBA::Any; - this->exception_->replace (value.type (), value.value (), 1, env); - - // @@ This cast is not safe, but we haven't implemented the >>= - // and <<= operators for base exceptions (yet). - CORBA_Exception* x = (CORBA_Exception*)value.value (); - if (CORBA_UserException::_narrow (x) != 0) - this->exception_type_ = TAO_GIOP_USER_EXCEPTION; + this->forward_location_ = forward_request->forward_reference; + } + + // Normal exception + else + { + this->exception_ = new CORBA::Any; + this->exception_->replace (value.type (), value.value (), 1, env); + + // @@ This cast is not safe, but we haven't implemented the >>= + // and <<= operators for base exceptions (yet). + CORBA_Exception* x = (CORBA_Exception*)value.value (); + if (CORBA_UserException::_narrow (x) != 0) + this->exception_type_ = TAO_GIOP_USER_EXCEPTION; else - this->exception_type_ = TAO_GIOP_SYSTEM_EXCEPTION; - } + this->exception_type_ = TAO_GIOP_SYSTEM_EXCEPTION; + } + } } // Extension @@ -434,15 +448,25 @@ IIOP_ServerRequest::init_reply (CORBA::Environment &env) env); this->outgoing_->write_ulong (this->request_id_); - // Standard exceptions only. - if (env.exception () != 0) + // Standard exceptions are caught in Connect::handle_input + + // Forward exception only. + if (!CORBA::is_nil (this->forward_location_.in ())) { - CORBA::Environment env2; - CORBA::Exception *x = env.exception (); - CORBA::TypeCode_ptr except_tc = x->_type (); + this->outgoing_->write_ulong (TAO_GIOP_LOCATION_FORWARD); + + CORBA::Object_ptr object_ptr = this->forward_location_.in (); + (void) this->outgoing_->encode (CORBA::_tc_Object, + &object_ptr, + 0, + env); - this->outgoing_->write_ulong (TAO_GIOP_SYSTEM_EXCEPTION); - (void) this->outgoing_->encode (except_tc, x, 0, env2); + // If encoding went fine + if (env.exception () != 0) + { + dexc (env, "ServerRequest::marshal - forwarding parameter encode failed"); + return; + } } // Any exception at all. @@ -487,7 +511,8 @@ IIOP_ServerRequest::dsi_marshal (CORBA::Environment &env) const void *value; // only if there wasn't any exception, we proceed - if (this->exception_type_ == TAO_GIOP_NO_EXCEPTION) + if (this->exception_type_ == TAO_GIOP_NO_EXCEPTION && + CORBA::is_nil (this->forward_location_.in ())) { // ... then send any return value ... if (this->retval_) diff --git a/TAO/tao/Server_Request.h b/TAO/tao/Server_Request.h index f0dc4c9287c..09b75d7ed6a 100644 --- a/TAO/tao/Server_Request.h +++ b/TAO/tao/Server_Request.h @@ -264,6 +264,11 @@ public: TAO_HRESULT QueryInterface (REFIID riid, void **ppv); + // To handle System Exceptions at the lowest level, + // a method returning the request_id_ is needed. + + CORBA::ULong request_id (void); + private: #if !defined (TAO_COPY_OPNAME) char* operation_; @@ -272,6 +277,8 @@ private: #endif // Operation name. + CORBA::Object_var forward_location_; + TAO_InputCDR *incoming_; // Incoming stream. diff --git a/TAO/tao/Server_Request.i b/TAO/tao/Server_Request.i index 89cacd18abe..c888c5cf6f3 100644 --- a/TAO/tao/Server_Request.i +++ b/TAO/tao/Server_Request.i @@ -70,3 +70,9 @@ IIOP_ServerRequest::service_info (void) const { return this->service_info_; } + +ACE_INLINE CORBA::ULong +IIOP_ServerRequest::request_id (void) +{ + return this->request_id_; +} |