diff options
Diffstat (limited to 'TAO/tao/IIOP_Object.cpp')
-rw-r--r-- | TAO/tao/IIOP_Object.cpp | 732 |
1 files changed, 0 insertions, 732 deletions
diff --git a/TAO/tao/IIOP_Object.cpp b/TAO/tao/IIOP_Object.cpp deleted file mode 100644 index 6066b2cf140..00000000000 --- a/TAO/tao/IIOP_Object.cpp +++ /dev/null @@ -1,732 +0,0 @@ -// $Id$ - -// @ (#)iiopobj.cpp 1.9 95/11/04 -// Copyright 1995 by Sun Microsystems Inc. -// All Rights Reserved -// -// IIOP Bridge: CORBA::Object operations -// -// Some CORBA::Object and other operations are specific to this IIOP -// based implementation, and can neither be used by other kinds of -// objref nor have a default implementation. - -#include "tao/corba.h" - -#if !defined (__ACE_INLINE__) -# include "tao/IIOP_Object.i" -#endif /* ! __ACE_INLINE__ */ - -int -IIOP::Profile::set (const char *h, - const CORBA::UShort p, - const ACE_INET_Addr *addr) -{ - this->iiop_version.major = IIOP::MY_MAJOR; - this->iiop_version.minor = IIOP::MY_MINOR; - - if (this->host) - { - delete [] this->host; - this->host = 0; - } - - this->port = p; - - if (h) - { - ACE_NEW_RETURN (this->host, - char[ACE_OS::strlen(h) + 1], - -1); - ACE_OS::strcpy (this->host, h); - } - - this->object_addr (addr); - return 0; -} - -int -IIOP::Profile::set (const char *h, - const CORBA::UShort p, - const char *key, - const ACE_INET_Addr *addr) -{ - if (key == 0) - return -1; - - if (this->set (h, p, addr) == -1) - return -1; - - int l = ACE_OS::strlen (key); - this->object_key.length (l); - - for (int i = 0; i < l; ++i) - this->object_key[i] = key[i]; - - return 0; -} - -int -IIOP::Profile::set (const char *h, - const CORBA::UShort p, - const TAO_opaque &key, - const ACE_INET_Addr *addr) -{ - if (this->set (h, p, addr) == -1) - return -1; - - this->object_key = key; - - return 0; -} - -IIOP::Profile::Profile (const IIOP::Profile &src) - : host (0) -{ - (void) this->set (src.host, - src.port, - src.object_key, - &src.object_addr_); -} - -int -IIOP::Profile::set (const ACE_INET_Addr &addr, - const char *key) -{ - // Set up an IIOP Profile to hold the host name. - - if (addr.get_ip_address () == INADDR_ANY) - { - // Special case. - char temphost[MAXHOSTNAMELEN + 1]; - if (addr.get_host_name (temphost, sizeof(temphost)) != 0) - return -1; - else - return this->set (temphost, - addr.get_port_number (), - key, - &addr); - } - else - { - const char *tempaddr = addr.get_host_name (); - if (tempaddr == 0) - return -1; - else - return this->set (tempaddr, - addr.get_port_number (), - key, - &addr); - } -} - -int -IIOP::Profile::set (const ACE_INET_Addr &addr, - const TAO_opaque &key) -{ - // Set up an IIOP Profile to hold the host name. - - if (addr.get_ip_address () == INADDR_ANY) - { - // Special case. - char temphost[MAXHOSTNAMELEN + 1]; - if (addr.get_host_name (temphost, sizeof(temphost)) != 0) - return -1; - else - return this->set (temphost, - addr.get_port_number (), - key, - &addr); - } - else - { - const char *tempaddr = addr.get_host_name (); - if (tempaddr == 0) - return -1; - else - return this->set (tempaddr, - addr.get_port_number (), - key, - &addr); - } -} - -IIOP::Profile::Profile (const char *h, - const CORBA::UShort p, - const char *key) - : host (0) -{ - (void) this->set (h, p, key); -} - -IIOP::Profile::Profile (const char *h, - const CORBA::UShort p, - const char *key, - const ACE_INET_Addr &addr) - : host (0) -{ - (void) this->set (h, p, key, &addr); -} - -IIOP::Profile::Profile (const ACE_INET_Addr &addr, - const char *key) - : host (0) -{ - (void) this->set (addr, key); -} - -IIOP::Profile::Profile (const ACE_INET_Addr &addr, - const TAO_opaque &key) - : host (0) -{ - (void) this->set (addr, key); -} - -// Quick'n'dirty hash of objref data, for partitioning objrefs into -// sets. -// -// NOTE that this must NOT go across the network! - -CORBA::ULong -IIOP_Object::hash (CORBA::ULong max, - CORBA::Environment &env) -{ - CORBA::ULong hashval; - - env.clear (); - - // Just grab a bunch of convenient bytes and hash them; could do - // more (hostname, full key, exponential hashing) but no real need - // to do so except if performance requires a more costly hash. - - hashval = profile.object_key.length () * profile.port; - hashval += profile.iiop_version.minor; - - if (profile.object_key.length () >= 4) - { - hashval += profile.object_key [1]; - hashval += profile.object_key [3]; - } - - return hashval % max; -} - -int operator==(const TAO_opaque& rhs, - const TAO_opaque& lhs) -{ - if (rhs.length () != lhs.length ()) - return 0; - - for (CORBA::ULong i = 0; - i < rhs.length (); - ++i) - if (rhs[i] != lhs[i]) - return 0; - - return 1; -} - -// Expensive comparison of objref data, to see if two objrefs -// certainly point at the same object. (It's quite OK for this to -// return FALSE, and yet have the two objrefs really point to the same -// object.) -// -// NOTE that this must NOT go across the network! - -CORBA::Boolean -IIOP_Object::is_equivalent (CORBA::Object_ptr other_obj, - CORBA::Environment &env) -{ - IIOP::Profile *body, *body2; - IIOP_Object *other_iiop_obj; - - env.clear (); - - if (CORBA::is_nil (other_obj) == CORBA::B_TRUE - || other_obj->QueryInterface (IID_IIOP_Object, - (void **) &other_iiop_obj) != TAO_NOERROR) - return CORBA::B_FALSE; - CORBA::release (other_obj); - - // Compare all the bytes of the object address -- must be the same. - - body = &profile; - body2 = &other_iiop_obj->profile; - - ACE_ASSERT (body->object_key.length () < UINT_MAX); - - return body->object_key == body2->object_key - && body->port == body2->port - && ACE_OS::strcmp (body->host, body2->host) == 0 - && body->iiop_version.minor == body2->iiop_version.minor - && body->iiop_version.major == body2->iiop_version.major; -} - -// For COM -- IUnknown operations - -// {A201E4C3-F258-11ce-9598-0000C07CA898} -DEFINE_GUID (IID_IIOP_Object, -0xa201e4c3, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); - -ULONG -IIOP_Object::AddRef (void) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, this->IUnknown_lock_, 0)); - - return ++this->refcount_; -} - -ULONG -IIOP_Object::Release (void) -{ - { - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, mon, this->IUnknown_lock_, 0)); - - ACE_ASSERT (this != 0); - - if (--this->refcount_ > 0) - return this->refcount_; - } - - delete this; - return 0; -} - -// Note that (as of this writing) this is the only place all the -// interfaces to an "objref" come together: -// -// IUnknown ... this one -// STUB_OBJECT ... inherited by this one -// IIOP_OBJECT ... this one -// -TAO_HRESULT -IIOP_Object::QueryInterface (REFIID riid, - void **ppv) -{ - *ppv = 0; - - if (IID_IIOP_Object == riid - || IID_STUB_Object == riid - || IID_TAO_IUnknown == riid) - *ppv = this; - - if (*ppv == 0) - return TAO_ResultFromScode (TAO_E_NOINTERFACE); - - (void) AddRef (); - return TAO_NOERROR; -} - -// TAO extensions -TAO_ObjectKey* -IIOP_Object::key (CORBA::Environment &) -{ - return new TAO_ObjectKey (this->profile.object_key); -} - -// It will usually be used by the _bind call. -// -// Note that if the repository ID (typeID) is NULL, it will make -// narrowing rather expensive, though it does ensure that type-safe -// narrowing code gets thoroughly exercised/debugged! Without a -// typeID, the _narrow will be required to make an expensive remote -// "is_a" call. - -IIOP_Object::IIOP_Object (const char *host, - const CORBA::UShort port, - const char *objkey, - char *repository_id) - : STUB_Object (repository_id), - profile (host, port, objkey), - refcount_ (1), - fwd_profile_ (0) -{ -} - -// Constructor. It will usually be used by the server side. -IIOP_Object::IIOP_Object (char *repository_id, - const ACE_INET_Addr &addr, - const char *objkey) - : STUB_Object (repository_id), - profile (addr, objkey), - refcount_ (1), - fwd_profile_ (0) -{ -} - -// THREADING NOTE: Code below this point is of course thread-safe (at -// least on supported threaded platforms), so the caller of these -// routines need only ensure that the data being passed in is not -// being modified by any other thread. -// -// As an _experiment_ (to estimate the performance cost) remote calls -// are currently deemed "cancel-safe". That means that they can be -// called by threads when they're in asynchronous cancellation mode. -// The only effective way to do this is to disable async cancellation -// for the duration of the call. There are numerous rude interactions -// with code generators for C++ ... cancellation handlers just do -// normal stack unwinding like exceptions, but exceptions are purely -// synchronous and sophisticated code generators rely on that to -// generate better code, which in some cases may be very hard to -// unwind. - -class TAO_Synchronous_Cancellation_Required - // = TITLE - // Stick one of these at the beginning of a block that can't - // support asynchronous cancellation, and which must be - // cancel-safe. - // - // = EXAMPLE - // somefunc() - // { - // TAO_Synchronous_Cancellation_Required NOT_USED; - // ... - // } -{ -public: - // These should probably be in a separate inline file, but they're - // only used within this one file right now, and we always want them - // inlined, so here they sit. - TAO_Synchronous_Cancellation_Required (void) - : old_type_ (0) - { -#if !defined (VXWORKS) - ACE_OS::thr_setcanceltype (THR_CANCEL_DEFERRED, &old_type_); -#endif /* ! VXWORKS */ - } - - ~TAO_Synchronous_Cancellation_Required (void) - { -#if !defined (VXWORKS) - int dont_care; - ACE_OS::thr_setcanceltype(old_type_, &dont_care); -#endif /* ! VXWORKS */ - } -private: - int old_type_; -}; - -// "Stub interpreter" for static stubs. IDL compiler (or human -// equivalent thereof :-) should just dump a read-only description of -// the call into "calldata" and do varargs calls to this routine, -// which does all the work. - -void -IIOP_Object::do_static_call (CORBA::Environment &env, // exception reporting - const TAO_Call_Data *info, // call description - ...) // ... any parameters - -{ - TAO_Synchronous_Cancellation_Required NOT_USED; - - TAO_GIOP_Invocation call (this, - info->opname, - info->is_roundtrip); - - // We may need to loop through here more than once if we're - // forwarded to some other object reference. - // - // NOTE: A quality-of-service policy may be useful to establish - // here, specifically one controlling how many times the call is - // reissued before failing the call on the assumption that something - // is broken. - // - // NOTE: something missing is a dynamic way to change the policy of - // whether to issue LocateRequest messages or not. This code uses a - // simple, fixed policy: never use LocateRequest messages. - // - for (;;) - { - // Start the call by constructing the request message header. - - env.clear (); - call.start (env); - - if (env.exception ()) - { - dexc (env, "do_static_call, start request message"); - return; - } - - // Now, put all "in" and "inout" parameters into the request - // message body. - // - // Some "inout" data have an extra level of indirection, - // specified by the language mapping's memory allocation - // policies ... the indirection only shows up here when it's - // needed later for allocating "out" memory, otherwise there's - // just one indirection. - - u_int i; - const TAO_Param_Data *pdp; - va_list param_vector; - - va_start (param_vector, info); - - for (i = 0, pdp = info->params; - i < info->param_count; - i++, pdp++) - { - void *ptr = va_arg (param_vector, void *); - - if (pdp->mode == PARAM_IN) - call.put_param (pdp->tc, ptr, env); - else if (pdp->mode == PARAM_INOUT) - { - if (pdp->value_size == 0) - call.put_param (pdp->tc, ptr, env); - else - call.put_param (pdp->tc, *(void **)ptr, env); - } - - if (env.exception ()) - { - dexc (env, "do_static_call, put request parameter"); - return; - } - } - va_end (param_vector); - - // Make the call ... blocking for response if needed. Note that - // "oneway" calls can't return any exceptions except system - // ones. - - TAO_GIOP_ReplyStatusType status; - CORBA::ExceptionList exceptions; - - exceptions.length = exceptions.maximum = info->except_count; - exceptions.buffer = (CORBA::TypeCode_ptr *) info->excepts; - - status = call.invoke (exceptions, env); - - exceptions.buffer = 0; // don't free it - - if (env.exception ()) - { - dexc (env, "do_static_call, invoke"); - return; - } - if (!info->is_roundtrip - || status == TAO_GIOP_SYSTEM_EXCEPTION - || status == TAO_GIOP_USER_EXCEPTION) - return; - - // Now, get all the "return", "out", and "inout" parameters from - // the response message body. - - if (status == TAO_GIOP_NO_EXCEPTION) - { - va_start (param_vector, info); - for (i = 0, pdp = info->params; - i < info->param_count; - i++, pdp++) - { - void *ptr = va_arg (param_vector, void *); - - // if it is an inout parameter, it would become necessary to - // first release the "in" memory - if (pdp->mode == PARAM_INOUT) - { - // @@ - add others as we test each case - // (ASG) will do 03/22/98. - switch (pdp->tc->kind (env)) - { - case CORBA::tk_string: - { - CORBA::string_free (*(char **)ptr); - *(char **)ptr = 0; - } - break; - default: - break; - } - } - if (pdp->mode == PARAM_RETURN - || pdp->mode == PARAM_OUT - || pdp->mode == PARAM_INOUT) - { - // The language mapping's memory allocation policy - // says that some data is heap-allocated. This - // interpreter is told about the relevant policy by - // whoever built the operation description (e.g. the - // IDL compiler) so it doesn't have to know the - // policy associated with a particular language - // binding (e.g. C/C++ differ, and C++ even has - // different policies for different kinds of - // structures). - if (pdp->value_size == 0) - call.get_value (pdp->tc, ptr, env); - else - { - // assert (value_size == tc->size()); - *(void **)ptr = new CORBA::Octet [pdp->value_size]; - call.get_value (pdp->tc, *(void **)ptr, env); - } - - if (env.exception ()) - { - dexc (env, "do_static_call, get reply parameter"); - return; - } - } - } - va_end (param_vector); - return; - } - - // ... or maybe this request got forwarded to someplace else; send - // the request there instead. - assert (status == TAO_GIOP_LOCATION_FORWARD); - } -} - -// DII analogue of the above. Differs in how the vararg calling -// convention is implemented -- DII doesn't use the normal call stack -// with its implicit typing, but iinstead uses heap-based arguments -// with explicit typing. - -void -IIOP_Object::do_dynamic_call (const char *opname, // operation name - CORBA::Boolean is_roundtrip, // results required? - CORBA::NVList_ptr args, // parameters - CORBA::NamedValue_ptr result, // result - CORBA::Flags flags, // per-call flag (one!) - CORBA::ExceptionList &exceptions, // possible user exceptions - CORBA::Environment &env) // exception reporting -{ - TAO_Synchronous_Cancellation_Required NOT_USED; - - TAO_GIOP_Invocation call (this, opname, is_roundtrip); - - // Loop as needed for forwarding; see above. - - for (;;) - { - // Start the call by constructing the request message header. - env.clear (); - call.start (env); - - if (env.exception ()) - { - dexc (env, "do_static_call, start request message"); - return; - } - - // Now, put all "in" and "inout" parameters into the request - // message body. - - u_int i; - - for (i = 0; i < args->count (); i++) - { - CORBA::NamedValue_ptr value = args->item (i, env); - - if (value->flags () == CORBA::ARG_IN - || value->flags () == CORBA::ARG_INOUT) - { - call.put_param (value->value ()->type (), - (void *) value->value ()->value (), env); - if (env.exception ()) - { - dexc (env, "do_dynamic_call, put request parameter"); - return; - } - } - } - - // Make the call ... blocking for response if needed. Note that - // "oneway" calls can't return any exceptions except system ones. - - TAO_GIOP_ReplyStatusType status; - - status = call.invoke (exceptions, env); - if (env.exception ()) - { - dexc (env, "do_dynamic_call, invoke"); - return; - } - if (!is_roundtrip - || status == TAO_GIOP_SYSTEM_EXCEPTION - || status == TAO_GIOP_USER_EXCEPTION) - return; - - // Now, get all the "return", "out", and "inout" parameters from the - // response message body ... return parameter is first, the rest are - // in the order defined in the IDL spec (which is also the order that - // DII users are required to use). - - if (status == TAO_GIOP_NO_EXCEPTION) - { - if (result != 0) - { - // If caller didn't set OUT_LIST_MEMORY flag, allocate - // memory for return value ... - - if (!(flags & CORBA::OUT_LIST_MEMORY)) - { - CORBA::TypeCode_ptr tcp; - size_t size; - - tcp = result->value ()->type (); - size = tcp->size (env); - dexc (env, "do_dynamic_call, get result size"); - - if (size != 0) - { - void *ptr = new CORBA::Octet [size]; - - tcp->AddRef (); - result->value ()->replace (tcp, ptr, - CORBA::B_TRUE, env); - dexc (env, "do_dynamic_call, set result mem"); - } - } - - call.get_value (result->value ()->type (), - (void *) result->value ()->value (), env); - } - - for (i = 0; i < args->count (); i++) - { - CORBA::NamedValue_ptr value = args->item (i, env); - - if (value->flags () == CORBA::ARG_OUT - || value->flags () == CORBA::ARG_INOUT) - { - // If caller didn't set OUT_LIST_MEMORY flag, allocate - // memory for this parameter ... - if (!(flags & CORBA::OUT_LIST_MEMORY)) - { - CORBA::TypeCode_ptr tcp; - size_t size; - - tcp = value->value ()->type (); - size = tcp->size (env); - dexc (env, "do_dynamic_call, get param size"); - - if (size != 0) - { - void *ptr = new CORBA::Octet [size]; - - tcp->AddRef (); - value->value ()->replace (tcp, ptr, - CORBA::B_TRUE, env); - dexc (env, "do_dynamic_call, set result mem"); - } - } - - call.get_value (value->value ()->type (), - (void *) value->value ()->value (), env); - if (env.exception ()) - { - dexc (env, "do_dynamic_call, get response parameter"); - return; - } - } - } - return; - } - - // ... or maybe this request got forwarded to someplace else. - assert (status == TAO_GIOP_LOCATION_FORWARD); - } -} |