summaryrefslogtreecommitdiff
path: root/TAO/tao
diff options
context:
space:
mode:
authormk1 <mk1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-06-12 02:18:02 +0000
committermk1 <mk1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-06-12 02:18:02 +0000
commit48dfd3ac0bbaaa5091260859e2e79ae01b176664 (patch)
tree6947004db5f4bc6b78119c9cc0ea93fd822bd179 /TAO/tao
parenta01d0b8ea55bedb117b5f9786f7733f54482f352 (diff)
downloadATCD-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.cpp159
-rw-r--r--TAO/tao/Connect.h14
-rw-r--r--TAO/tao/GIOP.cpp219
-rw-r--r--TAO/tao/GIOP.h5
-rw-r--r--TAO/tao/IIOP_ORB.cpp7
-rw-r--r--TAO/tao/IIOP_Object.cpp20
-rw-r--r--TAO/tao/IIOP_Object.h37
-rw-r--r--TAO/tao/IIOP_Object.i45
-rw-r--r--TAO/tao/Server_Request.cpp61
-rw-r--r--TAO/tao/Server_Request.h7
-rw-r--r--TAO/tao/Server_Request.i6
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_;
+}