summaryrefslogtreecommitdiff
path: root/TAO
diff options
context:
space:
mode:
authorvzykov <vzykov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2008-03-28 09:19:19 +0000
committervzykov <vzykov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2008-03-28 09:19:19 +0000
commit7f2a90db8524841c5c2f7a0282f1b1e992c082c1 (patch)
tree58d5d136e2a8179ff8c080c7cce0585f9c6619c0 /TAO
parentcd38a3c363d7b3acb34f464434cdd79ace72df0c (diff)
downloadATCD-7f2a90db8524841c5c2f7a0282f1b1e992c082c1.tar.gz
ChangeLogTag: Fri Mar 28 09:07:14 UTC 2008 Vladimir Zykov <vladimir.zykov@prismtech.com>
Diffstat (limited to 'TAO')
-rw-r--r--TAO/ChangeLog39
-rw-r--r--TAO/tao/Adapter_Registry.cpp3
-rw-r--r--TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp4
-rw-r--r--TAO/tao/Collocated_Invocation.cpp6
-rw-r--r--TAO/tao/DynamicInterface/Dynamic_Implementation.cpp2
-rw-r--r--TAO/tao/GIOP_Message_Base.cpp24
-rw-r--r--TAO/tao/IORTable/Table_Adapter.cpp12
-rw-r--r--TAO/tao/Invocation_Adapter.cpp21
-rw-r--r--TAO/tao/Invocation_Base.cpp8
-rw-r--r--TAO/tao/Invocation_Base.h3
-rw-r--r--TAO/tao/Invocation_Base.inl4
-rw-r--r--TAO/tao/LocateRequest_Invocation_Adapter.cpp21
-rw-r--r--TAO/tao/ORB_Core.inl3
-rw-r--r--TAO/tao/PortableServer/Object_Adapter.cpp5
-rw-r--r--TAO/tao/PortableServer/Upcall_Wrapper.cpp4
-rw-r--r--TAO/tao/TAO_Server_Request.cpp5
-rw-r--r--TAO/tao/TAO_Server_Request.h8
-rw-r--r--TAO/tao/TAO_Server_Request.inl7
-rw-r--r--TAO/tests/Bug_3276_Regression/Bug_3276_Regression.mpc31
-rw-r--r--TAO/tests/Bug_3276_Regression/Manager.cpp222
-rw-r--r--TAO/tests/Bug_3276_Regression/Manager.h46
-rw-r--r--TAO/tests/Bug_3276_Regression/README26
-rw-r--r--TAO/tests/Bug_3276_Regression/Servant_Locator.cpp29
-rw-r--r--TAO/tests/Bug_3276_Regression/Servant_Locator.h28
-rw-r--r--TAO/tests/Bug_3276_Regression/client.cpp120
-rwxr-xr-xTAO/tests/Bug_3276_Regression/run_test.pl48
-rw-r--r--TAO/tests/Bug_3276_Regression/test.idl11
-rw-r--r--TAO/tests/Bug_3276_Regression/test_i.cpp24
-rw-r--r--TAO/tests/Bug_3276_Regression/test_i.h22
29 files changed, 749 insertions, 37 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index 86c597db0e0..ab159e3ab40 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,42 @@
+Fri Mar 28 09:07:14 UTC 2008 Vladimir Zykov <vladimir.zykov@prismtech.com>
+
+ * tao/GIOP_Message_Base.cpp:
+ * tao/PortableServer/Upcall_Wrapper.cpp:
+ * tao/PortableServer/Object_Adapter.cpp:
+ * tao/Invocation_Base.h:
+ * tao/LocateRequest_Invocation_Adapter.cpp:
+ * tao/Invocation_Base.cpp:
+ * tao/Collocated_Invocation.cpp:
+ * tao/ORB_Core.inl:
+ * tao/IORTable/Table_Adapter.cpp:
+ * tao/DynamicInterface/Dynamic_Implementation.cpp:
+ * tao/TAO_Server_Request.cpp:
+ * tao/Invocation_Base.inl:
+ * tao/Adapter_Registry.cpp:
+ * tao/TAO_Server_Request.h:
+ * tao/Invocation_Adapter.cpp:
+ * tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp:
+ * tao/TAO_Server_Request.inl:
+
+ Fixed a bug in the server side code with incorrect handling
+ of forward request exception that was contstructed with nil
+ object reference. Added throwing of a TRANSIENT exception on
+ the client side in case server forwards to nil object.
+
+ * tests/Bug_3276_Regression/client.cpp:
+ * tests/Bug_3276_Regression/Manager.h:
+ * tests/Bug_3276_Regression/Servant_Locator.cpp:
+ * tests/Bug_3276_Regression/test.idl:
+ * tests/Bug_3276_Regression/test_i.cpp:
+ * tests/Bug_3276_Regression/Manager.cpp:
+ * tests/Bug_3276_Regression/Servant_Locator.h:
+ * tests/Bug_3276_Regression/Bug_3276_Regression.mpc:
+ * tests/Bug_3276_Regression/README:
+ * tests/Bug_3276_Regression/run_test.pl:
+ * tests/Bug_3276_Regression/test_i.h:
+
+ Added a regression test.
+
Thu Mar 27 18:44:12 UTC 2008 Johnny Willemsen <jwillemsen@remedy.nl>
* docs/Options.html:
diff --git a/TAO/tao/Adapter_Registry.cpp b/TAO/tao/Adapter_Registry.cpp
index b927960ae3c..5f60fa3186a 100644
--- a/TAO/tao/Adapter_Registry.cpp
+++ b/TAO/tao/Adapter_Registry.cpp
@@ -6,6 +6,7 @@
#include "tao/Adapter.h"
#include "tao/SystemException.h"
#include "tao/debug.h"
+#include "tao/TAO_Server_Request.h"
#include "ace/Log_Msg.h"
#include "ace/OS_NS_string.h"
@@ -118,7 +119,7 @@ TAO_Adapter_Registry::dispatch (TAO::ObjectKey &key,
}
}
- if (CORBA::is_nil (forward_to))
+ if (!request.is_forwarded ())
{
throw ::CORBA::OBJECT_NOT_EXIST ();
}
diff --git a/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp
index 2176020836a..7d35160ec1f 100644
--- a/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp
+++ b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp
@@ -177,6 +177,10 @@ TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_ServerRequest*& request)
// ACTION: Assignment performs reference-counted copy of object ref.
clone_obj->forward_location_ = request->forward_location_;
+ // TYPE: bool
+ // ACTION: Primitive data type assignment
+ clone_obj->is_forwarded_ = request->is_forwarded_;
+
// TYPE: TAO_InputCDR*
// ACTION: This *must* be "cloned".
if (request->incoming_ != 0)
diff --git a/TAO/tao/Collocated_Invocation.cpp b/TAO/tao/Collocated_Invocation.cpp
index e0fb30328f5..e5612502a93 100644
--- a/TAO/tao/Collocated_Invocation.cpp
+++ b/TAO/tao/Collocated_Invocation.cpp
@@ -91,10 +91,10 @@ namespace TAO
s = TAO_INVOKE_SUCCESS;
#if TAO_HAS_INTERCEPTORS == 1
- if (this->forwarded_to_.in () ||
+ if (this->is_forwarded_ ||
this->response_expected_ == false)
{
- if (this->forwarded_to_.in ())
+ if (this->is_forwarded_)
this->reply_received (TAO_INVOKE_RESTART);
s = this->receive_other_interception ();
@@ -172,7 +172,7 @@ namespace TAO
}
#endif /* TAO_HAS_INTERCEPTORS == 1 */
- if (this->forwarded_to_.in () != 0)
+ if (this->is_forwarded_)
s = TAO_INVOKE_RESTART;
return s;
diff --git a/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp b/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp
index 79c6fb295a3..b3fa6df1a91 100644
--- a/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp
+++ b/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp
@@ -121,7 +121,7 @@ TAO_DynamicImplementation::_dispatch (TAO_ServerRequest &request,
// No need to do any of this if the client isn't waiting.
if (request.response_expected ())
{
- if (!CORBA::is_nil (request.forward_location ()))
+ if (request.is_forwarded ())
{
request.init_reply ();
request.tao_send_reply ();
diff --git a/TAO/tao/GIOP_Message_Base.cpp b/TAO/tao/GIOP_Message_Base.cpp
index 8f77605719e..56be7d9e437 100644
--- a/TAO/tao/GIOP_Message_Base.cpp
+++ b/TAO/tao/GIOP_Message_Base.cpp
@@ -865,7 +865,7 @@ TAO_GIOP_Message_Base::process_request (
//@@ TAO_DISPATCH_RESOLUTION_OPT_COMMENT_HOOK_END
- if (!CORBA::is_nil (forward_to.in ()))
+ if (request.is_forwarded ())
{
CORBA::Boolean const permanent_forward_condition =
this->orb_core_->is_permanent_forward_condition
@@ -1081,7 +1081,7 @@ TAO_GIOP_Message_Base::process_locate_request (TAO_Transport *transport,
server_request,
forward_to);
- if (!CORBA::is_nil (forward_to.in ()))
+ if (server_request.is_forwarded ())
{
status_info.status = GIOP::OBJECT_FORWARD;
status_info.forward_location_var = forward_to;
@@ -1103,21 +1103,11 @@ TAO_GIOP_Message_Base::process_locate_request (TAO_Transport *transport,
{
status_info.forward_location_var = server_request.forward_location ();
- if (!CORBA::is_nil (status_info.forward_location_var.in ()))
- {
- status_info.status = GIOP::OBJECT_FORWARD;
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) - TAO_GIOP_Message_Base::process_locate_request, ")
- ACE_TEXT ("forwarding\n")));
- }
- else
- {
- // Normal exception, so the object is not here
- status_info.status = GIOP::UNKNOWN_OBJECT;
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) - TAO_GIOP_Message_Base::process_locate_request, ")
- ACE_TEXT ("not here\n")));
- }
+ // Normal exception, so the object is not here
+ status_info.status = GIOP::UNKNOWN_OBJECT;
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - TAO_GIOP_Message_Base::process_locate_request, ")
+ ACE_TEXT ("not here\n")));
}
}
diff --git a/TAO/tao/IORTable/Table_Adapter.cpp b/TAO/tao/IORTable/Table_Adapter.cpp
index eac61635d6d..8798616a80a 100644
--- a/TAO/tao/IORTable/Table_Adapter.cpp
+++ b/TAO/tao/IORTable/Table_Adapter.cpp
@@ -15,6 +15,7 @@
#include "tao/Stub.h"
#include "tao/ORB.h"
#include "tao/Profile.h"
+#include "tao/TAO_Server_Request.h"
ACE_RCSID (IORTable,
Table_Adapter,
@@ -99,7 +100,7 @@ TAO_Table_Adapter::priority (void) const
int
TAO_Table_Adapter::dispatch (TAO::ObjectKey &key,
- TAO_ServerRequest &,
+ TAO_ServerRequest &request,
CORBA::Object_out forward_to)
{
TAO_IOR_Table_Impl_var rootref;
@@ -113,8 +114,13 @@ TAO_Table_Adapter::dispatch (TAO::ObjectKey &key,
rootref = this->root_;
}
- return this->find_object (key, forward_to) ? TAO_Adapter::DS_FORWARD
- : TAO_Adapter::DS_MISMATCHED_KEY;
+ if (this->find_object (key, forward_to))
+ {
+ request.forward_location (forward_to);
+ return TAO_Adapter::DS_FORWARD;
+ }
+ else
+ return TAO_Adapter::DS_MISMATCHED_KEY;
}
const char *
diff --git a/TAO/tao/Invocation_Adapter.cpp b/TAO/tao/Invocation_Adapter.cpp
index 0674e6e090d..8ebdc4f6ba4 100644
--- a/TAO/tao/Invocation_Adapter.cpp
+++ b/TAO/tao/Invocation_Adapter.cpp
@@ -356,7 +356,26 @@ namespace TAO
{
// The object pointer has to be changed to a TAO_Stub pointer
// in order to obtain the profiles.
- TAO_Stub *stubobj = effective_target->_stubobj ();
+ TAO_Stub *stubobj = 0;
+
+ bool nil_forward_ref = false;
+ if (CORBA::is_nil (effective_target))
+ nil_forward_ref = true;
+ else
+ {
+ stubobj =
+ effective_target->_stubobj ();
+
+ if (stubobj && stubobj->base_profiles ().size () == 0)
+ nil_forward_ref = true;
+ }
+
+ if (nil_forward_ref)
+ throw ::CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
+ errno),
+ CORBA::COMPLETED_NO);
if (stubobj == 0)
throw ::CORBA::INTERNAL (
diff --git a/TAO/tao/Invocation_Base.cpp b/TAO/tao/Invocation_Base.cpp
index db035dfcf3e..5e8efd0a774 100644
--- a/TAO/tao/Invocation_Base.cpp
+++ b/TAO/tao/Invocation_Base.cpp
@@ -41,6 +41,7 @@ namespace TAO
bool TAO_INTERCEPTOR (request_is_remote))
: details_ (details)
, forwarded_to_ (0)
+ , is_forwarded_ (false)
, response_expected_ (response_expected)
, otarget_ (ot)
, target_ (t)
@@ -104,7 +105,7 @@ namespace TAO
throw;
}
- if (this->forwarded_to_.in ())
+ if (this->is_forwarded_)
return TAO_INVOKE_RESTART;
}
@@ -163,7 +164,7 @@ namespace TAO
throw;
}
- if (this->forwarded_to_.in ())
+ if (this->is_forwarded_)
return TAO_INVOKE_RESTART;
}
@@ -182,7 +183,7 @@ namespace TAO
{
this->adapter_->receive_exception (*this);
- if (this->forwarded_to_.in ())
+ if (this->is_forwarded_)
{
status = PortableInterceptor::LOCATION_FORWARD;
}
@@ -222,6 +223,7 @@ namespace TAO
this->invoke_status_ = TAO::TAO_INVOKE_USER_EXCEPTION;
this->forwarded_to_ = CORBA::Object::_nil ();
+ this->is_forwarded_ = false;
this->caught_exception_ = exception;
}
diff --git a/TAO/tao/Invocation_Base.h b/TAO/tao/Invocation_Base.h
index 625601957bc..1e8139fb1c5 100644
--- a/TAO/tao/Invocation_Base.h
+++ b/TAO/tao/Invocation_Base.h
@@ -138,6 +138,9 @@ namespace TAO
/// Forwarded object reference.
CORBA::Object_var forwarded_to_;
+ /// If we get nil forward reference we need more reliable indication of forwarding.
+ bool is_forwarded_;
+
/// Is response expected?
bool response_expected_;
diff --git a/TAO/tao/Invocation_Base.inl b/TAO/tao/Invocation_Base.inl
index c6a27ca28ab..bad2c07c445 100644
--- a/TAO/tao/Invocation_Base.inl
+++ b/TAO/tao/Invocation_Base.inl
@@ -22,6 +22,7 @@ namespace TAO
Invocation_Base::forwarded_reference (CORBA::Object_ptr o)
{
this->forwarded_to_ = CORBA::Object::_duplicate (o);
+ this->is_forwarded_ = true;
}
ACE_INLINE CORBA::Object_ptr
@@ -33,13 +34,14 @@ namespace TAO
ACE_INLINE CORBA::Object_ptr
Invocation_Base::steal_forwarded_reference (void)
{
+ this->is_forwarded_ = false;
return this->forwarded_to_._retn ();
}
ACE_INLINE bool
Invocation_Base::is_forwarded (void) const
{
- return (this->forwarded_to_.in () != 0);
+ return this->is_forwarded_;
}
ACE_INLINE CORBA::Boolean
diff --git a/TAO/tao/LocateRequest_Invocation_Adapter.cpp b/TAO/tao/LocateRequest_Invocation_Adapter.cpp
index 2d98421343b..18d7eb0bbbd 100644
--- a/TAO/tao/LocateRequest_Invocation_Adapter.cpp
+++ b/TAO/tao/LocateRequest_Invocation_Adapter.cpp
@@ -130,7 +130,26 @@ namespace TAO
{
// The object pointer has to be changed to a TAO_Stub pointer
// in order to obtain the profiles.
- TAO_Stub *stubobj = effective_target->_stubobj ();
+ TAO_Stub *stubobj = 0;
+
+ bool nil_forward_ref = false;
+ if (CORBA::is_nil (effective_target))
+ nil_forward_ref = true;
+ else
+ {
+ stubobj =
+ effective_target->_stubobj ();
+
+ if (stubobj && stubobj->base_profiles ().size () == 0)
+ nil_forward_ref = true;
+ }
+
+ if (nil_forward_ref)
+ throw ::CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
+ errno),
+ CORBA::COMPLETED_NO);
if (stubobj == 0)
throw ::CORBA::INTERNAL (
diff --git a/TAO/tao/ORB_Core.inl b/TAO/tao/ORB_Core.inl
index 7e086c46af2..05ee53dd0bd 100644
--- a/TAO/tao/ORB_Core.inl
+++ b/TAO/tao/ORB_Core.inl
@@ -600,8 +600,9 @@ TAO_ORB_Core::is_permanent_forward_condition
const TAO_Service_Callbacks *service_callback =
this->fault_tolerance_service ().service_callback ();
+ // Since forward location is allowed to be nil then check for it.
CORBA::Boolean const permanent_forward_condition =
- service_callback &&
+ service_callback && obj &&
service_callback->is_permanent_forward_condition (obj,
service_context);
diff --git a/TAO/tao/PortableServer/Object_Adapter.cpp b/TAO/tao/PortableServer/Object_Adapter.cpp
index 0391991be16..0a5d7857479 100644
--- a/TAO/tao/PortableServer/Object_Adapter.cpp
+++ b/TAO/tao/PortableServer/Object_Adapter.cpp
@@ -757,7 +757,7 @@ TAO_Object_Adapter::dispatch (TAO::ObjectKey &key,
// thrown, then set the forward_to object reference and return
// with the appropriate return status.
forward_to.ptr () = request.forward_location ();
- if (!CORBA::is_nil (request.forward_location ()))
+ if (request.is_forwarded ())
{
return TAO_Adapter::DS_FORWARD;
}
@@ -777,7 +777,7 @@ TAO_Object_Adapter::dispatch (TAO::ObjectKey &key,
// thrown, then set the forward_to object reference and return
// with the appropriate return status.
forward_to.ptr () = request.forward_location ();
- if (!CORBA::is_nil (request.forward_location ()))
+ if (request.is_forwarded ())
{
return TAO_Adapter::DS_FORWARD;
}
@@ -790,6 +790,7 @@ TAO_Object_Adapter::dispatch (TAO::ObjectKey &key,
if (result == TAO_Adapter::DS_FORWARD)
{
+ request.reply_status (GIOP::LOCATION_FORWARD);
request.forward_location (forward_to.ptr ());
if (sri_adapter != 0)
{
diff --git a/TAO/tao/PortableServer/Upcall_Wrapper.cpp b/TAO/tao/PortableServer/Upcall_Wrapper.cpp
index d354c47381f..7da86e41a1e 100644
--- a/TAO/tao/PortableServer/Upcall_Wrapper.cpp
+++ b/TAO/tao/PortableServer/Upcall_Wrapper.cpp
@@ -99,7 +99,7 @@ TAO::Upcall_Wrapper::upcall (TAO_ServerRequest & server_request,
// Don't bother performing the upcall if an interceptor caused a
// location forward.
CORBA::Object_var forward_to = server_request.forward_location ();
- if (CORBA::is_nil (forward_to.in ()))
+ if (!server_request.is_forwarded ())
{
if (interceptor_adapter != 0)
{
@@ -133,7 +133,7 @@ TAO::Upcall_Wrapper::upcall (TAO_ServerRequest & server_request,
// we'd still need to avoid resetting the reply status to
// SUCCESSFUL, however.
CORBA::Object_var forward_to_after = server_request.forward_location ();
- if (CORBA::is_nil (forward_to_after.in ()))
+ if (!server_request.is_forwarded ())
{
// No location forward by interceptors and successful upcall.
server_request.pi_reply_status (PortableInterceptor::SUCCESSFUL);
diff --git a/TAO/tao/TAO_Server_Request.cpp b/TAO/tao/TAO_Server_Request.cpp
index eaee1862bc0..893d416f762 100644
--- a/TAO/tao/TAO_Server_Request.cpp
+++ b/TAO/tao/TAO_Server_Request.cpp
@@ -57,6 +57,7 @@ TAO_ServerRequest::TAO_ServerRequest (TAO_GIOP_Message_Base *mesg_base,
operation_ (0),
operation_len_ (0),
release_operation_ (false),
+ is_forwarded_ (false),
incoming_ (&input),
outgoing_ (&output),
response_expected_ (false),
@@ -99,6 +100,7 @@ TAO_ServerRequest::TAO_ServerRequest (TAO_GIOP_Message_Base *mesg_base,
operation_ (CORBA::string_dup (operation)),
operation_len_ (operation == 0 ? 0 : ACE_OS::strlen (operation)),
release_operation_ (true),
+ is_forwarded_ (false),
incoming_ (0),
outgoing_ (&output),
response_expected_ (response_expected),
@@ -133,6 +135,7 @@ TAO_ServerRequest::TAO_ServerRequest (TAO_ORB_Core * orb_core,
operation_ (details.opname ()),
operation_len_ (details.opname_len ()),
release_operation_ (false),
+ is_forwarded_ (false),
incoming_ (0),
outgoing_ (0),
response_expected_ (details.response_flags () == TAO_TWOWAY_RESPONSE_FLAG
@@ -247,7 +250,7 @@ TAO_ServerRequest::init_reply (void)
reply_params.argument_flag_ = this->argument_flag_;
// Forward exception only.
- if (!CORBA::is_nil (this->forward_location_.in ()))
+ if (this->is_forwarded_)
{
CORBA::Boolean const permanent_forward_condition =
this->orb_core_->is_permanent_forward_condition (this->forward_location_.in (),
diff --git a/TAO/tao/TAO_Server_Request.h b/TAO/tao/TAO_Server_Request.h
index f0cd4e25724..281937636e9 100644
--- a/TAO/tao/TAO_Server_Request.h
+++ b/TAO/tao/TAO_Server_Request.h
@@ -208,6 +208,12 @@ public:
/// Get the forward_location.
CORBA::Object_ptr forward_location (void);
+ /**
+ * Since forward location is allowed to be nil then this is a proper
+ * method to check if the request is being forwarded.
+ */
+ bool is_forwarded (void) const;
+
/// Get the reply status
GIOP::ReplyStatusType reply_status (void);
@@ -288,6 +294,8 @@ private:
CORBA::Object_var forward_location_;
+ bool is_forwarded_;
+
/// Incoming stream.
TAO_InputCDR *incoming_;
/// Outgoing stream.
diff --git a/TAO/tao/TAO_Server_Request.inl b/TAO/tao/TAO_Server_Request.inl
index 3dd267a0826..ef3532f4c6c 100644
--- a/TAO/tao/TAO_Server_Request.inl
+++ b/TAO/tao/TAO_Server_Request.inl
@@ -169,6 +169,7 @@ TAO_ServerRequest::forward_location (CORBA::Object_ptr forward_reference)
{
this->forward_location_ =
CORBA::Object::_duplicate (forward_reference);
+ this->is_forwarded_ = true;
}
ACE_INLINE CORBA::Object_ptr
@@ -177,6 +178,12 @@ TAO_ServerRequest::forward_location (void)
return CORBA::Object::_duplicate (this->forward_location_.in ());
}
+ACE_INLINE bool
+TAO_ServerRequest::is_forwarded (void) const
+{
+ return this->is_forwarded_;
+}
+
ACE_INLINE GIOP::ReplyStatusType
TAO_ServerRequest::reply_status (void)
{
diff --git a/TAO/tests/Bug_3276_Regression/Bug_3276_Regression.mpc b/TAO/tests/Bug_3276_Regression/Bug_3276_Regression.mpc
new file mode 100644
index 00000000000..fa17ef0e663
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/Bug_3276_Regression.mpc
@@ -0,0 +1,31 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Client): taoclient, anytypecode, avoids_minimum_corba, pi {
+ exename = client
+
+ IDL_Files {
+ test.idl
+ }
+
+ Source_Files {
+ testC.cpp
+ client.cpp
+ }
+}
+
+project(*Manager): taoserver, avoids_minimum_corba {
+ exename = manager
+ after += *Client
+
+ IDL_Files {
+ }
+
+ Source_Files {
+ testC.cpp
+ testS.cpp
+ test_i.cpp
+ Servant_Locator.cpp
+ Manager.cpp
+ }
+}
diff --git a/TAO/tests/Bug_3276_Regression/Manager.cpp b/TAO/tests/Bug_3276_Regression/Manager.cpp
new file mode 100644
index 00000000000..99873c00bae
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/Manager.cpp
@@ -0,0 +1,222 @@
+//$Id$
+
+#include "Manager.h"
+#include "test_i.h"
+
+#include "ace/SString.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_stdio.h"
+
+const char *control_ior = 0;
+const char *proxy_ior = 0;
+
+int
+parse_args (int argc, char *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "c:p:");
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'c':
+ control_ior = get_opts.opt_arg ();
+ break;
+ case 'p':
+ proxy_ior = get_opts.opt_arg ();
+ break;
+ }
+ // Indicates sucessful parsing of the command line
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ try
+ {
+ Manager manager;
+
+ // Initilaize the ORB, POA etc.
+ manager.init (argc, argv);
+
+ if (parse_args (argc, argv) == -1)
+ return -1;
+
+ manager.activate_servant ();
+
+ CORBA::ORB_var orb = manager.orb ();
+ CORBA::Object_var server_ref = manager.server ();
+
+ CORBA::String_var ior =
+ orb->object_to_string (server_ref.in ());
+
+ FILE *output_file = 0;
+
+ if (proxy_ior != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Writing the servant locator object ref out to file %s\n", proxy_ior));
+ output_file = ACE_OS::fopen (proxy_ior, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file for writing IOR: %s",
+ proxy_ior),
+ 1);
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+ }
+
+ // this is only to shutdown the manager afterwards
+ Simple_Server_i server_impl (orb.in ());
+
+ Simple_Server_var server = server_impl._this ();
+
+ ior =
+ orb->object_to_string (server.in ());
+
+ ACE_DEBUG ((LM_DEBUG, "Activated as <%s>\n", ior.in ()));
+
+ // If the proxy_ior exists, output the ior to it
+ if (control_ior != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Writing the root poa servant server IOR out to file %s\n", control_ior));
+ output_file = ACE_OS::fopen (control_ior, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file for writing IOR: %s",
+ control_ior),
+ 1);
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+ }
+
+ manager.run ();
+ }
+ catch (const CORBA::Exception & ex)
+ {
+ ex._tao_print_exception ("Exception caught in manager:");
+ return -1;
+ }
+
+ return 0;
+}
+
+Manager::Manager (void)
+ : orb_ (0),
+ new_poa_var_ (0)
+{
+ //no-op
+}
+
+Manager::~Manager (void)
+{
+ this->orb_->destroy ();
+}
+
+CORBA::ORB_ptr
+Manager::orb (void)
+{
+ return CORBA::ORB::_duplicate (this->orb_.in ());
+}
+
+CORBA::Object_ptr
+Manager::server (void)
+{
+ return CORBA::Object::_duplicate (this->server_.in ());
+}
+
+int
+Manager::init (int argc, char *argv[])
+{
+ this->orb_ = CORBA::ORB_init (argc,
+ argv,
+ 0);
+
+ // Obtain the RootPOA.
+ CORBA::Object_var obj_var =
+ this->orb_->resolve_initial_references ("RootPOA");
+
+ // Get the POA_var object from Object_var.
+ PortableServer::POA_var root_poa_var =
+ PortableServer::POA::_narrow (obj_var.in ());
+
+ // Get the POAManager of the RootPOA.
+ PortableServer::POAManager_var poa_manager_var =
+ root_poa_var->the_POAManager ();
+
+ poa_manager_var->activate ();
+
+ // Policies for the childPOA to be created.
+ CORBA::PolicyList policies (4);
+ policies.length (4);
+
+ // The next two policies are common to both
+ // Id Assignment Policy
+ policies[0] =
+ root_poa_var->create_id_assignment_policy (PortableServer::USER_ID);
+
+ // Lifespan policy
+ policies[1] =
+ root_poa_var->create_lifespan_policy (PortableServer::PERSISTENT);
+
+ // Tell the POA to use a servant manager
+ policies[2] =
+ root_poa_var->create_request_processing_policy (PortableServer::USE_SERVANT_MANAGER);
+
+ // Servant Retention Policy -> Use a locator
+ policies[3] =
+ root_poa_var->create_servant_retention_policy (PortableServer::NON_RETAIN);
+
+ ACE_CString name = "newPOA";
+
+ this->new_poa_var_ =
+ root_poa_var->create_POA (name.c_str (),
+ poa_manager_var.in (),
+ policies);
+
+ // Creation of childPOAs is over. Destroy the Policy objects.
+ for (CORBA::ULong i = 0;
+ i < policies.length ();
+ ++i)
+ {
+ CORBA::Policy_ptr policy = policies[i];
+ policy->destroy ();
+ }
+
+ return 0;
+}
+
+int
+Manager::activate_servant ()
+{
+ Servant_Locator *tmp = 0;
+
+ ACE_NEW_THROW_EX (tmp,
+ Servant_Locator,
+ CORBA::NO_MEMORY ());
+
+ this->servant_locator_.reset (tmp);
+
+ // Set ServantLocator object as the servant Manager of
+ // secondPOA.
+ this->new_poa_var_->set_servant_manager (this->servant_locator_.get ());
+
+ // Try to create a reference with user created ID in new_poa
+ // which uses ServantLocator.
+ PortableServer::ObjectId_var oid_var =
+ PortableServer::string_to_ObjectId ("Simple_Server");
+
+ this->server_ =
+ new_poa_var_->create_reference_with_id (oid_var.in (),
+ "IDL:Simple_Server:1.0");
+
+ return 0;
+}
+
+int
+Manager::run ()
+{
+ this->orb_->run ();
+
+ return 0;
+}
diff --git a/TAO/tests/Bug_3276_Regression/Manager.h b/TAO/tests/Bug_3276_Regression/Manager.h
new file mode 100644
index 00000000000..7ad190181e4
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/Manager.h
@@ -0,0 +1,46 @@
+//$Id$
+
+#ifndef _MANAGER_H_
+#define _MANAGER_H_
+
+#include "ace/Auto_Ptr.h"
+#include "Servant_Locator.h"
+
+class Manager
+{
+public:
+ Manager (void);
+ // Ctor
+
+ ~Manager (void);
+
+ int init (int argc, char *argv[]);
+ // Initialize the ORB, POA etc.
+
+ int activate_servant (void);
+ // Activate the servant etc.
+
+ int run (void);
+ // Run the ORB's event loop.
+
+ CORBA::ORB_ptr orb (void);
+ // ORB's accessor.
+
+ CORBA::Object_ptr server (void);
+ // Server's accessor.
+
+private:
+ CORBA::ORB_var orb_;
+ // Our ORB
+
+ PortableServer::POA_var new_poa_var_;
+ // The new poa that is created.
+
+ ACE_Auto_Ptr<Servant_Locator> servant_locator_;
+ // Our servant locator
+
+ CORBA::Object_var server_;
+ //
+};
+
+#endif /*_MANAGER_H_ */
diff --git a/TAO/tests/Bug_3276_Regression/README b/TAO/tests/Bug_3276_Regression/README
new file mode 100644
index 00000000000..2718af710f0
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/README
@@ -0,0 +1,26 @@
+// $Id$
+
+This is a regression test for TAO#3276.
+It tests whether nil forward requests are handled correctly.
+
+__Regression Output__
+
+$ ./run_test.pl
+Writing the servant locator object ref out to file /home/vzykov/devel/DOCGroup/check/Bug_3276_Regression/proxy.ior
+Activated as <IOR:010000001600000049444c3a53696d706c655f5365727665723a312e300000000100000000000000840000000101020023000000676c6173676f772e6865616471756172746572732e65636c6970736573702e636f6d00002e8900001b00000014010f00525354c8b4ec4733e803000000000001000000010000006e02000000000000000800000001000000004f41540100000018000000010000000100010001000000010001050901010000000000>
+Writing the root poa servant server IOR out to file /home/vzykov/devel/DOCGroup/check/Bug_3276_Regression/control.ior
+About to throw forward request exception for target...
+ERROR: client timedout
+ERROR: client returned -1
+ERROR: manager timedout
+ERROR: server returned -1
+
+__Successful Output__
+
+$ ./run_test.pl
+Writing the servant locator object ref out to file /home/vzykov/devel/DOCGroup/check/Bug_3276_Regression/proxy.ior
+Activated as <IOR:010000001600000049444c3a53696d706c655f5365727665723a312e300000000100000000000000840000000101020023000000676c6173676f772e6865616471756172746572732e65636c6970736573702e636f6d00002a8900001b00000014010f00525354e3b3ec472cf20c000000000001000000010000006e02000000000000000800000001000000004f41540100000018000000010000000100010001000000010001050901010000000000>
+Writing the root poa servant server IOR out to file /home/vzykov/devel/DOCGroup/check/Bug_3276_Regression/control.ior
+About to throw forward request exception for target...
+TRANSIENT caught in client as it was expected.
+Servant in process id (13116) received shutdown request. Complying...
diff --git a/TAO/tests/Bug_3276_Regression/Servant_Locator.cpp b/TAO/tests/Bug_3276_Regression/Servant_Locator.cpp
new file mode 100644
index 00000000000..580776adf3e
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/Servant_Locator.cpp
@@ -0,0 +1,29 @@
+// $Id$
+
+#include "Servant_Locator.h"
+#include "ace/Log_Msg.h"
+#include "testC.h"
+#include "ace/OS_NS_string.h"
+
+ACE_RCSID(Forwarding, Servant_Locator, "$Id$")
+
+PortableServer::Servant
+Servant_Locator::preinvoke (const PortableServer::ObjectId & /* oid */,
+ PortableServer::POA_ptr /* poa_ptr */,
+ const char * /* op */,
+ PortableServer::ServantLocator::Cookie & /* cookie */)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "About to throw forward request exception for target...\n"));
+ // Throw a nil forward.
+ throw PortableServer::ForwardRequest (CORBA::Object::_nil ());
+}
+
+void
+Servant_Locator::postinvoke (const PortableServer::ObjectId &,
+ PortableServer::POA_ptr ,
+ const char *,
+ PortableServer::ServantLocator::Cookie ,
+ PortableServer::Servant)
+{
+}
diff --git a/TAO/tests/Bug_3276_Regression/Servant_Locator.h b/TAO/tests/Bug_3276_Regression/Servant_Locator.h
new file mode 100644
index 00000000000..a22e5612d7f
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/Servant_Locator.h
@@ -0,0 +1,28 @@
+// $Id$
+
+#ifndef _SERVANT_LOCATOR_H_
+#define _SERVANT_LOCATOR_H_
+
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/ServantLocatorC.h"
+#include "tao/ORB.h"
+
+class Servant_Locator : public PortableServer::ServantLocator
+{
+public:
+ virtual PortableServer::Servant preinvoke (const PortableServer::ObjectId &oid,
+ PortableServer::POA_ptr adapter,
+ const char *operation,
+ PortableServer::ServantLocator::Cookie &the_cookie);
+ // This method is invoked by a POA whenever it receives a request.
+
+ virtual void postinvoke (const PortableServer::ObjectId &oid,
+ PortableServer::POA_ptr adapter,
+ const char *operation,
+ PortableServer::ServantLocator::Cookie the_cookie,
+ PortableServer::Servant the_servant);
+ // This method is invoked whenever a servant completes a
+ // request.
+};
+
+#endif /* _SERVANT_LOCATOR_H */
diff --git a/TAO/tests/Bug_3276_Regression/client.cpp b/TAO/tests/Bug_3276_Regression/client.cpp
new file mode 100644
index 00000000000..c0fb9eb32ab
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/client.cpp
@@ -0,0 +1,120 @@
+// $Id$
+
+#include "ace/SString.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_unistd.h"
+#include "testC.h"
+#include "tao/ORB_Constants.h"
+
+const char *proxy_ior = 0;
+const char *control_ior = 0;
+
+int
+parse_args (int argc, char *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "p:c:");
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'p':
+ proxy_ior = get_opts.opt_arg ();
+ break;
+ case 'c':
+ control_ior = get_opts.opt_arg ();
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-c <control>"
+ "-p <proxy>"
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates sucessful parsing of the command line
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "");
+
+ if (parse_args (argc, argv) == -1)
+ return -1;
+
+ CORBA::Object_var obj =
+ orb->string_to_object (proxy_ior);
+
+ if (obj.in () == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "The received object is nil\n"),
+ -1);
+ }
+
+ Simple_Server_var server =
+ Simple_Server::_narrow (obj.in ());
+
+ if (CORBA::is_nil (server.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Object reference is nil\n"),
+ -1);
+ }
+
+ try
+ {
+ while (true)
+ {
+ // Make a remote call
+ server->remote_call ();
+ ACE_OS::sleep (2);
+ }
+ }
+ catch (CORBA::TRANSIENT& ex)
+ {
+ CORBA::ULong m = ex.minor () & 0x00000F80u;
+ if (m == TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE &&
+ ex.completed () == CORBA::COMPLETED_NO)
+ {
+ ACE_DEBUG ((LM_DEBUG, "TRANSIENT caught in client as it was expected.\n"));
+ }
+ else
+ {
+ ex._tao_print_exception ("Unexpected TRANSIENT caught in client:");
+ return 2;
+ }
+ }
+
+ obj =
+ orb->string_to_object (control_ior);
+
+ if (obj.in () == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "The received objref is NULL\n"),
+ -1);
+ }
+
+ server =
+ Simple_Server::_narrow (obj.in ());
+
+ server->shutdown ();
+
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception & ex)
+ {
+ ex._tao_print_exception ("Exception caught in client:");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/Bug_3276_Regression/run_test.pl b/TAO/tests/Bug_3276_Regression/run_test.pl
new file mode 100755
index 00000000000..5da09f6b743
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/run_test.pl
@@ -0,0 +1,48 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::Run_Test;
+
+$status = 0;
+
+$control_ior = PerlACE::LocalFile ("control.ior");
+unlink $control_ior;
+
+$proxy_ior = PerlACE::LocalFile ("proxy.ior");
+unlink $proxy_ior;
+
+if (PerlACE::is_vxworks_test()) {
+ $SV = new PerlACE::ProcessVX ("manager", "-c control.ior -p proxy.ior");
+} else {
+ $SV = new PerlACE::Process ("manager", "-c $control_ior -p $proxy_ior");
+}
+$CL = new PerlACE::Process ("client", "-c file://$control_ior -p file://$proxy_ior");
+
+$SV->Spawn ();
+if (PerlACE::waitforfile_timed ($control_ior,
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$control_ior>\n";
+ exit 1;
+}
+
+$client = $CL->SpawnWaitKill (10);
+if ($client != 0) {
+ print STDERR "ERROR: client returned $client\n";
+ $status = 1;
+}
+
+$server = $SV->WaitKill (5);
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+unlink $control_ior;
+unlink $proxy_ior;
+
+exit $status;
diff --git a/TAO/tests/Bug_3276_Regression/test.idl b/TAO/tests/Bug_3276_Regression/test.idl
new file mode 100644
index 00000000000..6e89ce2f572
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/test.idl
@@ -0,0 +1,11 @@
+/*
+ * $Id$
+ */
+
+interface Simple_Server
+{
+ void remote_call ();
+
+ oneway void shutdown ();
+};
+
diff --git a/TAO/tests/Bug_3276_Regression/test_i.cpp b/TAO/tests/Bug_3276_Regression/test_i.cpp
new file mode 100644
index 00000000000..1e80fe881e7
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/test_i.cpp
@@ -0,0 +1,24 @@
+// $Id$
+
+#include "test_i.h"
+
+Simple_Server_i::Simple_Server_i (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+{
+ // no-op
+}
+
+void
+Simple_Server_i::remote_call ()
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "Print out from process id (%P) hosting the servant \n"));
+}
+
+void
+Simple_Server_i::shutdown ()
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "Servant in process id (%P) received shutdown request. Complying... \n"));
+ this->orb_->shutdown (0);
+}
diff --git a/TAO/tests/Bug_3276_Regression/test_i.h b/TAO/tests/Bug_3276_Regression/test_i.h
new file mode 100644
index 00000000000..b301f1f6945
--- /dev/null
+++ b/TAO/tests/Bug_3276_Regression/test_i.h
@@ -0,0 +1,22 @@
+// $Id$
+
+#ifndef _TEST_I_H_
+#define _TEST_I_H_
+
+#include "testS.h"
+
+class Simple_Server_i : public POA_Simple_Server
+{
+public:
+ Simple_Server_i (CORBA::ORB_ptr orb);
+ // ctor
+
+ virtual void remote_call ();
+
+ virtual void shutdown ();
+
+private:
+ CORBA::ORB_var orb_;
+};
+
+#endif /* _TEST_I_H_ */