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 + -
显示快捷键?