omniinternal.cc

来自「编译工具」· CC 代码 · 共 1,724 行 · 第 1/4 页

CC
1,724
字号
                           // by the var, hence fullfilling the semantics                           // of this function.                           // If this function completes normally, make                           // sure that _retn() is called on the var so                           // that the ior is not released incorrectly!  // Try an interceptor  omniIdentity* result = 0;  if (omniInterceptorP::createIdentity) {    omniInterceptors::createIdentity_T::info_T info(ior,target,result,locked);    omniInterceptorP::visit(info);    if (result) {      holder._retn();      return result;    }  }  // Decode the profiles  const IOP::TaggedProfileList& profiles = ior->iopProfiles();  if (ior->addr_selected_profile_index() < 0) {    // Pick the first TAG_INTERNET_IOP profile    CORBA::ULong total = profiles.length();    CORBA::ULong index;    for (index = 0; index < total; index++) {      if ( profiles[index].tag == IOP::TAG_INTERNET_IOP ) break;    }    if (index < total)      ior->addr_selected_profile_index(index);    else      omniORB::logs(25, "createIdentity for IOR with no IIOP profiles.");  }  omniIOR::IORInfo* info = ior->getIORInfo();  // getIORInfo() has the side effect of decoding the selected  // TAG_INTERNET_IOP profile and any IOP::TAG_MULTIPLE_COMPONENTS  // if that has not been done already.  //  // We use this function to trigger the decoding, instead of say  // calling omniIOR::decodeIOPprofile() first, because createIdentity  // may be called with the same ior more than once. It is highly  // undesirable if the IOP profile is decoded in each of these calls.  // Not only is this inefficent but doing so would create a thread  // safety nightmare.  CORBA::Boolean is_local = 0;  Rope* rope;  if (_OMNI_NS(giopRope)::selectRope(ior->getIORInfo()->addresses(),				     info,rope,is_local) == 0) {    return 0;  }  _CORBA_Unbounded_Sequence_Octet object_key;  if (ior->addr_selected_profile_index() >= 0)    IIOP::unmarshalObjectKey(profiles[ior->addr_selected_profile_index()],			     object_key);  if (is_local) {    CORBA::ULong hashv = hash(object_key.get_buffer(), object_key.length());    omni_optional_lock sync(*internalLock,locked,locked);    omniObjTableEntry* entry =      omniObjTable::locateActive(object_key.get_buffer(),				 object_key.length(), hashv, 0);    if (entry && entry->servant()->_ptrToInterface(target)) {      // Compatible activated object      return entry;    }    else {      // Not active or servant incompatible with target      return createInProcessIdentity(object_key.get_buffer(),				     object_key.length());    }  }  else {    // Remote    holder._retn();    omni_optional_lock sync(*internalLock,locked,locked);    result = new omniRemoteIdentity(ior,				    object_key.get_buffer(),				    object_key.length(),				    rope);    return result;  }}omniIdentity*omni::createInProcessIdentity(const _CORBA_Octet* key, int keysize) {  return new omniInProcessIdentity(key,keysize);}omniIdentity*omni::createLoopBackIdentity(omniIOR* ior,const _CORBA_Octet* key,int keysize){  Rope* rope = omniObjAdapter::defaultLoopBack();  rope->incrRefCount();  return new omniRemoteIdentity(ior,key,keysize,rope);}omniObjRef*omni::createObjRef(const char* targetRepoId,		   omniIOR* ior,		   CORBA::Boolean locked,		   omniIdentity* id){  ASSERT_OMNI_TRACEDMUTEX_HELD(*internalLock, locked);  OMNIORB_ASSERT(targetRepoId);  OMNIORB_ASSERT(ior);  if (id) {    omniLocalIdentity* lid = omniLocalIdentity::downcast(id);    if (lid && (!lid->servant() ||		!lid->servant()->_ptrToInterface(targetRepoId))) {      // Local id can't be used by the objref      omni_optional_lock sync(*internalLock,locked,locked);      id = createInProcessIdentity(lid->key(), lid->keysize());    }  }  else {    ior->duplicate();  // consumed by createIdentity    id = omni::createIdentity(ior, targetRepoId, locked);    if ( !id ) {      ior->release();      return 0;    }  }  proxyObjectFactory* pof = proxyObjectFactory::lookup(ior->repositoryID());  if( pof && !pof->is_a(targetRepoId) &&      !omni::ptrStrMatch(targetRepoId, CORBA::Object::_PD_repoId) ) {    // We know that <mostDerivedRepoId> is not derived from    // <targetRepoId>.     pof = 0;  }  // Once we reach here:  // if (pof != 0)  //    pof points to the proxy factory that is an exact match to  //    the interface identified by the ior's repository ID and it has been  //    verified that the interface identified by <targetRepoId> is  //    equal to or is a base class of the ior's repository ID.  // else  //    there is no proxy factory linked into this executable that  //    matches the interface identified by the ior's repository ID.  // or  //    there _is_ a proxy factory for ior's repository ID, but we  //    know that it is not derived from <targetRepoId>. We must  //    contact the object, in case it actually supports an interface  //    derived from both the ior's type and <targetRepoId>.  int target_intf_not_confirmed = 0;  if( !pof ) {    pof = proxyObjectFactory::lookup(targetRepoId);    OMNIORB_ASSERT(pof);    // The assertion above will fail if your application attempts to    // create an object reference while another thread is shutting    // down the ORB.    if( !omni::ptrStrMatch(targetRepoId, CORBA::Object::_PD_repoId) )      target_intf_not_confirmed = 1;  }  if( omniORB::trace(10) ) {    omniORB::logger l;    l << "Creating ref to ";    if      (omniLocalIdentity    ::downcast(id)) l << "local";    else if (omniInProcessIdentity::downcast(id)) l << "in process";    else if (omniRemoteIdentity   ::downcast(id)) l << "remote";    else                                          l << "unknown";    l << ": " << id << "\n"      " target id      : " << targetRepoId << "\n"      " most derived id: " << (const char*)ior->repositoryID() << "\n";  }  // Now create the object reference itself.  omniObjRef* objref = pof->newObjRef(ior, id);  if( target_intf_not_confirmed )  objref->pd_flags.type_verified = 0;  {    omni_optional_lock sync(*internalLock, locked, locked);    id->gainRef(objref);  }  if (orbParameters::persistentId.length()) {    // Check to see if we need to re-write the IOR.    omniIOR::IORExtraInfoList& extra = ior->getIORInfo()->extraInfo();    for (CORBA::ULong index = 0; index < extra.length(); index++) {      if (extra[index]->compid == IOP::TAG_OMNIORB_PERSISTENT_ID) {	if (!id->inThisAddressSpace()) {	  omniORB::logs(15, "Re-write local persistent object reference.");	  omniObjRef* new_objref;	  {	    omni_optional_lock sync(*internalLock, locked, locked);	    omniIOR* new_ior = new omniIOR(ior->repositoryID(),					   id->key(), id->keysize());	    new_objref = createObjRef(targetRepoId, new_ior, 1, 0);	  }	  releaseObjRef(objref);	  objref = new_objref;	}	break;      }    }  }  return objref;}omniObjRef*omni::createLocalObjRef(const char* mostDerivedRepoId,			const char* targetRepoId,			omniObjTableEntry* entry){  ASSERT_OMNI_TRACEDMUTEX_HELD(*internalLock, 1);  OMNIORB_ASSERT(targetRepoId);  OMNIORB_ASSERT(entry);  // See if a suitable reference exists in the local ref list.  // Suitable means having the same most-derived-intf-repo-id, and  // also supporting the <targetRepoId>.  {    omniObjRef* objref;    omnivector<omniObjRef*>::iterator i    = entry->objRefs().begin();    omnivector<omniObjRef*>::iterator last = entry->objRefs().end();    for (; i != last; i++) {      objref = *i;      if( omni::ptrStrMatch(mostDerivedRepoId, objref->_mostDerivedRepoId()) &&	  objref->_ptrToObjRef(targetRepoId) ) {	// We just need to check that the ref count is not zero here,	// 'cos if it is then the objref is about to be deleted!	// See omni::releaseObjRef().	objref_rc_lock->lock();	int dying = objref->pd_refCount == 0;	if( !dying )  objref->pd_refCount++;	objref_rc_lock->unlock();	if( !dying ) {	  omniORB::logs(15, "createLocalObjRef -- reusing reference from local"			" ref list.");	  return objref;	}      }    }  }  // Reach here if we have to create a new objref.  omniIOR* ior = new omniIOR(mostDerivedRepoId,			     entry->key(), entry->keysize());  return createObjRef(targetRepoId,ior,1,entry);}omniObjRef*omni::createLocalObjRef(const char* mostDerivedRepoId,			const char* targetRepoId,			const _CORBA_Octet* key, int keysize){  ASSERT_OMNI_TRACEDMUTEX_HELD(*internalLock, 1);  OMNIORB_ASSERT(targetRepoId);  OMNIORB_ASSERT(key && keysize);  // See if there's a suitable entry in the object table  CORBA::ULong hashv = hash(key, keysize);  omniObjTableEntry* entry = omniObjTable::locateActive(key, keysize,							hashv, 0);  if (entry)    return createLocalObjRef(mostDerivedRepoId, targetRepoId, entry);  omniIOR* ior = new omniIOR(mostDerivedRepoId, key, keysize);  return createObjRef(targetRepoId,ior,1,entry);}voidomni::revertToOriginalProfile(omniObjRef* objref){  ASSERT_OMNI_TRACEDMUTEX_HELD(*internalLock, 0);  OMNIORB_ASSERT(objref);  omniORB::logs(10, "Reverting object reference to original profile");  omniIOR_var ior = objref->_getIOR();  omni_tracedmutex_lock sync(*internalLock);  // We might have already been reverted... We check here  // rather than sooner, so as to avoid holding <internalLock>  // longer than necessary.  if( !objref->pd_flags.forward_location ) {    return;  }  ior->duplicate(); // consumed by createIdentity  omniIdentity* id = omni::createIdentity(ior, 					  objref->_localServantTarget(), 1);  if( !id ) {    OMNIORB_THROW(INV_OBJREF,INV_OBJREF_CorruptedObjRef, CORBA::COMPLETED_NO);  }  // For efficiency lets just assume that it exists.  We are  // about to retry anyway -- so we'll soon find out!  objref->pd_flags.forward_location = 0;  objref->pd_flags.type_verified = 1;  objref->pd_flags.object_exists = 1;  objref->_setIdentity(id);}voidomni::locationForward(omniObjRef* objref, omniObjRef* new_location,		      CORBA::Boolean permanent){  ASSERT_OMNI_TRACEDMUTEX_HELD(*internalLock, 0);  OMNIORB_ASSERT(objref);  OMNIORB_ASSERT(new_location);  omniORB::logs(10, "GIOP::LOCATION_FORWARD -- retry request.");  // I suppose it is possible that a local servant was stupid  // enough to re-direct us to itself!  If this happened it is  // just possible that new_location == objref (if the most-  // derived and interface types were the same).  if( new_location == objref ) {    releaseObjRef(new_location);    return;  }  {    omni_tracedmutex_lock sync(*internalLock);    // We assume that the new object exists, and that it supports    // the correct interface.  If it doesn't exist we'll get an    // OBJECT_NOT_EXIST exception, revert to the original and try    // again.  At worst we will keep trying again and again with    // exponential backoff.    //  If it supports the wrong interface then this is not our    // fault.  It should show up as a BAD_OPERATION or something.    objref->pd_flags.forward_location = 1;    objref->pd_flags.object_exists = 1;    objref->pd_flags.type_verified = 1;    // <new_location>'s identity may well be sufficient    // for our needs -- but if local we do need to check    // that the servant supports the correct c++ type    // interface.    omniIdentity* new_id = new_location->_identity();    omniLocalIdentity* new_lid = omniLocalIdentity::downcast(new_id);    if (new_lid) {      if (new_lid->deactivated() ||	  !new_lid->servant()->_ptrToInterface(objref->_localServantTarget())){	// Identity in new location is either dead or incompatible	// with this object reference. Use an inProcessIdentity.	new_id = createInProcessIdentity(new_lid->key(), new_lid->keysize());	objref->pd_flags.type_verified = 0;      }    }    objref->_setIdentity(new_id);    if (permanent) {      // This location forwarding is permanent, replace the IOR of this      // object reference with the new one. If this object reference is      // later passed to another server, the new IOR will be transferred.      omni_tracedmutex_lock sync(*omniIOR::lock);      new_location->pd_ior->duplicateNoLock();      objref->pd_ior->releaseNoLock();      objref->pd_ior = new_location->pd_ior;      objref->pd_flags.forward_location = 0;    }  }  releaseObjRef(new_location);}voidomni::assertFail(const char* file, int line, const char* expr){  if( omniORB::trace(1) ) {    omniORB::logger l;    l << "Assertion failed.  This indicates a bug in the application using\n"      "omniORB, or maybe in omniORB itself.\n"      " file: " << file << "\n"      " line: " << line << "\n"      " info: " << expr << "\n";  }  throw omniORB::fatalException(file, line, expr);}voidomni::ucheckFail(const char* file, int line, const char* expr){

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?