diff options
Diffstat (limited to 'TAO/tao/Exception.cpp')
-rw-r--r-- | TAO/tao/Exception.cpp | 1263 |
1 files changed, 1250 insertions, 13 deletions
diff --git a/TAO/tao/Exception.cpp b/TAO/tao/Exception.cpp index e8711f28f66..92fbb75ee88 100644 --- a/TAO/tao/Exception.cpp +++ b/TAO/tao/Exception.cpp @@ -1,7 +1,9 @@ -// $Id$ +// $id: Exception.cpp,v 1.182 2003/11/10 20:29:26 dhinton Exp $ + +// THREADING NOTE: calling thread handles mutual exclusion policy +// on all of these data structures. #include "Exception.h" -#include "SystemException.h" #include "Environment.h" #include "Any_SystemException.h" #include "Any_Dual_Impl_T.h" @@ -29,27 +31,70 @@ #include "ace/OS_NS_stdio.h" - ACE_RCSID (tao, Exception, "$Id$") +// Static initializers. + +ACE_Allocator *TAO_Exceptions::global_allocator_; + +// Flag that denotes that the TAO TypeCode constants have been +// initialized. +bool TAO_Exceptions::initialized_ = false; + +namespace TAO +{ + // TAO specific typecode. + extern CORBA::TypeCode_ptr TC_completion_status; +} + + +/** + * @name @c errno Encoding + * + * The @c errno encoding is located in the bottom 7 bits. + */ +//@{ +const CORBA::ULong TAO_UNSPECIFIED_MINOR_CODE = 0x0U; +const CORBA::ULong TAO_ETIMEDOUT_MINOR_CODE = 0x1U; +const CORBA::ULong TAO_ENFILE_MINOR_CODE = 0x2U; +const CORBA::ULong TAO_EMFILE_MINOR_CODE = 0x3U; +const CORBA::ULong TAO_EPIPE_MINOR_CODE = 0x4U; +const CORBA::ULong TAO_ECONNREFUSED_MINOR_CODE = 0x5U; +const CORBA::ULong TAO_ENOENT_MINOR_CODE = 0x6U; +const CORBA::ULong TAO_EBADF_MINOR_CODE = 0x7U; +const CORBA::ULong TAO_ENOSYS_MINOR_CODE = 0x8U; +const CORBA::ULong TAO_EPERM_MINOR_CODE = 0x9U; +const CORBA::ULong TAO_EAFNOSUPPORT_MINOR_CODE = 0xAU; +const CORBA::ULong TAO_EAGAIN_MINOR_CODE = 0xBU; +const CORBA::ULong TAO_ENOMEM_MINOR_CODE = 0xCU; +const CORBA::ULong TAO_EACCES_MINOR_CODE = 0xDU; +const CORBA::ULong TAO_EFAULT_MINOR_CODE = 0xEU; +const CORBA::ULong TAO_EBUSY_MINOR_CODE = 0xFU; +const CORBA::ULong TAO_EEXIST_MINOR_CODE = 0x10U; +const CORBA::ULong TAO_EINVAL_MINOR_CODE = 0x11U; +const CORBA::ULong TAO_ECOMM_MINOR_CODE = 0x12U; +const CORBA::ULong TAO_ECONNRESET_MINOR_CODE = 0x13U; +const CORBA::ULong TAO_ENOTSUP_MINOR_CODE = 0x14U; +// *Don't* use TAO_<errno>_MINOR_CODE greater than 0x7FU! +//@} // **************************************************************** -CORBA::Exception::Exception (const char * repository_id, - const char * local_name) +CORBA::Exception::Exception (const char *repository_id, + const char *local_name) : id_ (CORBA::string_dup (repository_id)), name_ (CORBA::string_dup (local_name)) { - ACE_ASSERT (this->id_.in () != 0 && this->name_.in () != 0); + ACE_ASSERT (this->id_ != 0 && this->name_ != 0); } CORBA::Exception::Exception (const CORBA::Exception &src) : id_ (CORBA::string_dup (src.id_)), name_ (CORBA::string_dup (src.name_)) { - ACE_ASSERT (this->id_.in () != 0 && this->name_.in () != 0); + ACE_ASSERT (this->id_ != 0 && this->name_ != 0); } // NOTE: It's this code, not anything defined in a subclass, which is @@ -57,23 +102,35 @@ CORBA::Exception::Exception (const CORBA::Exception &src) // can do this because it's got the local name and the id. CORBA::Exception::Exception (void) - : id_ (), - name_ () + : id_ (0), + name_ (0) { } CORBA::Exception::~Exception (void) { + CORBA::string_free (this->id_); + CORBA::string_free (this->name_); } CORBA::Exception & CORBA::Exception::operator= (const CORBA::Exception &src) { + if (this->id_) + { + CORBA::string_free (this->id_); + } + this->id_ = CORBA::string_dup (src.id_); - ACE_ASSERT (this->id_.in () != 0); + ACE_ASSERT (this->id_ != 0); + + if (this->name_) + { + CORBA::string_free (this->name_); + } this->name_ = CORBA::string_dup (src.name_); - ACE_ASSERT (this->name_.in () != 0); + ACE_ASSERT (this->name_ != 0); return *this; } @@ -81,13 +138,13 @@ CORBA::Exception::operator= (const CORBA::Exception &src) const char * CORBA::Exception::_rep_id (void) const { - return this->id_.in (); + return this->id_; } const char * CORBA::Exception::_name (void) const { - return this->name_.in (); + return this->name_; } CORBA::TypeCode_ptr @@ -158,6 +215,1186 @@ namespace CORBA #endif /* (ACE_LACKS_IOSTREAM_TOTALLY) */ +// Avoid zillions of not-quite-inlined copies of utilities. + +CORBA::UserException::UserException (void) +{ +} + +CORBA::UserException::UserException (const char *repository_id, + const char *local_name) + : CORBA::Exception (repository_id, + local_name) +{ +} + +CORBA::UserException::~UserException (void) +{ +} + +CORBA::UserException & +CORBA::UserException::operator= (const CORBA::UserException &src) +{ + this->Exception::operator= (src); + return *this; +} + +int +CORBA::UserException::_is_a (const char* interface_id) const +{ + return ACE_OS::strcmp (interface_id, + "IDL:omg.org/CORBA/UserException:1.0") == 0 + || this->Exception::_is_a (interface_id); +} + +CORBA::UserException* +CORBA::UserException::_downcast (CORBA::Exception* exception) +{ + if (exception->_is_a ("IDL:omg.org/CORBA/UserException:1.0")) + { + return dynamic_cast<CORBA::UserException *> (exception); + } + + return 0; +} + +const CORBA::UserException* +CORBA::UserException::_downcast (const CORBA::Exception *exception) +{ + if (exception->_is_a ("IDL:omg.org/CORBA/UserException:1.0")) + { + return dynamic_cast<const CORBA::UserException *> (exception); + } + + return 0; +} + +ACE_CString +CORBA::UserException::_info (void) const +{ + // @@ we can use the exception's typecode to dump all the data held + // within it ... + + ACE_CString user_exception_info = "user exception, ID '"; + user_exception_info += this->_rep_id (); + user_exception_info += "'"; + return user_exception_info; +} + +// **************************************************************** + +namespace CORBA +{ + CORBA::TypeCode_ptr _tc_UnknownUserException = 0; +} + +// **************************************************************** + +CORBA::SystemException::SystemException (void) +{ +} + +CORBA::SystemException::SystemException (const char *repository_id, + const char *local_name, + CORBA::ULong code, + CORBA::CompletionStatus completed) + : CORBA::Exception (repository_id, + local_name), + minor_ (code), + completed_ (completed) +{ +} + +CORBA::SystemException::SystemException (CORBA::ULong code, + CORBA::CompletionStatus completed) + : minor_ (code), + completed_ (completed) +{ +} + + +CORBA::SystemException::SystemException (const CORBA::SystemException &src) + : CORBA::Exception (src), + minor_ (src.minor_), + completed_ (src.completed_) +{ +} + +CORBA::SystemException::~SystemException (void) +{ +} + +CORBA::SystemException & +CORBA::SystemException::operator= (const CORBA::SystemException &src) +{ + this->Exception::operator= (src); + + this->minor_ = src.minor_; + this->completed_ = src.completed_; + + return *this; +} + + +int +CORBA::SystemException::_is_a (const char* interface_id) const +{ + return ((ACE_OS::strcmp (interface_id, this->_rep_id ()) == 0) || + (ACE_OS::strcmp (interface_id, + "IDL:omg.org/CORBA/SystemException:1.0") == 0) + || this->Exception::_is_a (interface_id)); +} + +CORBA::SystemException* +CORBA::SystemException::_downcast (CORBA::Exception* exception) +{ + if (exception->_is_a ("IDL:omg.org/CORBA/SystemException:1.0")) + { + return dynamic_cast<CORBA::SystemException *> (exception); + } + + return 0; +} + +const CORBA::SystemException* +CORBA::SystemException::_downcast (const CORBA::Exception *exception) +{ + if (exception->_is_a ("IDL:omg.org/CORBA/SystemException:1.0")) + { + return dynamic_cast<const CORBA::SystemException *> (exception); + } + + return 0; +} + +void +CORBA::SystemException::_tao_encode (TAO_OutputCDR &cdr + ACE_ENV_ARG_DECL) const +{ + if (cdr.write_string (this->_rep_id ()) + && cdr.write_ulong (this->minor ()) + && cdr.write_ulong (this->completed ())) + { + return; + } + + ACE_THROW (CORBA::MARSHAL ()); +} + +void +CORBA::SystemException::_tao_decode (TAO_InputCDR &cdr + ACE_ENV_ARG_DECL) +{ + // The string is read by the caller, to determine the exact type of + // the exception. We just decode the fields... + // cdr.read_string (this->id ()); + CORBA::ULong tmp; + + if (cdr.read_ulong (this->minor_) + && cdr.read_ulong (tmp)) + { + this->completed_ = CORBA::CompletionStatus (tmp); + return; + } + + ACE_THROW (CORBA::MARSHAL ()); +} + +CORBA::ULong +CORBA::SystemException::_tao_errno (int errno_value) +{ + switch (errno_value) + { + case 0: + return TAO_UNSPECIFIED_MINOR_CODE; + case ETIMEDOUT: + return TAO_ETIMEDOUT_MINOR_CODE; + case ENFILE: + return TAO_ENFILE_MINOR_CODE; + case EPIPE: + return TAO_EPIPE_MINOR_CODE; + case ECONNREFUSED: + return TAO_ECONNREFUSED_MINOR_CODE; + case ENOENT: + return TAO_ENOENT_MINOR_CODE; + +#if !defined (ACE_HAS_WINCE) + case EMFILE: + return TAO_EMFILE_MINOR_CODE; + case EBADF: + return TAO_EBADF_MINOR_CODE; + case EPERM: + return TAO_EPERM_MINOR_CODE; + case EINVAL: + return TAO_EINVAL_MINOR_CODE; +#endif // ACE_HAS_WINCE + +#if (ENOSYS != EFAULT) + case ENOSYS: + return TAO_ENOSYS_MINOR_CODE; +#endif /* ENOSYS != EFAULT */ + case EAFNOSUPPORT: + return TAO_EAFNOSUPPORT_MINOR_CODE; + case EAGAIN: + return TAO_EAGAIN_MINOR_CODE; + case ENOMEM: + return TAO_ENOMEM_MINOR_CODE; + case EACCES: + return TAO_EACCES_MINOR_CODE; + case EFAULT: + return TAO_EFAULT_MINOR_CODE; + case EBUSY: + return TAO_EBUSY_MINOR_CODE; + case EEXIST: + return TAO_EEXIST_MINOR_CODE; + case ECOMM: + return TAO_ECOMM_MINOR_CODE; + case ECONNRESET: + return TAO_ECONNRESET_MINOR_CODE; +#if (ENOTSUP != ENOSYS) + case ENOTSUP: + return TAO_ENOTSUP_MINOR_CODE; +#endif /* ENOSYS != EFAULT */ + default: + // Mask off bottom 7 bits and return them. + return errno_value & 0x7FU; + } +} + +CORBA::ULong +CORBA::SystemException::_tao_minor_code (u_int location, + int errno_value) +{ + return + TAO_DEFAULT_MINOR_CODE + | location + | _tao_errno (errno_value); +} + +void +CORBA::SystemException::_tao_print_system_exception (FILE *) const +{ + ACE_DEBUG ((LM_ERROR, + ACE_TEXT("(%P|%t) system exception, ID '%s'\n"), + ACE_TEXT_CHAR_TO_TCHAR (this->_info ().c_str ()))); +} + +ACE_CString +CORBA::SystemException::_info (void) const +{ + // @@ there are a few other "user exceptions" in the CORBA scope, + // they're not all standard/system exceptions ... really need to + // either compare exhaustively against all those IDs (yeech) or + // (preferably) to represent the exception type directly in the + // exception value so it can be queried. + + ACE_CString info = "system exception, ID '"; + info += this->_rep_id (); + info += "'\n"; + + const CORBA::ULong VMCID = this->minor () & 0xFFFFF000u; + + if (VMCID == TAO_DEFAULT_MINOR_CODE) + { + // @@ Move the following code to a subroutine, it is too long already! + const char *location; + switch (this->minor () & 0x00000F80u) + { + case TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE: + location = "location forward failed"; + break; + case TAO_INVOCATION_SEND_REQUEST_MINOR_CODE: + location = "send request failed"; + break; + case TAO_POA_DISCARDING: + location = "poa in discarding state"; + break; + case TAO_POA_HOLDING: + location = "poa in holding state"; + break; + case TAO_POA_INACTIVE: + location = "poa in inactive state"; + break; + case TAO_UNHANDLED_SERVER_CXX_EXCEPTION: + location = "unhandled c++ exception in server side"; + break; + case TAO_INVOCATION_RECV_REQUEST_MINOR_CODE: + location = "failed to recv request response"; + break; + case TAO_CONNECTOR_REGISTRY_NO_USABLE_PROTOCOL: + location = "all protocols failed to parse the IOR"; + break; + case TAO_MPROFILE_CREATION_ERROR: + location = "error during MProfile creation"; + break; + case TAO_TIMEOUT_CONNECT_MINOR_CODE: + location = "timeout during connect"; + break; + case TAO_TIMEOUT_SEND_MINOR_CODE: + location = "timeout during send"; + break; + case TAO_TIMEOUT_RECV_MINOR_CODE: + location = "timeout during recv"; + break; + case TAO_IMPLREPO_MINOR_CODE: + location = "implrepo server exception"; + break; + case TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE: + location = "endpoint initialization failure in Acceptor Registry"; + break; + case TAO_ORB_CORE_INIT_LOCATION_CODE: + location = "ORB Core initialization failed"; + break; + case TAO_POLICY_NARROW_CODE: + location = "Failure when narrowing a Policy"; + break; + case TAO_GUARD_FAILURE: + location = "Failure when trying to acquire a guard/monitor"; + break; + case TAO_POA_BEING_DESTROYED: + location = "POA has been destroyed or is currently being destroyed"; + break; + case TAO_AMH_REPLY_LOCATION_CODE: + location = "Failure when trying to send AMH reply"; + break; + case TAO_RTCORBA_THREAD_CREATION_LOCATION_CODE: + location = "Failure in thread creation for RTCORBA thread pool"; + break; + default: + location = "unknown location"; + } + + const char *errno_indication; + char unknown_errno [255]; + CORBA::ULong minor_code = this->minor () & 0x7FU; + switch (minor_code) + { + case TAO_UNSPECIFIED_MINOR_CODE: + errno_indication = "unspecified errno"; + break; + case TAO_ETIMEDOUT_MINOR_CODE: + errno_indication = "ETIMEOUT"; + break; + case TAO_ENFILE_MINOR_CODE: + errno_indication = "ENFILE"; + break; + case TAO_EMFILE_MINOR_CODE: + errno_indication = "EMFILE"; + break; + case TAO_EPIPE_MINOR_CODE: + errno_indication = "EPIPE"; + break; + case TAO_ECONNREFUSED_MINOR_CODE: + errno_indication = "ECONNREFUSED"; + break; + case TAO_ENOENT_MINOR_CODE: + errno_indication = "ENOENT"; + break; + case TAO_EBADF_MINOR_CODE: + errno_indication = "EBADF"; + break; + case TAO_ENOSYS_MINOR_CODE: + errno_indication = "ENOSYS"; + break; + case TAO_EPERM_MINOR_CODE: + errno_indication = "EPERM"; + break; + case TAO_EAFNOSUPPORT_MINOR_CODE: + errno_indication = "EAFNOSUPPORT"; + break; + case TAO_EAGAIN_MINOR_CODE: + errno_indication = "EAGAIN"; + break; + case TAO_ENOMEM_MINOR_CODE: + errno_indication = "ENOMEM"; + break; + case TAO_EACCES_MINOR_CODE: + errno_indication = "EACCES"; + break; + case TAO_EFAULT_MINOR_CODE: + errno_indication = "EFAULT"; + break; + case TAO_EBUSY_MINOR_CODE: + errno_indication = "EBUSY"; + break; + case TAO_EEXIST_MINOR_CODE: + errno_indication = "EEXIST"; + break; + case TAO_EINVAL_MINOR_CODE: + errno_indication = "EINVAL"; + break; + case TAO_ECOMM_MINOR_CODE: + errno_indication = "ECOMM"; + break; + case TAO_ECONNRESET_MINOR_CODE: + errno_indication = "ECONNRESET"; + break; + case TAO_ENOTSUP_MINOR_CODE: + errno_indication = "ENOTSUP"; + break; + default: + { + // 7 bits of some other errno. + ACE_OS::sprintf (unknown_errno, + "low 7 bits of errno: %3u %s", + minor_code, ACE_OS::strerror (minor_code)); + + errno_indication = unknown_errno; + } + } + + char buffer[BUFSIZ]; + ACE_OS::sprintf (buffer, + "TAO exception, " + "minor code = %x (%s; %s), " + "completed = %s\n", + minor_code, + location, + errno_indication, + (completed () == CORBA::COMPLETED_YES) ? "YES" : + (completed () == CORBA::COMPLETED_NO) ? "NO" : + (completed () == CORBA::COMPLETED_MAYBE) ? "MAYBE" : + "garbage"); + + info += buffer; + } + else if (VMCID == CORBA::OMGVMCID) + { + const CORBA::ULong minor_code = this->minor () & 0xFFFU; + + const char *minor_description = 0; + + if (minor_code > 0) + minor_description = + CORBA::SystemException::_tao_get_omg_exception_description ( + *this, + minor_code); + else + minor_description = "*unknown description*"; + + char buffer[BUFSIZ]; + ACE_OS::sprintf (buffer, + "OMG minor code (%d), " + "described as '%s', " + "completed = %s\n", + minor_code, + minor_description, + (completed () == CORBA::COMPLETED_YES) ? "YES" : + (completed () == CORBA::COMPLETED_NO) ? "NO" : + (completed () == CORBA::COMPLETED_MAYBE) ? "MAYBE" : + "garbage"); + + info += buffer; + } + else + { + char buffer[BUFSIZ]; + ACE_OS::sprintf (buffer, + "Unknown vendor minor code id (%x), " + "minor code = %x, completed = %s\n", + VMCID, + this->minor (), // Use the raw minor code + (completed () == CORBA::COMPLETED_YES) ? "YES" : + (completed () == CORBA::COMPLETED_NO) ? "NO" : + (completed () == CORBA::COMPLETED_MAYBE) ? "MAYBE" : + "garbage"); + + info += buffer; + } + + return info; +} + +const char * +CORBA::SystemException::_tao_get_omg_exception_description ( + const CORBA::SystemException &exc, + CORBA::ULong minor_code) +{ +#ifndef ACE_NDEBUG + + static const char *UNKNOWN_TABLE[] = + { + "Unlisted user exception received by client.", // 1 + "Non-standard SystemException not supported.", // 2 + "An unkown user exception received by a portable interceptor." // 3 + }; + + static const char *BAD_PARAM_TABLE[] = + { + "Failure to register, unregister, or lookup value factory.", // 1 + "RID already defined in IFR.", // 2 + "Name already used in the context in IFR.", // 3 + "Target is not a valid container.", // 4 + "Name clash in inherited context.", // 5 + "Incorrect type for abstract interface.", // 6 + "string_to_object conversion failed due to a bad scheme name.", // 7 + "string_to_object conversion failed due to a bad address.", // 8 + "string_to_object conversion failed due to a bad schema specific part.",// 9 + "string_to_object conversion failed due to non specific reason.", // 10 + "Attempt to derive abstract interface from non-abstract base interface in the Interface Repository.", // 11 + "Attempt to let a ValueDef support more than one non-abstract interface in the Interface Repository.", // 12 + "Attempt to use an incomplete TypeCode as a parameter.", // 13 + "Invalid object id passed to POA::create_reference_by_id.", // 14 + "Bad name argument in TypeCode operation.", // 15 + "Bad RepositoryId argument in TypeCode operation.", // 16 + "Invalid member namein TypeCode operation.", // 17 + "Duplicate label value in create_union_tc.", // 18 + "Incompatible TypeCode of label and discriminator in create_union_tc.", // 19 + "Supplied discriminator type illegitimate in create_union_tc.", // 20 + "Any passed to ServerRequest::set_exception does not contain an exception.", // 21 + "Unlisted user exception passed to ServerRequest::set_exception", // 22 + "wchar transmission code set not in service context.", // 23 + "Service context is not in OMG-defined range.", // 24 + "Enum value out of range.", // 25 + "Invalid service context Id in portable interceptor.", // 26 + "Attempt to call register_initial_reference with a null Object.", // 27 + "Invalid component Id in portable interceptor.", // 28 + "Invalid profile Id in portable interceptor.", // 29 + "Two or more Policy objects with the same PolicyType value supplied to Object::set_policy_overrides or PolicyManager::set_policy_overrides." // 30 + "Attempt to define a oneway operation with non-void result, out or inout parameters or user exceptions.", // 31 + "DII asked to create request for an implicit operation.", // 32, + "An OTS/XA integration xa_ call returned XAER_INVAL.", // 33 + "Union branch modifier called with bad case label discriminator.", // 34 + "Illegal IDL context property name.", // 35 + "Illegal IDL property search string.", // 36 + "Illegal IDL context name.", // 37 + "Non-empty IDL context.", // 38 + "Servant not found [ServantManager].", // 39 + "ORB output stream does not support ValueOutputStream interface.", // 40 + "ORB input stream does not support ValueInputStream interface." // 41 + }; + + static const char *IMP_LIMIT_TABLE[] = + { + "Unable to use any profile in IOR." // 1 + }; + + static const char *INITIALIZE_TABLE[] = + { + "Priority range too restricted for ORB." // 1 + }; + + + static const char *INV_OBJREF_TABLE[] = + { + "wchar Code Set support not specified.", // 1 + "Codeset component required for type using wchar or wstring data." // 2 + }; + + static const char *MARSHAL_TABLE[] = + { + "Unable to locate value factory.", // 1 + "ServerRequest::set_result called before ServerRequest::ctx when the operation IDL contains a context clause.", // 2 + "NVList passed to ServerRequest::arguments does not describe all parameters passed by client.", // 3 + "Attempt to marshal Local object.", // 4 + "wchar or wstring data erroneously sent by client over GIOP 1.0 connection.", // 5 + "wchar or wstring data erroneously returned by server over GIOP 1.0 connection." //6 + "Unsupported RMI/IDL custom value type stream format." // 7 + }; + + static const char *BAD_TYPECODE_TABLE[] = + { + "Attempt to marshal incomplete TypeCode.", // 1 + "Member type code illegitimate in TypeCode operation.", // 2 + "Illegal parameter type." // 3 + }; + + static const char *NO_IMPLEMENT_TABLE[] = + { + "Missing local value implementation.", // 1 + "Incompatible value implementation version.", // 2 + "Unable to use any profile in IOR.", // 3 + "Attempt to use DII on Local object.", // 4 + "Biomolecular Sequence Analysis iterator cannot be reset.", // 5 + "Biomolecular Sequence Analysis metadata is not available as XML.", // 6 + "Genomic Maps iterator cannot be rest." // 7 + }; + + static const char *NO_RESOURCE_TABLE[] = + { + "Portable Interceptor operation not support in this binding.", // 1 + "No connection for request's priority." // 2 + }; + + static const char *BAD_INV_ORDER_TABLE[] = + { + "Dependency exists in IFR preventing destruction of this object", // 1 + "Attempt to destroy indestructible objects in IFR.", // 2 + "Operation would deadlock.", // 3 + "ORB has shutdown.", // 4 + "Attempt to invoke \"send\" or \"invoke\" operation of the same \"Request\" object more than once.", // 5 + "Attempt to set a servant manager after one has already been set.", // 6 + "ServerRequest::arguments called more than once or after a call to ServerRequest::set_exception.", // 7 + "ServerRequest::ctx called more than once or before ServerRequest::arguments or after ServerRequest::ctx, ServerRequest::set_result or ServerRequest::set_exception.", // 8 + "ServerRequest::result called more than once or before ServerRequest::arguments or after ServerRequest::set_result or ServerRequest::set_exception.", // 9 + "Attempt to send a DII request after it was sent previously.", // 10 + "Attempt to poll a DII request or to retrieve its result before the request was sent.", // 11 + "Attempt to poll a DII request or to retrieve its result after the result was retrieved previously.", // 12 + "Attempt to poll a synchronous DII request or to retrieve results from a synchronous DII request.", // 13 + "Invalid portable interceptor call", // 14 + "Service context add failed in portable interceptor because a service context with the given id already exists.", // 15 + "Registration of PolicyFactory failed because a factory already exists for the given type.", // 16 + "POA cannot create POAs while undergoing destruction." // 17 + }; + + static const char *TRANSIENT_TABLE[] = + { + "Request discarded due to resource exhaustion in POA, or because POA is in discarding state.", // 1 + "No usable profile in IOR.", // 2 + "Request cancelled.", // 3 + "POA destroyed." // 4 + }; + + static const char *OBJ_ADAPTER_TABLE[] = + { + "System exception in POA::unknown_adapter.", // 1 + "Incorrect servant type returned by servant manager", // 2 + "No default servant available [POA policy].", // 3 + "No servant manager available [POA policy].", // 4 + "Violation of POA policy by ServantActivator::incarnate.",// 5 + "Exception in PortableInterceptor::IORInterceptor::components_established.", // 6 + "Null servant returned by servant manager." // 7 + }; + + static const char *DATA_CONVERSION_TABLE[] = + { + "Character does not map to negotiated transmission code set.", // 1 + "Failure of PriorityMapping object." // 2 + }; + + static const char *OBJECT_NOT_EXIST_TABLE[] = + { + "Attempt to pass an unactivated (unregistered) value as an object reference.", // 1 + "POAManager::incarnate failed to create POA." // 2 + }; + + static const char *INV_POLICY_TABLE[] = + { + "Unable to reconcile IOR specified policy with the effective policy override." // 1 + "Invalid PolicyType.", // 2 + "No PolicyFactory has been registered for the given PolicyType." // 3 + }; + + if (minor_code == 0) + return "*unknown description*"; + + minor_code--; // Adjust to match table offset. + + if (exc._is_a ("IDL:omg.org/CORBA/UNKNOWN:1.0") + && minor_code < sizeof UNKNOWN_TABLE / sizeof (char *)) + return UNKNOWN_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/BAD_PARAM:1.0") + && minor_code < sizeof BAD_PARAM_TABLE / sizeof (char *)) + return BAD_PARAM_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/IMP_LIMIT:1.0") + && minor_code < sizeof IMP_LIMIT_TABLE / sizeof (char *)) + return IMP_LIMIT_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/INITIALIZE:1.0") + && minor_code < sizeof INITIALIZE_TABLE / sizeof (char *)) + return INITIALIZE_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/INV_OBJREF:1.0") + && minor_code < sizeof INV_OBJREF_TABLE / sizeof (char *)) + return INV_OBJREF_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/MARSHAL:1.0") + && minor_code < sizeof MARSHAL_TABLE / sizeof (char *)) + return MARSHAL_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/BAD_TYPECODE:1.0") + && minor_code < sizeof BAD_TYPECODE_TABLE / sizeof (char *)) + return BAD_TYPECODE_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/NO_IMPLEMENT:1.0") + && minor_code < sizeof NO_IMPLEMENT_TABLE / sizeof (char *)) + return NO_IMPLEMENT_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/NO_RESOURCE:1.0") + && minor_code < sizeof NO_RESOURCE_TABLE / sizeof (char *)) + return NO_RESOURCE_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/BAD_INV_ORDER:1.0") + && minor_code < sizeof BAD_INV_ORDER_TABLE / sizeof (char *)) + return BAD_INV_ORDER_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/TRANSIENT:1.0") + && minor_code < sizeof TRANSIENT_TABLE / sizeof (char *)) + return TRANSIENT_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/OBJ_ADAPTER:1.0") + && minor_code < sizeof OBJ_ADAPTER_TABLE / sizeof (char *)) + return OBJ_ADAPTER_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/DATA_CONVERSION:1.0") + && minor_code < sizeof DATA_CONVERSION_TABLE / sizeof (char *)) + return DATA_CONVERSION_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") + && minor_code < sizeof OBJECT_NOT_EXIST_TABLE / sizeof (char *)) + return OBJECT_NOT_EXIST_TABLE[minor_code]; + + if (exc._is_a ("IDL:omg.org/CORBA/INV_POLICY:1.0") + && minor_code < sizeof INV_POLICY_TABLE / sizeof (char *)) + return INV_POLICY_TABLE[minor_code]; + +#else + ACE_UNUSED_ARG (exc); + ACE_UNUSED_ARG (minor_code); +#endif /* !ACE_NDEBUG */ + + return "*unknown description*"; +} + +// Note that "buffer" holds the (unscoped) name originally, and is +// then overwritten. + +void +TAO_Exceptions::make_unknown_user_typecode (CORBA::TypeCode_ptr &tcp + ACE_ENV_ARG_DECL) +{ + // Create the TypeCode for the CORBA::UnknownUserException. + TAO_OutputCDR stream (0, + ACE_CDR_BYTE_ORDER, + TAO_Exceptions::global_allocator_, + TAO_Exceptions::global_allocator_, + TAO_Exceptions::global_allocator_, + ACE_DEFAULT_CDR_MEMCPY_TRADEOFF); + + static const char * interface_id = + "IDL:omg.org/CORBA/UnknownUserException:1.0"; + static const char * name = "UnknownUserException"; + static const char * field_name = "exception"; + + const CORBA::Boolean result = + (stream.write_octet (TAO_ENCAP_BYTE_ORDER) == 0 + || stream.write_string (interface_id) == 0 + || stream.write_string (name) == 0 + || stream.write_ulong (1L) == 0 + || stream.write_string (field_name) == 0); + + if (result) + ACE_THROW (CORBA::INITIALIZE ()); + + if (!(stream << CORBA::_tc_any)) + ACE_THROW (CORBA::INITIALIZE ()); + + ACE_NEW_THROW_EX (tcp, + CORBA::TypeCode (CORBA::tk_except, + stream.length (), + stream.buffer (), + 1, + sizeof (CORBA::UserException)), + CORBA::INITIALIZE ()); +} + +void +TAO_Exceptions::make_standard_typecode (CORBA::TypeCode_ptr &tcp, + const char *name, + char *buffer, + size_t buflen + ACE_ENV_ARG_DECL) +{ + // This function must only be called ONCE, and with a global lock + // held! The <CORBA::ORB_init> method is responsible for ensuring + // this. + static const char *minor = "minor"; + static const char *completed = "completed"; + + // Create a CDR stream ... juggle the alignment here a bit, we know + // it's good enough for the typecode. + +#if defined(ACE_MVS) + // @@ We need to use a translator to make sure that all TypeCodes + // are stored in ISO8859 form, the problem is that this hack does + // not scale as more native sets have to be supported + + ACE_IBM1047_ISO8859 translator; + TAO_OutputCDR stream (buffer, + buflen, + ACE_CDR_BYTE_ORDER, + TAO_Exceptions::global_allocator_, + TAO_Exceptions::global_allocator_, + TAO_Exceptions::global_allocator_, + ACE_DEFAULT_CDR_MEMCPY_TRADEOFF, + &translator); +#else + TAO_OutputCDR stream (buffer, + buflen, + ACE_CDR_BYTE_ORDER, + TAO_Exceptions::global_allocator_, + TAO_Exceptions::global_allocator_, + TAO_Exceptions::global_allocator_, + ACE_DEFAULT_CDR_MEMCPY_TRADEOFF); +#endif /* ACE_MVS */ + + // into CDR stream, stuff (in order): + // - byte order flag [4 bytes] + // - exception ID [27 + N bytes] + // - exception name [4 + N bytes ] + // - number of members (2) [4 bytes ] + // - foreach member, { name string, typecode } [~40 bytes] + + static const char prefix[] = "IDL:omg.org/CORBA/"; + static const char suffix[] = ":1.0"; + char * full_id = + CORBA::string_alloc (sizeof prefix + + static_cast<CORBA::ULong> (ACE_OS::strlen (name)) + + sizeof suffix); + + CORBA::String_var safe_full_id = full_id; + + ACE_OS::strcpy (full_id, prefix); + ACE_OS::strcat (full_id, name); + ACE_OS::strcat (full_id, suffix); + + CORBA::Boolean result = stream.write_octet (TAO_ENCAP_BYTE_ORDER) == 0 + || stream.write_string (full_id) == 0 + || stream.write_string (name) == 0 + || stream.write_ulong (2L) != 1 + || stream.write_string (minor) == 0; + + result = result || !(stream << CORBA::_tc_ulong); + + (void) safe_full_id.out (); // No longer need the string + + result = result || stream.write_string (completed) == 0; + result = result || !(stream << TAO::TC_completion_status); + + if (result) + ACE_THROW (CORBA::INITIALIZE ()); + + // @@ It is possible to throw an exception at this point? + // What if the exception typecode has not been initialized yet? + + // OK, we stuffed the buffer we were given (or grew a bigger one; + // hope to avoid that during initialization). Now build and return + // a TypeCode, saving it away in the list of ones that the ORB will + // always accept as part of any operation response! + + ACE_NEW_THROW_EX (tcp, + CORBA::TypeCode (CORBA::tk_except, + stream.length (), + stream.buffer (), + 1, + sizeof (CORBA::SystemException)), + CORBA::INITIALIZE ()); + ACE_CHECK; + + ACE_ASSERT (tcp->length_ <= buflen); + return; +} + +#if defined (__Lynx__) + +// LynxOS uses macro THREAD_CANCELLED internally, so it must +// be undefined to avoid compilation errors +#if defined (THREAD_CANCELLED) +#undef THREAD_CANCELLED +#endif /* THREAD_CANCELLED */ + +#endif /*__Lynx__ */ + + +// List of standard/system exceptions ... used to create static +// storage for their typecodes, then later to initialize that storage +// using the routine above. (It's just too painful to init these +// typecodes statically in all cases!) + +#define STANDARD_EXCEPTION_LIST \ + TAO_SYSTEM_EXCEPTION (UNKNOWN) \ + TAO_SYSTEM_EXCEPTION (BAD_PARAM) \ + TAO_SYSTEM_EXCEPTION (NO_MEMORY) \ + TAO_SYSTEM_EXCEPTION (IMP_LIMIT) \ + TAO_SYSTEM_EXCEPTION (COMM_FAILURE) \ + TAO_SYSTEM_EXCEPTION (INV_OBJREF) \ + TAO_SYSTEM_EXCEPTION (OBJECT_NOT_EXIST) \ + TAO_SYSTEM_EXCEPTION (NO_PERMISSION) \ + TAO_SYSTEM_EXCEPTION (INTERNAL) \ + TAO_SYSTEM_EXCEPTION (MARSHAL) \ + TAO_SYSTEM_EXCEPTION (INITIALIZE) \ + TAO_SYSTEM_EXCEPTION (NO_IMPLEMENT) \ + TAO_SYSTEM_EXCEPTION (BAD_TYPECODE) \ + TAO_SYSTEM_EXCEPTION (BAD_OPERATION) \ + TAO_SYSTEM_EXCEPTION (NO_RESOURCES) \ + TAO_SYSTEM_EXCEPTION (NO_RESPONSE) \ + TAO_SYSTEM_EXCEPTION (PERSIST_STORE) \ + TAO_SYSTEM_EXCEPTION (BAD_INV_ORDER) \ + TAO_SYSTEM_EXCEPTION (TRANSIENT) \ + TAO_SYSTEM_EXCEPTION (FREE_MEM) \ + TAO_SYSTEM_EXCEPTION (INV_IDENT) \ + TAO_SYSTEM_EXCEPTION (INV_FLAG) \ + TAO_SYSTEM_EXCEPTION (INTF_REPOS) \ + TAO_SYSTEM_EXCEPTION (BAD_CONTEXT) \ + TAO_SYSTEM_EXCEPTION (OBJ_ADAPTER) \ + TAO_SYSTEM_EXCEPTION (DATA_CONVERSION) \ + TAO_SYSTEM_EXCEPTION (INV_POLICY) \ + TAO_SYSTEM_EXCEPTION (REBIND) \ + TAO_SYSTEM_EXCEPTION (TIMEOUT) \ + TAO_SYSTEM_EXCEPTION (TRANSACTION_UNAVAILABLE) \ + TAO_SYSTEM_EXCEPTION (TRANSACTION_MODE) \ + TAO_SYSTEM_EXCEPTION (TRANSACTION_REQUIRED) \ + TAO_SYSTEM_EXCEPTION (TRANSACTION_ROLLEDBACK) \ + TAO_SYSTEM_EXCEPTION (INVALID_TRANSACTION) \ + TAO_SYSTEM_EXCEPTION (CODESET_INCOMPATIBLE) \ + TAO_SYSTEM_EXCEPTION (BAD_QOS) \ + TAO_SYSTEM_EXCEPTION (INVALID_ACTIVITY) \ + TAO_SYSTEM_EXCEPTION (ACTIVITY_COMPLETED) \ + TAO_SYSTEM_EXCEPTION (ACTIVITY_REQUIRED) \ + TAO_SYSTEM_EXCEPTION (THREAD_CANCELLED) + +// Declare static storage for these ... the buffer is "naturally" +// aligned and overwritten. +// +// @@ this actually doesn't guarantee "natural" alignment, but +// it works that way in most systems. + +#define TAO_TC_BUF_LEN 256 + +static CORBA::Long tc_buf_CORBA[TAO_TC_BUF_LEN / sizeof (CORBA::Long)]; + +#define TAO_SYSTEM_EXCEPTION(name) \ + CORBA::TypeCode_ptr CORBA::_tc_ ## name = 0; + STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + + static CORBA::TypeCode_ptr *type_code_array [] = { +#define TAO_SYSTEM_EXCEPTION(name) \ + &CORBA::_tc_ ## name, + STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + &CORBA::_tc_null}; + +// Since we add an extra element subtract 1 +static const CORBA::ULong array_sz = + (sizeof (type_code_array) / sizeof (CORBA::TypeCode_ptr)) - 1; + +static const char *repo_id_array[] = { +#define TAO_SYSTEM_EXCEPTION(name) \ + (char *) "IDL:omg.org/CORBA/" #name ":1.0", + STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + 0 + }; + + +TAO::excp_factory excp_array [] = { +#define TAO_SYSTEM_EXCEPTION(name) \ + &CORBA::name::_tao_create, + STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + 0 + }; + +void +TAO_Exceptions::init (ACE_ENV_SINGLE_ARG_DECL) +{ + // This routine should only be called once. + + // Not thread safe. Caller must provide synchronization. + + if (TAO_Exceptions::initialized_) + { + return; + } + + // Initialize the start up allocator. + ACE_NEW (TAO_Exceptions::global_allocator_, + ACE_New_Allocator); + + static const char *name_array[] = { +#define TAO_SYSTEM_EXCEPTION(name) \ + # name, + STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + 0 + }; + + for (CORBA::ULong i = 0; i < array_sz; ++i) + { + TAO_Exceptions::make_standard_typecode (*type_code_array[i], + name_array[i], + (char*) tc_buf_CORBA, + sizeof tc_buf_CORBA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + + TAO_Exceptions::make_unknown_user_typecode (CORBA::_tc_UnknownUserException + ACE_ENV_ARG_PARAMETER); + + TAO_Exceptions::initialized_ = true; +} + +#undef TAO_TC_BUF_LEN + + +CORBA::SystemException * +TAO_Exceptions::create_system_exception (const char *id + ACE_ENV_ARG_DECL_NOT_USED) +{ + for (CORBA::ULong i = 0; i < array_sz; ++i) + { + if (ACE_OS::strcmp (id, repo_id_array[i]) == 0) + return (*(excp_array[i])) (); + } + + return 0; +} + +void +TAO_Exceptions::fini (void) +{ + for (CORBA::ULong i = 0; i < array_sz; ++i) + { + CORBA::release (*type_code_array[i]); + *type_code_array[i] = 0; + } + + CORBA::release (CORBA::_tc_UnknownUserException); + CORBA::_tc_UnknownUserException = 0; + + delete TAO_Exceptions::global_allocator_; + TAO_Exceptions::global_allocator_ = 0; +} + +#define TAO_SYSTEM_EXCEPTION(name) \ +CORBA::name * \ +CORBA::name ::_downcast (CORBA::Exception* exception) \ +{ \ + if (exception->_is_a ("IDL:omg.org/CORBA/" #name ":1.0")) \ + return dynamic_cast<CORBA::name *> (exception); \ + return 0; \ +} + +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + +#define TAO_SYSTEM_EXCEPTION(name) \ +void \ +CORBA::name ::_raise (void) const \ +{ \ + TAO_RAISE (*this); \ +} + +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + +// SystemException constructors +#define TAO_SYSTEM_EXCEPTION(name) \ +CORBA::name ::name (void) \ + : CORBA::SystemException ("IDL:omg.org/CORBA/" #name ":1.0", \ + #name, \ + TAO_DEFAULT_MINOR_CODE, \ + CORBA::COMPLETED_NO) \ +{ \ +} \ +\ +CORBA::name ::name (CORBA::ULong code, CORBA::CompletionStatus completed) \ + : CORBA::SystemException ("IDL:omg.org/CORBA/" #name ":1.0", \ + #name, \ + code, \ + completed) \ +{ \ +} + +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + +#define TAO_SYSTEM_EXCEPTION(name) \ +CORBA::TypeCode_ptr \ +CORBA::name ::_type (void) const \ +{ \ + return CORBA::_tc_ ## name; \ +} + +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + +#define TAO_SYSTEM_EXCEPTION(name) \ +void \ +CORBA::name ::_tao_any_destructor (void *x) \ +{ \ + CORBA::name *tmp = static_cast<CORBA::name *> (x); \ + delete tmp; \ +} + +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + +#define TAO_SYSTEM_EXCEPTION(name) \ +CORBA::Exception * \ +CORBA::name ::_tao_duplicate (void) const \ +{ \ + CORBA::Exception *result; \ + ACE_NEW_RETURN (result, CORBA::name (*this), 0); \ + return result; \ +} + +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + +#define TAO_SYSTEM_EXCEPTION(name) \ +CORBA::SystemException * \ +CORBA::name ::_tao_create (void) \ +{ \ + CORBA::name *result; \ + ACE_NEW_RETURN (result, CORBA::name (), 0); \ + return result; \ +} + +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + +#define TAO_SYSTEM_EXCEPTION(name) \ +void \ +CORBA::operator<<= (CORBA::Any &any, const CORBA::name &ex) \ +{ \ + TAO::Any_SystemException::insert_copy ( \ + any, \ + CORBA::name ::_tao_any_destructor, \ + CORBA::_tc_ ## name, \ + ex \ + ); \ +} + +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + +#define TAO_SYSTEM_EXCEPTION(name) \ +void \ +CORBA::operator<<= (CORBA::Any &any, CORBA::name *ex) \ +{ \ + TAO::Any_SystemException::insert ( \ + any, \ + CORBA::name ::_tao_any_destructor, \ + CORBA::_tc_ ## name, \ + ex \ + ); \ +} + +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + +#define TAO_SYSTEM_EXCEPTION(name) \ +CORBA::Boolean operator>>= (const CORBA::Any &any, \ + const CORBA::name *&ex) \ +{ \ + return \ + TAO::Any_SystemException::extract ( \ + any, \ + CORBA::name ::_tao_any_destructor, \ + CORBA::_tc_ ## name, \ + (const CORBA::SystemException *&) ex, \ + &CORBA::name ::_tao_create); \ +} + +STANDARD_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + + #if defined (TAO_DONT_CATCH_DOT_DOT_DOT) TAO_DONT_CATCH::TAO_DONT_CATCH (void) |