📄 poa.cc
字号:
// Normal case -- do the call here call_desc.poa(this); _OMNI_NS(poaCurrentStackInsert) insert(&call_desc); call_desc.doLocalCall(id->servant());}intomniOrbPOA::objectExists(const _CORBA_Octet*, int){ if( pd_policy.req_processing == RPP_ACTIVE_OBJ_MAP ) return 0; pd_lock.lock(); int ret = pd_defaultServant || pd_servantActivator || pd_servantLocator; pd_lock.unlock(); return ret;}voidomniOrbPOA::lastInvocationHasCompleted(omniLocalIdentity* id){ ASSERT_OMNI_TRACEDMUTEX_HELD(*omni::internalLock, 1); omniObjTableEntry* entry = omniObjTableEntry::downcast(id); OMNIORB_ASSERT(entry); // This function should only ever be called with a localIdentity // which is an objectTableEntry, since those are the only ones which // can be deactivated. if (entry->state() == omniObjTableEntry::DEACTIVATING_OA) { if (omniORB::trace(15)) { omniORB::logger l; l << "POA(" << (char*) pd_name << ") not etherealising object " << entry <<".\n"; } omni::internalLock->unlock(); return; } if( omniORB::trace(15) ) { omniORB::logger l; l << "POA(" << (char*) pd_name << ") etherealising object " << entry <<".\n" << " id: " << id->servant()->_mostDerivedRepoId() << "\n"; } entry->setEtherealising(); omni::internalLock->unlock(); PortableServer::ServantActivator_ptr sa = 0; // This lock _could_ go inside the body of the 'if' below, but I want // to ensure that we take this lock no matter what. The reason is to // ensure that detached_object() is called (in deactivate_object()) // before met_detached_object() (below). Otherwise we get a nasty // race ... pd_lock.lock(); if( (pd_policy.req_processing == RPP_SERVANT_MANAGER && pd_policy.retain_servants) || pd_dying ) { // The omniLocalIdentity still holds a reference to us, and // we hold a reference to the servant activator, so we don't // need to grab a reference to pd_servantActivator here. // (since it is also immutable once set). sa = pd_servantActivator; if( pd_dying && !pd_destroyed ) { // We cannot etherealise until apparent destruction is complete. // Wait for apparent destruction. if (omniORB::trace(25)) { omniORB::logger l; l << "Waiting for destruction of POA before etherealising " << entry << ".\n"; } while( !pd_destroyed ) pd_deathSignal.wait(); omniORB::logs(25, "POA destroyed; continuing with etherealisation."); } } pd_lock.unlock(); PortableServer::Servant servant = DOWNCAST(id->servant()); if( sa ) { // Delegate etherealisation to a separate thread. add_object_to_etherealisation_queue(entry, sa, 0, 1); } else { omni::internalLock->lock(); entry->setDead(); omni::internalLock->unlock(); try { servant->_remove_ref(); } catch (...) { // _remove_ref should not throw exceptions, but in case it does, // we deal with it here. met_detached_object(); throw; } met_detached_object(); }}//////////////////////// omniORB Internal ////////////////////////static void generateUniqueId(CORBA::Octet* k);omniOrbPOA::omniOrbPOA(const char* name, omniOrbPOAManager* manager, const Policies& policies, omniOrbPOA* parent) : OMNIORB_BASE_CTOR(PortableServer::)POA(0), pd_destroyed(0), pd_dying(0), pd_refCount(1), pd_parent(parent), pd_adapterActivator(0), pd_servantActivator(0), pd_servantLocator(0), pd_defaultServant(0), pd_rq_state(PortableServer::POAManager::HOLDING), pd_call_lock(0), pd_deathSignal(&pd_lock), pd_oidIndex(0), pd_activeObjList(0), pd_oidPrefix(0){ OMNIORB_ASSERT(name); OMNIORB_ASSERT(manager); pd_name = name; pd_manager = manager; if (pd_parent == (omniOrbPOA*)1) { // This is the magic INS POA OMNIORB_ASSERT(theRootPOA); theRootPOA->incrRefCount(); pd_parent = theRootPOA; int fnlen = strlen(pd_parent->pd_fullname) + strlen(name) + 1; pd_fullname = _CORBA_String_helper::alloc(fnlen); strcpy(pd_fullname, pd_parent->pd_fullname); strcat(pd_fullname, POA_NAME_SEP_STR); strcat(pd_fullname, name); pd_poaIdSize = 0; pd_poaId = (const char*)""; } else if( pd_parent ) { int fnlen = strlen(parent->pd_fullname) + strlen(name) + 1; pd_fullname = _CORBA_String_helper::alloc(fnlen); strcpy(pd_fullname, parent->pd_fullname); strcat(pd_fullname, POA_NAME_SEP_STR); strcat(pd_fullname, name); pd_poaIdSize = fnlen + 1; if( policies.transient ) pd_poaIdSize += TRANSIENT_SUFFIX_SIZE + 1; pd_poaId = _CORBA_String_helper::alloc(pd_poaIdSize - 1); strcpy(pd_poaId, pd_fullname); if( policies.transient ) { ((char*) pd_poaId)[fnlen] = TRANSIENT_SUFFIX_SEP; generateUniqueId((_CORBA_Octet*) ((char*) pd_poaId + fnlen + 1)); ((char*) pd_poaId)[pd_poaIdSize - 1] = '\0'; } else if (!policies.user_assigned_id && poaUniquePersistentSystemIds) { pd_oidPrefix = new CORBA::Octet[TRANSIENT_SUFFIX_SIZE]; generateUniqueId(pd_oidPrefix); } } else { // This is the root poa. OMNIORB_ASSERT(policies.transient); pd_fullname = (const char*) ""; pd_poaIdSize = 1 + TRANSIENT_SUFFIX_SIZE + 1; pd_poaId = _CORBA_String_helper::alloc(pd_poaIdSize - 1); ((char*) pd_poaId)[0] = TRANSIENT_SUFFIX_SEP; generateUniqueId((_CORBA_Octet*) ((char*) pd_poaId + 1)); ((char*) pd_poaId)[pd_poaIdSize - 1] = '\0'; } switch (policies.threading) { case TP_ORB_CTRL: break; case TP_SINGLE_THREAD: pd_call_lock = new omni_rmutex(); break; case TP_MAIN_THREAD: pd_main_thread_sync.mu = new omni_tracedmutex(); pd_main_thread_sync.cond= new omni_tracedcondition(pd_main_thread_sync.mu); break; } // We assume that the policies given have been checked for validity. pd_policy = policies;}omniOrbPOA::omniOrbPOA() // nil constructor : OMNIORB_BASE_CTOR(PortableServer::)POA(1), omniObjAdapter(1), pd_destroyed(1), pd_dying(1), pd_refCount(0), pd_name((const char*) 0), pd_parent(0), pd_manager(0), pd_adapterActivator(0), pd_servantActivator(0), pd_servantLocator(0), pd_defaultServant(0), pd_rq_state(PortableServer::POAManager::INACTIVE), pd_poaIdSize(0), pd_deathSignal(&pd_lock), pd_oidIndex(0), pd_activeObjList(0), pd_oidPrefix(0){}voidomniOrbPOA::do_destroy(CORBA::Boolean etherealize_objects){ ASSERT_OMNI_TRACEDMUTEX_HELD(*omni::internalLock, 0); ASSERT_OMNI_TRACEDMUTEX_HELD(pd_lock, 0); ASSERT_OMNI_TRACEDMUTEX_HELD(poa_lock, 0); OMNIORB_ASSERT(pd_dying); PortableServer::POA_var child; while (1) { { omni_tracedmutex_lock sync(poa_lock); if (pd_children.length()) child = PortableServer::POA::_duplicate(pd_children[0]); else child = PortableServer::POA::_nil(); } if (!CORBA::is_nil(child)) { try { child->destroy(etherealize_objects, 1); } catch(CORBA::OBJECT_NOT_EXIST& ex) { // Race with another thread destroying a child POA. omni_thread::sleep(0, 100000000); } catch (...) { omniORB::logs(2, "Unexpected exception in do_destroy."); } } else { // No more children break; } } child = PortableServer::POA::_nil(); OMNIORB_ASSERT(pd_children.length() == 0); if( omniORB::trace(10) ) { omniORB::logger l; l << "Deactivating all POA(" << (char*) pd_name << ")'s objects.\n"; } // Deactivate all objects in the active object map. omniObjTableEntry* obj_list = 0; pd_lock.lock(); if( pd_activeObjList ) pd_activeObjList->reRootOAObjList(&obj_list); PortableServer::ServantActivator_ptr sa = pd_servantActivator; pd_lock.unlock(); omni::internalLock->lock(); deactivate_objects(obj_list); if( omniORB::trace(10) ) { omniORB::logger l; l << "Waiting for requests to complete on POA(" << (char*) pd_name << ").\n"; } pd_rq_state = (int) PortableServer::POAManager::INACTIVE; waitForAllRequestsToComplete(1); if( omniORB::trace(10) ) { omniORB::logger l; l << "Requests on POA(" << (char*) pd_name << ") completed.\n"; } complete_object_deactivation(obj_list); omni::internalLock->unlock(); // Apparent destruction of POA occurs before etherealisations. pd_lock.lock(); pd_destroyed = 1; PortableServer::Servant defaultServant = pd_defaultServant; pd_defaultServant = 0; if( omniORB::trace(10) ) { omniORB::logger l; l << "Etherealising POA(" << (char*) pd_name << ")'s objects.\n"; } // Signal so that any detached objects waiting to etherealise // can proceed. pd_deathSignal.broadcast(); pd_lock.unlock(); // Etherealise the objects. this->etherealise_objects(obj_list, etherealize_objects, sa); // Wait for objects which have been detached to complete their // etherealisations. wait_for_detached_objects(); if( defaultServant ) defaultServant->_remove_ref(); poa_lock.lock(); pd_lock.lock(); pd_destroyed = 2; if( pd_parent ) { pd_parent->lose_child(this); pd_parent = 0; if (theINSPOA == this) { if (theRootPOA) theRootPOA->decrRefCount(); theINSPOA = 0; } } else { OMNIORB_ASSERT(theRootPOA == this); theRootPOA = 0; } poa_lock.unlock(); pd_lock.unlock(); pd_deathSignal.broadcast(); try { adapterInactive(); } catch(...) {} if( omniORB::trace(10) ) { omniORB::logger l; l << "Destruction of POA(" << (char*) pd_name << ") complete.\n"; } adapterDestroyed(); CORBA::release(this);}voidomniOrbPOA::pm_change_state(PortableServer::POAManager::State new_state){ omni::internalLock->lock(); pd_rq_state = (int) new_state; omni::internalLock->unlock(); pd_signal->broadcast();}voidomniOrbPOA::pm_waitForReqCmpltnOrSttChnge(omniOrbPOAManager::State state){ ASSERT_OMNI_TRACEDMUTEX_HELD(*omni::internalLock, 0); // Wait until all outstanding requests have completed, // or until the state has changed. omni::internalLock->lock(); pd_signalOnZeroInvocations++; while( pd_rq_state == (int) state && pd_nReqActive ) pd_signal->wait(); pd_signalOnZeroInvocations--; omni::internalLock->unlock();}voidomniOrbPOA::pm_deactivate(_CORBA_Boolean etherealize_objects){ ASSERT_OMNI_TRACEDMUTEX_HELD(*omni::internalLock, 0); ASSERT_OMNI_TRACEDMUTEX_HELD(pd_lock, 0); pd_lock.lock(); if( pd_dying ) { // If being destroyed by another thread, then we just // have to wait until that completes. incrRefCount(); while( pd_destroyed != 2 ) pd_deathSignal.wait(); pd_lock.unlock(); decrRefCount(); return; } omniObjTableEntry* obj_list = 0; if( pd_activeObjList ) pd_activeObjList->reRootOAObjList(&obj_list); PortableServer::ServantActivator_ptr sa = pd_servantActivator; // We pretend to detach an object here, so that if some other // thread tries to destroy this POA, they will have to block // until we've finished etherealising these objects. if( obj_list ) detached_object(); pd_lock.unlock(); omni::internalLock->lock(); deactivate_objects(obj_list); waitForAllRequestsToComplete(1); complete_object_deactivation(obj_list); omni::internalLock->unlock(); if( obj_list ) { if( etherealize_objects ) this->etherealise_objects(obj_list, etherealize_objects, sa); met_detached_object(); wait_for_detached_objects(); }}void*omniOrbPOA::servant__this(PortableServer::Servant p_servant, const char* repoId){ CHECK_NOT_NIL(); OMNIORB_ASSERT(p_servant && repoId); if( !pd_policy.retain_servants || (pd_policy.multiple_id && !pd_policy.implicit_activation) ) throw WrongPolicy(); omni_tracedmutex_lock sync(pd_lock); CHECK_NOT_DESTROYED(); omni_tracedmutex_lock sync2(*omni::internalLock); if( !pd_policy.multiple_id ) { // Search the servants activations, to see if it is activated in // this poa. omnivector<omniObjTableEntry*>::const_iterator i, last; i = p_servant->_activations().begin(); last = p_servant->_activations().end(); for (; i != last; i++) { if ((*i)->adapter() == this) { OMNIORB_ASSERT(pd_poaIdSize == 0 || omni::ptrStrMatch(pd_poaId, (const char*) (*i)->key())); omniObjRef* objref = omni::createLocalObjRef(p_servant->_mostDerivedRepoId(), repoId, *i); OMNIORB_ASSERT(objref); return objref->_ptrToObjRef(repoId); } } } if( !pd_policy.implicit_activation ) throw WrongPolicy(); CHECK_NOT_DYING(); // If we get here, then we have the implicit activation policy, // and either the servant is not activated
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -