diff options
author | vzykov <vzykov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2008-03-28 09:19:19 +0000 |
---|---|---|
committer | vzykov <vzykov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2008-03-28 09:19:19 +0000 |
commit | 7f2a90db8524841c5c2f7a0282f1b1e992c082c1 (patch) | |
tree | 58d5d136e2a8179ff8c080c7cce0585f9c6619c0 /TAO | |
parent | cd38a3c363d7b3acb34f464434cdd79ace72df0c (diff) | |
download | ATCD-7f2a90db8524841c5c2f7a0282f1b1e992c082c1.tar.gz |
ChangeLogTag: Fri Mar 28 09:07:14 UTC 2008 Vladimir Zykov <vladimir.zykov@prismtech.com>
Diffstat (limited to 'TAO')
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_ */ |