diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-08-19 20:10:52 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-08-19 20:10:52 +0000 |
commit | c475c0ec6c761ce135f467a7508db95553ef15a0 (patch) | |
tree | 89bf6776828fc0980e00b291d3cdec31d3bf1d56 | |
parent | 60c857404706ec402ef3b2279df516106a75fa5b (diff) | |
download | ATCD-c475c0ec6c761ce135f467a7508db95553ef15a0.tar.gz |
ChangeLogTag:Wed Aug 19 15:06:59 1998 Carlos O'Ryan <coryan@cs.wustl.edu>
-rw-r--r-- | TAO/ChangeLog-98c | 37 | ||||
-rw-r--r-- | TAO/tao/Exception.cpp | 201 | ||||
-rw-r--r-- | TAO/tao/Exception.h | 52 | ||||
-rw-r--r-- | TAO/tao/Invocation.cpp | 210 | ||||
-rw-r--r-- | TAO/tao/ORB.h | 6 | ||||
-rw-r--r-- | TAO/tao/Typecode.cpp | 44 | ||||
-rw-r--r-- | TAO/tao/Typecode.h | 8 | ||||
-rw-r--r-- | TAO/tests/Param_Test/Makefile | 3 | ||||
-rw-r--r-- | TAO/tests/Param_Test/README | 16 | ||||
-rw-r--r-- | TAO/tests/Param_Test/any.cpp | 6 | ||||
-rw-r--r-- | TAO/tests/Param_Test/driver.cpp | 16 | ||||
-rw-r--r-- | TAO/tests/Param_Test/except.cpp | 196 | ||||
-rw-r--r-- | TAO/tests/Param_Test/except.h | 77 | ||||
-rw-r--r-- | TAO/tests/Param_Test/options.cpp | 2 | ||||
-rw-r--r-- | TAO/tests/Param_Test/options.h | 3 | ||||
-rw-r--r-- | TAO/tests/Param_Test/param_test.idl | 14 | ||||
-rw-r--r-- | TAO/tests/Param_Test/param_test_i.cpp | 68 | ||||
-rw-r--r-- | TAO/tests/Param_Test/param_test_i.h | 10 | ||||
-rwxr-xr-x | TAO/tests/Param_Test/run_test.pl | 2 | ||||
-rw-r--r-- | TAO/tests/Param_Test/tests.h | 1 | ||||
-rw-r--r-- | TAO/tests/Param_Test/ub_any_seq.cpp | 6 |
21 files changed, 791 insertions, 187 deletions
diff --git a/TAO/ChangeLog-98c b/TAO/ChangeLog-98c index d7a96b107d4..64c5514e136 100644 --- a/TAO/ChangeLog-98c +++ b/TAO/ChangeLog-98c @@ -1,3 +1,40 @@ +Wed Aug 19 15:06:59 1998 Carlos O'Ryan <coryan@cs.wustl.edu> + + * tao/ORB.h: + * tao/Exception.h: + * tao/Exception.cpp: + * tao/Invocation.cpp: + Added the new CORBA::UnknownUserException, that is used with DII + when a user exception is raised. + User and system exceptions are created using the right dynamic + type. + Minimized code size by using a factory method for the system + exceptions in the TAO_Exceptions class. + + * tao/Typecode.h: + * tao/Typecode.cpp: + Completed the implementation for the Bounds and BadKind + exceptions. + + * tests/Param_Test/Makefile: + * tests/Param_Test/README: + * tests/Param_Test/driver.cpp: + * tests/Param_Test/options.cpp: + * tests/Param_Test/options.h: + * tests/Param_Test/param_test.idl: + * tests/Param_Test/param_test_i.cpp: + * tests/Param_Test/param_test_i.h: + * tests/Param_Test/run_test.pl: + * tests/Param_Test/tests.h: + Added a new test for exceptions, it verifies that user + exceptions are properly transmitted and demarshaled and that + unexpected exceptions are converted into CORBA::UNKNOWN. + + * tests/Param_Test/any.cpp: + * tests/Param_Test/ub_any_seq.cpp: + The tests (specially the server side) are silent unless the + TAO_debug_level is greater than 0. + Wed Aug 19 14:24:18 1998 David L. Levine <levine@cs.wustl.edu> * TAO version 0.2.5 released. diff --git a/TAO/tao/Exception.cpp b/TAO/tao/Exception.cpp index bb8ca578a65..66c6911aaa3 100644 --- a/TAO/tao/Exception.cpp +++ b/TAO/tao/Exception.cpp @@ -71,6 +71,12 @@ CORBA_Exception::CORBA_Exception (const CORBA_Exception &src) // is responsible for releasing any storage owned by the exception. // It can do this because it's got the typecode. +CORBA_Exception::CORBA_Exception (void) + : type_ (0), + refcount_ (1) +{ +} + CORBA_Exception::~CORBA_Exception (void) { assert (this->refcount_ == 0); @@ -108,7 +114,13 @@ CORBA_Exception::_type (void) const int CORBA_Exception::_is_a (const char* repository_id) const { - return (ACE_OS::strcmp (repository_id, "IDL:CORBA/Exception:1.0")==0); + return (ACE_OS::strcmp (repository_id, "IDL:omg.org/CORBA/Exception:1.0")==0); +} + +void +CORBA_Exception::_raise (void) +{ + // @@ TODO this method should be defined on each Exception. } CORBA::ULong @@ -136,6 +148,10 @@ CORBA_Exception::_decr_refcnt (void) // Avoid zillions of not-quite-inlined copies of utilities. +CORBA_UserException::CORBA_UserException (void) +{ +} + CORBA_UserException::CORBA_UserException (CORBA::TypeCode_ptr tc) : CORBA_Exception (tc) { @@ -160,14 +176,14 @@ int CORBA_UserException::_is_a (const char* interface_id) const { return ACE_OS::strcmp (interface_id, - "IDL:CORBA/UserException:1.0") == 0 + "IDL:omg.org/CORBA/UserException:1.0") == 0 || CORBA_Exception::_is_a (interface_id); } CORBA_UserException* CORBA_UserException::_narrow (CORBA_Exception* exception) { - if (exception->_is_a ("IDL:CORBA/UserException:1.0")) + if (exception->_is_a ("IDL:omg.org/CORBA/UserException:1.0")) return ACE_dynamic_cast (CORBA_UserException *, exception); return 0; } @@ -211,22 +227,100 @@ int CORBA_SystemException::_is_a (const char* interface_id) const { return ACE_OS::strcmp (interface_id, - "IDL:CORBA/SystemException:1.0") == 0 + "IDL:omg.org/CORBA/SystemException:1.0") == 0 || CORBA_Exception::_is_a (interface_id); } CORBA_SystemException* CORBA_SystemException::_narrow (CORBA_Exception* exception) { - if (exception->_is_a ("IDL:CORBA/SystemException:1.0")) + if (exception->_is_a ("IDL:omg.org/CORBA/SystemException:1.0")) return ACE_dynamic_cast (CORBA_SystemException*,exception); return 0; } +// **************************************************************** + +CORBA_UnknownUserException::CORBA_UnknownUserException (void) + : CORBA_UserException (CORBA::_tc_UnknownUserException), + exception_ (0) +{ +} + +CORBA_UnknownUserException::CORBA_UnknownUserException (CORBA_Any &ex) +{ + this->exception_ = new CORBA_Any (ex); +} + +CORBA_UnknownUserException::~CORBA_UnknownUserException (void) +{ + if (this->exception_ != 0) + delete this->exception_; +} + +CORBA_Any& +CORBA_UnknownUserException::exception (void) +{ + return *this->exception_; +} + +int +CORBA_UnknownUserException::_is_a (const char* interface_id) const +{ + return ((ACE_OS::strcmp (interface_id, + "IDL:omg.org/CORBA/UnknownUserException:1.0") == 0) + || CORBA_UserException::_is_a (interface_id)); +} + +CORBA_UnknownUserException* +CORBA_UnknownUserException::_narrow (CORBA_Exception *ex) +{ + if (ex->_is_a ("IDL:omg.org/CORBA/UnknownUserException:1.0")) + return ACE_dynamic_cast (CORBA_UnknownUserException*, ex); + return 0; +} + // Note that "buffer" holds the (unscoped) name originally, and is // then overwritten. void +TAO_Exceptions::make_unknown_user_typecode (CORBA::TypeCode_ptr &tcp, + CORBA::Environment &env) +{ + // Create the TypeCode for the CORBA_UnknownUserException + TAO_OutputCDR stream; + + const char* interface_id = + "IDL:omg.org/CORBA/UnknownUserException:1.0"; + const char* name = "UnknownUserException"; + const char* field_name = "exception"; + + if (stream.write_octet (TAO_ENCAP_BYTE_ORDER) != CORBA::B_TRUE + || stream.encode (CORBA::_tc_string, + &interface_id, 0, + env) != CORBA::TypeCode::TRAVERSE_CONTINUE + || stream.encode (CORBA::_tc_string, + &name, 0, + env) != CORBA::TypeCode::TRAVERSE_CONTINUE + || stream.write_ulong (1L) != CORBA::B_TRUE + || stream.encode (CORBA::_tc_string, + &field_name, 0, + env) != CORBA::TypeCode::TRAVERSE_CONTINUE + || stream.encode (CORBA::_tc_TypeCode, + &CORBA::_tc_any, 0, + env) != CORBA::TypeCode::TRAVERSE_CONTINUE) + { + env.exception (new CORBA_INITIALIZE (CORBA::COMPLETED_NO)); + return; + } + + tcp = new CORBA::TypeCode (CORBA::tk_except, + stream.length (), + stream.buffer (), + CORBA::B_TRUE); +} + +void TAO_Exceptions::make_standard_typecode (CORBA::TypeCode_ptr &tcp, const char *name, char *buffer, @@ -345,9 +439,24 @@ TAO_Exceptions::make_standard_typecode (CORBA::TypeCode_ptr &tcp, STANDARD_EXCEPTION_LIST #undef TAO_SYSTEM_EXCEPTION +CORBA::TypeCode_ptr CORBA::_tc_UnknownUserException = 0; + // static CORBA::TypeCode tc_std_ ## name (CORBA::tk_except); // CORBA::TypeCode_ptr CORBA::_tc_ ## name = &tc_std_ ## name; +#define POA_EXCEPTION_LIST \ + POA_EXCEPTION (AdapterAlreadyExists) \ + POA_EXCEPTION (AdapterInactive) \ + POA_EXCEPTION (AdapterNonExistent) \ + POA_EXCEPTION (InvalidPolicy) \ + POA_EXCEPTION (NoServant) \ + POA_EXCEPTION (ObjectAlreadyActive) \ + POA_EXCEPTION (ObjectNotActive) \ + POA_EXCEPTION (ServantAlreadyActive) \ + POA_EXCEPTION (ServantNotActive) \ + POA_EXCEPTION (WrongAdapter) \ + POA_EXCEPTION (WrongPolicy ) \ + void TAO_Exceptions::init (CORBA::Environment &env) { @@ -365,18 +474,60 @@ TAO_Exceptions::init (CORBA::Environment &env) // Register POA exceptions as system exceptions TAO_Exceptions::system_exceptions->add (PortableServer::_tc_ForwardRequest); TAO_Exceptions::system_exceptions->add (PortableServer::POAManager::_tc_AdapterInactive); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_AdapterAlreadyExists); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_AdapterInactive); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_AdapterNonExistent); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_InvalidPolicy); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_NoServant); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_ObjectAlreadyActive); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_ObjectNotActive); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_ServantAlreadyActive); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_ServantNotActive); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_WrongAdapter); - TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_WrongPolicy ); TAO_Exceptions::system_exceptions->add (PortableServer::Current::_tc_NoContext); + +#define POA_EXCEPTION(name) \ + TAO_Exceptions::system_exceptions->add (PortableServer::POA::_tc_ ## name); +POA_EXCEPTION_LIST +#undef POA_EXCEPTION + + if (env.exception () == 0) + TAO_Exceptions::make_unknown_user_typecode (CORBA::_tc_UnknownUserException, + env); +} + +CORBA_Exception* +TAO_Exceptions::create_system_exception (const char* id, + CORBA::Environment& env) +{ +#define TAO_SYSTEM_EXCEPTION(name) \ + { \ + const char* xid = CORBA::_tc_ ## name ->id (env); \ + if (ACE_OS::strcmp (id, xid) == 0) \ + return new CORBA:: name; \ + } + STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION +#define POA_EXCEPTION(name) \ + { \ + env.clear (); \ + const char* xid = PortableServer::POA::_tc_ ## name ->id (env); \ + if (env.exception () == 0 && ACE_OS::strcmp (id, xid) == 0) \ + return new PortableServer::POA:: name; \ + } +POA_EXCEPTION_LIST +#undef POA_EXCEPTION + + { + env.clear (); + const char* xid = PortableServer::_tc_ForwardRequest->id (env); + if (env.exception () == 0 && ACE_OS::strcmp (id, xid) == 0) + return new PortableServer::ForwardRequest; + } + { + env.clear (); + const char* xid = PortableServer::POAManager::_tc_AdapterInactive->id (env); + if (env.exception () == 0 && ACE_OS::strcmp (id, xid) == 0) + return new PortableServer::POAManager::AdapterInactive; + } + { + env.clear (); + const char* xid = PortableServer::Current::_tc_NoContext->id (env); + if (env.exception () == 0 && ACE_OS::strcmp (id, xid) == 0) + return new PortableServer::Current::NoContext; + } + + return 0; } void @@ -389,13 +540,14 @@ TAO_Exceptions::fini (void) STANDARD_EXCEPTION_LIST #undef TAO_SYSTEM_EXCEPTION + delete CORBA::_tc_UnknownUserException; } #define TAO_SYSTEM_EXCEPTION(name) \ int \ CORBA_##name ::_is_a (const char* interface_id) const \ { \ - return ((ACE_OS::strcmp (interface_id, "IDL:CORBA/" #name "1.0")==0) \ + return ((ACE_OS::strcmp (interface_id, "IDL:omg.org/CORBA/" #name ":1.0")==0) \ || CORBA_SystemException::_is_a (interface_id)); \ } STANDARD_EXCEPTION_LIST @@ -405,14 +557,25 @@ STANDARD_EXCEPTION_LIST CORBA_##name * \ CORBA_##name ::_narrow (CORBA_Exception* exception) \ { \ - if (exception->_is_a ("IDL:CORBA/" #name "1.0")) \ + if (exception->_is_a ("IDL:omg.org/CORBA/" #name ":1.0")) \ return ACE_dynamic_cast (CORBA_##name *, exception); \ return 0; \ } STANDARD_EXCEPTION_LIST #undef TAO_SYSTEM_EXCEPTION -#undef STANDARD_EXCEPTION_LIST +#define TAO_SYSTEM_EXCEPTION(name) \ +CORBA_##name :: CORBA_##name (void) \ + : CORBA_SystemException (CORBA::_tc_ ## name, \ + 0xffff0000L, \ + CORBA::COMPLETED_NO) \ +{ \ +} +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + +#undef POA_EXCEPTION_LIST +#undef STANDARD_EXCEPTION_LIST // Convenience -- say if the exception is a system exception or not. diff --git a/TAO/tao/Exception.h b/TAO/tao/Exception.h index e3f8d2bb37c..8c82e5e0316 100644 --- a/TAO/tao/Exception.h +++ b/TAO/tao/Exception.h @@ -20,6 +20,8 @@ #if !defined (TAO_EXCEPTION_H) # define TAO_EXCEPTION_H +class CORBA_Any; + class TAO_Export CORBA_Exception { // = TITLE @@ -57,6 +59,9 @@ public: // = To implement the narrow method. virtual int _is_a (const char* repository_id) const; + // = To throw the exception (when using the standard mapping. + virtual void _raise (void); + // = Methods required for memory management support. CORBA::ULong _incr_refcnt (void); CORBA::ULong _decr_refcnt (void); @@ -85,9 +90,6 @@ class TAO_Export CORBA_UserException : public CORBA_Exception // User exceptions are those defined by application developers // using OMG-IDL. public: - CORBA_UserException (void); - // default constructor - CORBA_UserException (const CORBA_UserException &src); // copy ctor @@ -107,6 +109,10 @@ public: virtual int _is_a (const char *interface_id) const; // used for narrowing + +protected: + CORBA_UserException (void); + // default constructor }; class TAO_Export CORBA_SystemException : public CORBA_Exception @@ -172,12 +178,13 @@ private: #define TAO_SYSTEM_EXCEPTION(name) \ class TAO_Export CORBA_ ## name : public CORBA_SystemException { \ public: \ + CORBA_ ## name (void); \ CORBA_ ## name (CORBA::CompletionStatus completed, \ CORBA::ULong code = 0xffff0000L) \ : CORBA_SystemException (CORBA::_tc_ ## name, code, completed) \ { } \ - virtual int _is_a (const char* type_id) const; \ static CORBA_##name * _narrow (CORBA_Exception* exception); \ + virtual int _is_a (const char* type_id) const; \ } TAO_SYSTEM_EXCEPTION(UNKNOWN); @@ -209,6 +216,33 @@ TAO_SYSTEM_EXCEPTION(DATA_CONVERSION); #undef TAO_SYSTEM_EXCEPTION +class TAO_Export CORBA_UnknownUserException : public CORBA_UserException +{ + // = TITLE + // CORBA_UnknownUserException + // + // = DESCRIPTION + // When user exceptions are received by a DII invocation the ORB + // is unable to create the exception with the right dynamic + // type; to workaround this problem it throws a + // CORBA::UnknownUserException that contains the exception inside + // an Any. +public: + CORBA_UnknownUserException (void); + CORBA_UnknownUserException (CORBA_Any& exception); + virtual ~CORBA_UnknownUserException (void); + // Constructor + + CORBA_Any& exception (void); + // Return the any containing the user exception. + + static CORBA_UnknownUserException* _narrow (CORBA_Exception *ex); + virtual int _is_a (const char* type_id) const; + // +private: + CORBA_Any* exception_; +}; + class TAO_Export CORBA_Environment { // = TITLE @@ -271,6 +305,11 @@ public: // correctly, initializing system exceptions is only an exercise // in CPU time; it allocates no new memory. + static void make_unknown_user_typecode (CORBA::TypeCode_ptr &tcp, + CORBA::Environment &env); + // Make the TypeCode for the CORBA::UnknownUserException standard + // exception. + static void init (CORBA::Environment &env); // Runtime initialization of all standard exception typecodes. // Called from <CORBA::ORB_init>. @@ -278,6 +317,11 @@ public: static void fini (void); // Runtime finalization of all standard exception typecodes. + static CORBA_Exception *create_system_exception (const char* id, + CORBA::Environment& env); + // Create a CORBA::SystemException given the interface repository + // ID. + enum { TC_BUFLEN = 160 diff --git a/TAO/tao/Invocation.cpp b/TAO/tao/Invocation.cpp index e0be7f2ba17..8de422ce4e7 100644 --- a/TAO/tao/Invocation.cpp +++ b/TAO/tao/Invocation.cpp @@ -596,88 +596,65 @@ TAO_GIOP_Twoway_Invocation::invoke (CORBA::ExceptionList &exceptions, return TAO_GIOP_SYSTEM_EXCEPTION; } } - // User and system exceptions differ only in what table of - // exception typecodes is searched. - CORBA::ExceptionList *xlist; - if (reply_status == TAO_GIOP_USER_EXCEPTION) - xlist = &exceptions; - else - xlist = TAO_Exceptions::system_exceptions; - - // Find it in the operation description and then use that to - // get the typecode. Use it to unmarshal the exception's - // value; if that exception is not allowed by this operation, - // fail (next). - - for (CORBA::ULong i = 0; - i < xlist->count (); - i++) - { - CORBA::TypeCode_ptr tcp = xlist->item (i, env); - - const char *xid = tcp->id (env); - - if (env.exception () != 0) - { - dexc (env, "invoke (), get exception ID"); - TAO_GIOP::send_error (this->data_->handler ()); - return TAO_GIOP_SYSTEM_EXCEPTION; - } - - if (ACE_OS::strcmp (buf, (char *)xid) == 0) - { - size_t size; - CORBA::Exception *exception; - - size = tcp->size (env); - if (env.exception () != 0) - { - dexc (env, "invoke (), get exception size"); - TAO_GIOP::send_error (this->data_->handler ()); - return TAO_GIOP_SYSTEM_EXCEPTION; - } - - // Create the exception, fill in the generic parts - // such as vtable, typecode ptr, refcount ... we need - // to clean them all up together, in case of errors - // unmarshaling. - - exception = new (new char [size]) CORBA::Exception (tcp); - - if (this->inp_stream_.decode (tcp, exception, 0, env) - != CORBA::TypeCode::TRAVERSE_CONTINUE) - { - delete exception; - ACE_DEBUG ((LM_ERROR, "(%P|%t) invoke, unmarshal %s exception %s\n", - (reply_status == TAO_GIOP_USER_EXCEPTION) ? "user" : "system", - buf)); - TAO_GIOP::send_error (this->data_->handler ()); - return TAO_GIOP_SYSTEM_EXCEPTION; - } - env.exception (exception); - return (TAO_GIOP_ReplyStatusType) reply_status; + CORBA_Exception *exception = 0; + if (reply_status == TAO_GIOP_SYSTEM_EXCEPTION) + { + exception = + TAO_Exceptions::create_system_exception (buf, env); + if (env.exception () != 0) + return TAO_GIOP_SYSTEM_EXCEPTION; + + this->inp_stream_.decode (exception->_type (), + &exception, 0, + env); + } + else + { + // Find it in the operation description and then use that + // to get the typecode. + // This is important to decode the exception. + + for (CORBA::ULong i = 0; + i < exceptions.count (); + i++) + { + CORBA::TypeCode_ptr tcp = + exceptions.item (i, env); + if (env.exception () != 0) + { + TAO_GIOP::send_error (this->data_->handler ()); + return TAO_GIOP_SYSTEM_EXCEPTION; + } + + const char *xid = tcp->id (env); + if (env.exception () != 0) + { + TAO_GIOP::send_error (this->data_->handler ()); + return TAO_GIOP_SYSTEM_EXCEPTION; + } + + if (ACE_OS::strcmp (buf, xid) != 0) + continue; + + // @@ Somehow store the CDR inside the Any, if + // necessary add an extension to the Any class. + const ACE_Message_Block* cdr = + this->inp_stream_.start (); + CORBA_Any any; + exception = + new CORBA_UnknownUserException (any); + break; } } // If we couldn't find this exception's typecode, report it as - // an OA error since the skeleton passed an exception that was - // not allowed by the operation's IDL definition. In the case - // of a dynamic skeleton it's actually an implementation bug. - // - // It's known to be _very_ misleading to try reporting this as - // any kind of marshaling error (unless minor codes are made - // to be _very_ useful) ... folk try to find/fix ORB bugs that - // don't exist, not bugs in/near the implementation code. - - if (reply_status == TAO_GIOP_USER_EXCEPTION) - env.exception (new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_YES)); - else - env.exception (new CORBA::INTERNAL (CORBA::COMPLETED_MAYBE)); - return TAO_GIOP_SYSTEM_EXCEPTION; + // CORBA::UNKNOWN exception. + + env.exception (new CORBA::UNKNOWN (CORBA::COMPLETED_MAYBE)); + return TAO_GIOP_SYSTEM_EXCEPTION; } - // NOTREACHED - + case TAO_GIOP_LOCATION_FORWARD: return (this->location_forward (this->inp_stream_, env)); } @@ -872,7 +849,20 @@ TAO_GIOP_Twoway_Invocation::invoke (TAO_Exception_Data *excepts, CORBA::Exception *exception = 0; CORBA::TypeCode_ptr tcp = 0; - if (reply_status == TAO_GIOP_USER_EXCEPTION) + if (reply_status == TAO_GIOP_SYSTEM_EXCEPTION) + { + exception = + TAO_Exceptions::create_system_exception (buf, env); + if (env.exception () != 0) + return TAO_GIOP_SYSTEM_EXCEPTION; + + this->inp_stream_.decode (exception->_type (), + exception, 0, + env); + if (env.exception () != 0) + return TAO_GIOP_SYSTEM_EXCEPTION; + } + else { // search the table of exceptions and see if there is a match for (CORBA::ULong i = 0; @@ -900,77 +890,27 @@ TAO_GIOP_Twoway_Invocation::invoke (TAO_Exception_Data *excepts, TAO_GIOP::send_error (this->data_->handler ()); return TAO_GIOP_SYSTEM_EXCEPTION; } - + this->inp_stream_.decode (exception->_type (), + exception, 0, + env); + if (env.exception () != 0) + return TAO_GIOP_SYSTEM_EXCEPTION; break; } } // end of loop CORBA::string_free (buf); } - else - { - CORBA::ExceptionList *xlist; - xlist = TAO_Exceptions::system_exceptions; - - // Find it in the operation description and then use that to - // get the typecode. Use it to unmarshal the exception's - // value; if that exception is not allowed by this operation, - // fail (next). - - for (CORBA::ULong i = 0; - i < xlist->count (); - i++) - { - tcp = xlist->item (i, env); - const char *xid = tcp->id (env); - - if (env.exception () != 0) - { - dexc (env, "invoke (), get exception ID"); - TAO_GIOP::send_error (this->data_->handler ()); - return TAO_GIOP_SYSTEM_EXCEPTION; - } - - if (ACE_OS::strcmp (buf, (char *)xid) == 0) - { - - // must be a system exception - exception = new CORBA::SystemException (tcp, - (CORBA::ULong)0, - CORBA::COMPLETED_NO); - } - } - } // If we couldn't find this exception's typecode, report it as - // an OA error since the skeleton passed an exception that was - // not allowed by the operation's IDL definition. In the case - // of a dynamic skeleton it's actually an implementation bug. - // - // It's known to be _very_ misleading to try reporting this as - // any kind of marshaling error (unless minor codes are made - // to be _very_ useful) ... folk try to find/fix ORB bugs that - // don't exist, not bugs in/near the implementation code. + // a CORBA::UNKNOWN, i.e. we got an exception that was not the + // right type... if (!exception) { - if (reply_status == TAO_GIOP_USER_EXCEPTION) - env.exception (new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_YES)); - else - env.exception (new CORBA::INTERNAL (CORBA::COMPLETED_MAYBE)); + env.exception (new CORBA::UNKNOWN (CORBA::COMPLETED_YES)); return TAO_GIOP_SYSTEM_EXCEPTION; } - // decode the exception - if (this->inp_stream_.decode (tcp, exception, 0, env) - != CORBA::TypeCode::TRAVERSE_CONTINUE) - { - delete exception; - ACE_DEBUG ((LM_ERROR, "(%P|%t) invoke, unmarshal %s exception %s\n", - (reply_status == TAO_GIOP_USER_EXCEPTION) ? "user" : "system", - buf)); - TAO_GIOP::send_error (this->data_->handler ()); - return TAO_GIOP_SYSTEM_EXCEPTION; - } env.exception (exception); return (TAO_GIOP_ReplyStatusType) reply_status; diff --git a/TAO/tao/ORB.h b/TAO/tao/ORB.h index 7940f4b4828..d0d04e63228 100644 --- a/TAO/tao/ORB.h +++ b/TAO/tao/ORB.h @@ -161,6 +161,8 @@ TAO_SYSTEM_EXCEPTION(OBJ_ADAPTER); TAO_SYSTEM_EXCEPTION(DATA_CONVERSION); #undef TAO_SYSTEM_EXCEPTION +class CORBA_UnknownUserException; + typedef class CORBA_ImplementationDef * CORBA_ImplementationDef_ptr; @@ -603,6 +605,8 @@ public: TAO_SYSTEM_EXCEPTION(DATA_CONVERSION); #undef TAO_SYSTEM_EXCEPTION + typedef CORBA_UnknownUserException UnknownUserException; + // = all the CORBA::is_nil methods. static Boolean is_nil (Object_ptr); static Boolean is_nil (Environment_ptr); @@ -741,6 +745,8 @@ public: static TypeCode_ptr _tc_Bounds; static TypeCode_ptr _tc_BadKind; + static TypeCode_ptr _tc_UnknownUserException; + static ORB_ptr ORB_init (int &argc, char *const *argv, const char *orb_name, diff --git a/TAO/tao/Typecode.cpp b/TAO/tao/Typecode.cpp index a79f2943cee..fabffc6d26b 100644 --- a/TAO/tao/Typecode.cpp +++ b/TAO/tao/Typecode.cpp @@ -25,11 +25,55 @@ CORBA_TypeCode::Bounds::Bounds (void) { } +void +CORBA_TypeCode::Bounds::_raise (void) +{ +} + +CORBA_TypeCode::Bounds* +CORBA_TypeCode::Bounds::_narrow (CORBA_Exception *ex) +{ + if (ex->_is_a ("IDL:omg.orb/CORBA/TypeCode/Bounds:1.0")) + return ACE_dynamic_cast (CORBA_TypeCode::Bounds*, ex); + return 0; +} + +int +CORBA_TypeCode::Bounds::_is_a (const char* interface_id) const +{ + return ((ACE_OS::strcmp (interface_id, + "IDL:omg.orb/CORBA/TypeCode/Bounds:1.0") == + 0) + || CORBA_UserException::_is_a (interface_id)); +} + CORBA_TypeCode::BadKind::BadKind (void) : CORBA_UserException (CORBA::_tc_BadKind) { } +void +CORBA_TypeCode::BadKind::_raise (void) +{ +} + +CORBA_TypeCode::BadKind* +CORBA_TypeCode::BadKind::_narrow (CORBA_Exception *ex) +{ + if (ex->_is_a ("IDL:omg.orb/CORBA/TypeCode/BadKind:1.0")) + return ACE_dynamic_cast (CORBA_TypeCode::BadKind*, ex); + return 0; +} + +int +CORBA_TypeCode::BadKind::_is_a (const char* interface_id) const +{ + return ((ACE_OS::strcmp (interface_id, + "IDL:omg.orb/CORBA/TypeCode/BadKind:1.0") == + 0) + || CORBA_UserException::_is_a (interface_id)); +} + // decreases the refcount and deletes when refcount reaches 0 // Constructor for CONSTANT typecodes with empty parameter lists. diff --git a/TAO/tao/Typecode.h b/TAO/tao/Typecode.h index 8e0a5b28f2f..4751d9df2ca 100644 --- a/TAO/tao/Typecode.h +++ b/TAO/tao/Typecode.h @@ -61,12 +61,20 @@ public: { public: Bounds (void); + + virtual void _raise (void); + Bounds* _narrow (CORBA_Exception *ex); + virtual int _is_a (const char* interface_id) const; }; class BadKind : public CORBA_UserException { public: BadKind (void); + + virtual void _raise (void); + BadKind* _narrow (CORBA_Exception *ex); + virtual int _is_a (const char* interface_id) const; }; static CORBA::TypeCode_ptr _duplicate (CORBA::TypeCode_ptr tc); diff --git a/TAO/tests/Param_Test/Makefile b/TAO/tests/Param_Test/Makefile index be6af0f4018..f1fe3155749 100644 --- a/TAO/tests/Param_Test/Makefile +++ b/TAO/tests/Param_Test/Makefile @@ -57,7 +57,8 @@ CLI_FILES = param_testC \ ub_string \ ub_struct_seq \ var_array \ - var_struct + var_struct \ + except PARAM_TEST_SVR_OBJS = $(addsuffix .o,$(SVR_FILES)) PARAM_TEST_CLT_OBJS = $(addsuffix .o,$(CLI_FILES)) diff --git a/TAO/tests/Param_Test/README b/TAO/tests/Param_Test/README index 998ed87852b..20f6dc2e6b2 100644 --- a/TAO/tests/Param_Test/README +++ b/TAO/tests/Param_Test/README @@ -40,7 +40,8 @@ To run the client, type [-d] debugging [-n loopcount] number of times to run the test - [-f servant-IOR-file] reads the servant-IOR from the specified file. + [-f servant-IOR-file] reads the servant-IOR from the + specified file. [-k Param_Test-obj-ref-key] object key of Param_Test object [-h hostname] host to bind to [-p port] port number of server @@ -72,9 +73,12 @@ To run the client, type bd_long_sequence for bounded sequences of shorts fixed_array for arrays of fixed sized types (longs) var_array for arrays of var sized types (strings) + typecode for typecode + exception for exceptions - There are 2 options of giving the Param_obj-ref-key i.e IOR to the client: + There are 2 options of giving the Param_obj-ref-key i.e IOR to +the client: 1. Using the -f option to read the IOR from a file. @@ -83,9 +87,10 @@ To run the client, type run_test.pl: ----------- - There is a perl script in this directory named run_test.pl to test all - the types. It starts the server first and then runs the client with - the different data type parameters. The arguments it takes are: + There is a perl script in this directory named run_test.pl to + test all the types. It starts the server first and then runs + the client with the different data type parameters. The + arguments it takes are: -n num -- runs the client num times (default is 5) -d -- runs each in debug mode @@ -93,4 +98,3 @@ run_test.pl: -h -- prints this information -t type -- runs only one type of param test -i (dii|sii) -- Changes the type of invocation (default is sii) - diff --git a/TAO/tests/Param_Test/any.cpp b/TAO/tests/Param_Test/any.cpp index 588102a72e7..479bb5307b0 100644 --- a/TAO/tests/Param_Test/any.cpp +++ b/TAO/tests/Param_Test/any.cpp @@ -72,7 +72,8 @@ Test_Any::init_parameters (Param_Test_ptr objref, { CORBA::Short s; s = gen->gen_short (); - ACE_DEBUG ((LM_DEBUG, "setting short = %d\n", s)); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "setting short = %d\n", s)); this->in_ <<= s; this->inout_ <<= s; } @@ -80,7 +81,8 @@ Test_Any::init_parameters (Param_Test_ptr objref, case 1: { char *str = gen->gen_string (); - ACE_DEBUG ((LM_DEBUG, "setting string = %s\n", str)); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "setting string = %s\n", str)); this->in_ <<= str; this->inout_ <<= str; } diff --git a/TAO/tests/Param_Test/driver.cpp b/TAO/tests/Param_Test/driver.cpp index 7ab52d20603..ee35cffcfc2 100644 --- a/TAO/tests/Param_Test/driver.cpp +++ b/TAO/tests/Param_Test/driver.cpp @@ -422,6 +422,20 @@ Driver::run (void) delete client; } break; + + case Options::TEST_EXCEPTION: + { + Param_Test_Client<Test_Exception> *client = new + Param_Test_Client<Test_Exception> (this->orb_.in (), + this->objref_.in(), + new Test_Exception); + if (opt->invoke_type () == Options::SII) + retstatus = client->run_sii_test (); + else + retstatus = client->run_dii_test (); + delete client; + } + break; default: break; } @@ -468,6 +482,7 @@ template class Param_Test_Client<Test_Long_Sequence>; template class Param_Test_Client<Test_Bounded_Long_Sequence>; template class Param_Test_Client<Test_Fixed_Array>; template class Param_Test_Client<Test_Var_Array>; +template class Param_Test_Client<Test_Exception>; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #pragma instantiate ACE_Singleton<Driver, ACE_SYNCH_RECURSIVE_MUTEX> #pragma instantiate Param_Test_Client<Test_Short> @@ -493,4 +508,5 @@ template class Param_Test_Client<Test_Var_Array>; #pragma instantiate Param_Test_Client<Test_Bounded_Long_Sequence> #pragma instantiate Param_Test_Client<Test_Fixed_Array> #pragma instantiate Param_Test_Client<Test_Var_Array> +#pragma instantiate Param_Test_Client<Test_Exception> #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/tests/Param_Test/except.cpp b/TAO/tests/Param_Test/except.cpp new file mode 100644 index 00000000000..1db805bef2b --- /dev/null +++ b/TAO/tests/Param_Test/except.cpp @@ -0,0 +1,196 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests/Param_Test +// +// = FILENAME +// except.cpp +// +// = DESCRIPTION +// tests exception +// +// = AUTHORS +// Carlos O'Ryan +// +// ============================================================================ + +#include "helper.h" +#include "except.h" + +ACE_RCSID(Param_Test, except, "$Id$") + +// ************************************************************************ +// Test_Exception +// ************************************************************************ + +Test_Exception::Test_Exception (void) + : opname_ (CORBA::string_dup ("test_exception")) +{ +} + +Test_Exception::~Test_Exception (void) +{ + CORBA::string_free (this->opname_); + this->opname_ = 0; +} + +const char * +Test_Exception::opname (void) const +{ + return this->opname_; +} + +int +Test_Exception::init_parameters (Param_Test_ptr, + CORBA::Environment &) +{ + Generator *gen = GENERATOR::instance (); // value generator + + this->in_ = gen->gen_short (); + this->inout_ = 0; + return 0; +} + +int +Test_Exception::reset_parameters (void) +{ + this->inout_ = 0; + this->out_ = 0; + this->ret_ = 0; + return 0; +} + +int +Test_Exception::run_sii_test (Param_Test_ptr objref, + CORBA::Environment &_env) +{ + TAO_TRY + { + this->ret_ = objref->test_exception (this->in_, + this->inout_, + this->out_, + TAO_TRY_ENV); + TAO_CHECK_ENV; + } + TAO_CATCH (Param_Test::Ooops, ex) + { + if (TAO_debug_level > 0) + { + const char* reason = ex.reason.in (); + if (reason == 0) + reason = "nil"; + ACE_DEBUG ((LM_DEBUG, + "Test_Exception::run_sii_test - " + "expected user exception" + " (%s,%d)\n", reason, ex.input)); + } + this->inout_ = this->in_ * 2; + this->out_ = this->in_ * 3; + this->ret_ = this->in_ * 4; + TAO_TRY_ENV.clear (); + return 0; + } + TAO_CATCH (CORBA::UNKNOWN, ex) + { + if (TAO_debug_level > 0) + { + TAO_TRY_ENV.print_exception ("Test_Exception::run_sii_test - " + "expected system exception\n"); + } + this->inout_ = this->in_ * 2; + this->out_ = this->in_ * 3; + this->ret_ = this->in_ * 4; + TAO_TRY_ENV.clear (); + return 0; + } + TAO_CATCH (Param_Test::BadBoy, ex) + { + TAO_TRY_ENV.print_exception ("Test_Exception::run_sii_test - " + " unexpected exception\n"); + TAO_RETHROW_RETURN (-1); + } + TAO_CATCHANY + { + TAO_RETHROW_RETURN (-1); + } + TAO_ENDTRY; + + return 0; +} + +int +Test_Exception::add_args (CORBA::NVList_ptr param_list, + CORBA::NVList_ptr retval, + CORBA::Environment &env) +{ + // we provide top level memory to the ORB to retrieve the data + CORBA::Any in_arg (CORBA::_tc_ulong, + &this->in_, + CORBA::B_FALSE); + + CORBA::Any inout_arg (CORBA::_tc_ulong, + &this->inout_, + CORBA::B_FALSE); + + CORBA::Any out_arg (CORBA::_tc_ulong, + &this->out_, + CORBA::B_FALSE); + + // add parameters + param_list->add_value ("s1", + in_arg, + CORBA::ARG_IN, + env); + + param_list->add_value ("s2", + inout_arg, + CORBA::ARG_INOUT, + env); + + param_list->add_value ("s3", + out_arg, + CORBA::ARG_OUT, + env); + + // add return value. Let the ORB allocate storage. We simply tell the ORB + // what type we are expecting. + retval->item (0, env)->value ()->replace (CORBA::_tc_ulong, + &this->ret_, + CORBA::B_FALSE, // does not own + env); + return 0; +} + +CORBA::Boolean +Test_Exception::check_validity (void) +{ + if (this->inout_ == this->in_ * 2 && + this->out_ == this->in_ * 3 && + this->ret_ == this->in_ * 4) + return 1; + return 0; +} + +CORBA::Boolean +Test_Exception::check_validity (CORBA::Request_ptr) +{ + return this->check_validity (); +} + +void +Test_Exception::print_values (void) +{ + ACE_DEBUG ((LM_DEBUG, + "\n=*=*=*=*=*=*\n" + "in = %d, " + "inout = %d, " + "out = %d, " + "ret = %d\n" + "\n=*=*=*=*=*=*\n", + this->in_, + this->inout_, + this->out_, + this->ret_)); +} diff --git a/TAO/tests/Param_Test/except.h b/TAO/tests/Param_Test/except.h new file mode 100644 index 00000000000..a092172accd --- /dev/null +++ b/TAO/tests/Param_Test/except.h @@ -0,0 +1,77 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests/Param_Test +// +// = FILENAME +// except.h +// +// = DESCRIPTION +// Tests system and user exceptions +// +// = AUTHORS +// Carlos O'Ryan +// +// ============================================================================ + +#if !defined (PARAM_TEST_EXCEPTION_H) +#define PARAM_TEST_EXCEPTION_H + +#include "param_testC.h" + +class Test_Exception +{ +public: + Test_Exception (void); + // ctor + + ~Test_Exception (void); + // dtor + + int run_sii_test (Param_Test_ptr objref, + CORBA::Environment &env); + // run the SII test + + int add_args (CORBA::NVList_ptr nvlist, + CORBA::NVList_ptr retval, + CORBA::Environment &env); + + const char *opname (void) const; + // return operation name + + int init_parameters (Param_Test_ptr objref, + CORBA::Environment &env); + // set values for parameters + + int reset_parameters (void); + // reset values for CORBA + + CORBA::Boolean check_validity (void); + // check if results are valid + + CORBA::Boolean check_validity (CORBA::Request_ptr req); + // check if results are valid. This is used for DII results + + void print_values (void); + // print all the values + +private: + char *opname_; + // operation name + + CORBA::ULong in_; + // in parameter + + CORBA::ULong inout_; + // inout parameter + + CORBA::ULong out_; + // out parameter + + CORBA::ULong ret_; + // return value +}; + +#endif /* PARAM_TEST_EXCEPTION_H */ diff --git a/TAO/tests/Param_Test/options.cpp b/TAO/tests/Param_Test/options.cpp index 447370e2217..323c4d2a786 100644 --- a/TAO/tests/Param_Test/options.cpp +++ b/TAO/tests/Param_Test/options.cpp @@ -134,6 +134,8 @@ Options::parse_args (int argc, char **argv) this->test_type_ = Options::TEST_VAR_ARRAY; else if (!ACE_OS::strcmp (get_opts.optarg, "multdim_array")) this->test_type_ = Options::TEST_MULTDIM_ARRAY; + else if (!ACE_OS::strcmp (get_opts.optarg, "exception")) + this->test_type_ = Options::TEST_EXCEPTION; break; case '?': diff --git a/TAO/tests/Param_Test/options.h b/TAO/tests/Param_Test/options.h index 9f325474044..e3898028d33 100644 --- a/TAO/tests/Param_Test/options.h +++ b/TAO/tests/Param_Test/options.h @@ -52,7 +52,8 @@ public: TEST_BD_LONGSEQ, TEST_FIXED_ARRAY, TEST_VAR_ARRAY, - TEST_MULTDIM_ARRAY + TEST_MULTDIM_ARRAY, + TEST_EXCEPTION }; enum INVOKE_TYPE diff --git a/TAO/tests/Param_Test/param_test.idl b/TAO/tests/Param_Test/param_test.idl index 256c845cd87..1ab300aabb5 100644 --- a/TAO/tests/Param_Test/param_test.idl +++ b/TAO/tests/Param_Test/param_test.idl @@ -198,6 +198,20 @@ interface Param_Test inout Var_Array v2, out Var_Array v3); + + // Just to test report a problem + exception Ooops { + string reason; + unsigned long input; + }; + // To test what happens when an unexpected exception is thrown. + exception BadBoy { + }; + unsigned long test_exception (in unsigned long s1, + inout unsigned long s2, + out unsigned long s3) + raises (Ooops); + #if 0 // multidimensional arrays (fixed). The following will give rise to a 3 // dimensional array. The following will define a 3-dimensional array of size diff --git a/TAO/tests/Param_Test/param_test_i.cpp b/TAO/tests/Param_Test/param_test_i.cpp index 5fb49b50acf..3d7ba328ff4 100644 --- a/TAO/tests/Param_Test/param_test_i.cpp +++ b/TAO/tests/Param_Test/param_test_i.cpp @@ -56,7 +56,8 @@ Coffee_i::description (const Coffee::Desc &description, Param_Test_i::Param_Test_i (const char *coffee_name, const char *) - : obj_ (coffee_name) + : obj_ (coffee_name), + test_exception_count_ (0) { } @@ -227,17 +228,21 @@ Param_Test_i::test_strseq (const Param_Test::StrSeq &s1, *ret = new Param_Test::StrSeq, *out = new Param_Test::StrSeq; - ACE_DEBUG ((LM_DEBUG, "\n*=*=*=*SERVER SIDE=*=*=*=*=*=*=\n")); - for (CORBA::ULong i=0; (i < s2.length ()); i++) + if (TAO_debug_level > 0) { - ACE_DEBUG ((LM_DEBUG, - "Element #%d\n" - "in : %s\n", - i, - (s2[i]? (const char *)s2[i]:"<nul>"))); + ACE_DEBUG ((LM_DEBUG, "\n*=*=*=*SERVER SIDE=*=*=*=*=*=*=\n")); + for (CORBA::ULong i=0; (i < s2.length ()); i++) + { + ACE_DEBUG ((LM_DEBUG, + "Element #%d\n" + "in : %s\n", + i, + (s2[i]? (const char *)s2[i]:"<nul>"))); + } + if (s2.length () == 0) + ACE_DEBUG ((LM_DEBUG, "\ninout sequence is NUL\n")); } - if (s2.length () == 0) - ACE_DEBUG ((LM_DEBUG, "\ninout sequence is NUL\n")); + // now copy all elements of s1 into the others using the assignment operator s2 = s1; *out = s1; @@ -565,21 +570,27 @@ Param_Test_i::test_any (const CORBA::Any &a1, // debug the incoming Any if (a1 >>= short_in) { - ACE_DEBUG ((LM_DEBUG, "Received short = %d\n", short_in)); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "Received short = %d\n", short_in)); a2 >>= short_in; - ACE_DEBUG ((LM_DEBUG, "inout short = %d\n", short_in)); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "inout short = %d\n", short_in)); *a3.ptr () >>= short_in; - ACE_DEBUG ((LM_DEBUG, "out short = %d\n", short_in)); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "out short = %d\n", short_in)); *ret >>= short_in; - ACE_DEBUG ((LM_DEBUG, "ret short = %d\n", short_in)); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "ret short = %d\n", short_in)); } else if (a1 >>= str_in) { - ACE_DEBUG ((LM_DEBUG, "Received unbounded string = %s\n", str_in)); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "Received unbounded string = %s\n", str_in)); } else if (a1 >>= coffee) { - ACE_DEBUG ((LM_DEBUG, "Received Coffee object\n")); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "Received Coffee object\n")); } else { @@ -621,6 +632,31 @@ Param_Test_i::test_var_array (const Param_Test::Var_Array a1, return ret; } +CORBA::ULong +Param_Test_i::test_exception (CORBA::ULong s1, + CORBA::ULong& s2, + CORBA::ULong_out s3, + CORBA::Environment &env) + TAO_THROW_SPEC ((CORBA::SystemException, Param_Test::Ooops)) +{ + int d = this->test_exception_count_ % 3; + this->test_exception_count_++; + if (d == 0) + { + s2 = s1 * 2; + s3 = s1 * 3; + return s1 * 4; + } + else if (d == 1) + { + env.exception (new Param_Test::Ooops (CORBA::string_dup (" % 3 == 1"), + s1)); + return 0; + } + env.exception (new Param_Test::BadBoy); + return 0; +} + void Param_Test_i::shutdown (CORBA::Environment &) { diff --git a/TAO/tests/Param_Test/param_test_i.h b/TAO/tests/Param_Test/param_test_i.h index 775eca11fef..023ee8430bd 100644 --- a/TAO/tests/Param_Test/param_test_i.h +++ b/TAO/tests/Param_Test/param_test_i.h @@ -217,11 +217,21 @@ public: CORBA::Environment &env); // test for arrays of variable types + virtual CORBA::ULong test_exception (CORBA::ULong s1, + CORBA::ULong& s2, + CORBA::ULong_out s3, + CORBA::Environment &env) + TAO_THROW_SPEC ((CORBA::SystemException, Param_Test::Ooops)); + void shutdown (CORBA::Environment &env); private: Coffee_i obj_; // the coffee object reference we maintain + + int test_exception_count_; + // Count the number of calls to test_exception() so we can throw + // every 3 calls or so. }; #endif /* PARAM_TEST_I_H */ diff --git a/TAO/tests/Param_Test/run_test.pl b/TAO/tests/Param_Test/run_test.pl index b1cbd2faa95..a30be483d0b 100755 --- a/TAO/tests/Param_Test/run_test.pl +++ b/TAO/tests/Param_Test/run_test.pl @@ -98,7 +98,7 @@ for ($i = 0; $i <= $#ARGV; $i++) "any_sequence", "ub_short_sequence", "ub_long_sequence", "bd_short_sequence", "bd_long_sequence", - "fixed_array", "var_array", "typecode"); + "fixed_array", "var_array", "typecode", "exception"); if ($type ne "") { diff --git a/TAO/tests/Param_Test/tests.h b/TAO/tests/Param_Test/tests.h index 83cf511101c..146c5228d30 100644 --- a/TAO/tests/Param_Test/tests.h +++ b/TAO/tests/Param_Test/tests.h @@ -42,5 +42,6 @@ #include "ub_struct_seq.h" #include "var_array.h" #include "var_struct.h" +#include "except.h" #endif /* if !defined */ diff --git a/TAO/tests/Param_Test/ub_any_seq.cpp b/TAO/tests/Param_Test/ub_any_seq.cpp index 5cc4cf538b2..d1dd8071d99 100644 --- a/TAO/tests/Param_Test/ub_any_seq.cpp +++ b/TAO/tests/Param_Test/ub_any_seq.cpp @@ -67,7 +67,8 @@ Test_AnySeq::init_parameters (Param_Test_ptr objref, { CORBA::Short s; s = gen->gen_short (); - ACE_DEBUG ((LM_DEBUG, "setting short = %d\n", s)); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "setting short = %d\n", s)); this->in_[i] <<= s; this->inout_[i] <<= 0; // different from in_ } @@ -75,7 +76,8 @@ Test_AnySeq::init_parameters (Param_Test_ptr objref, case 1: { char *str = gen->gen_string (); - ACE_DEBUG ((LM_DEBUG, "setting string = %s\n", str)); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "setting string = %s\n", str)); this->in_[i] <<= str; this->inout_[i] <<= 0; // different from in_ } |