📄 omniobjref.cc
字号:
} if( !_omni_callTransientExceptionHandler(this, retries++, ex2) ) OMNIORB_THROW(TRANSIENT,ex2.minor(),ex2.completed()); } omni::locationForward(this,ex.get_obj()->_PR_getobj(),ex.is_permanent()); } }}omniIOR* omniObjRef::_getIOR(){ omni_tracedmutex_lock sync(*omniIOR::lock); // Must hold mutex before reading pd_ior. return pd_ior->duplicateNoLock();}voidomniObjRef::_marshal(omniObjRef* objref, cdrStream& s){ if (!objref || objref->_is_nil()) { ::operator>>= ((CORBA::ULong)1,s); s.marshalOctet('\0'); ::operator>>= ((CORBA::ULong) 0,s); return; } if (objref->pd_flags.orb_shutdown) OMNIORB_THROW(BAD_INV_ORDER, BAD_INV_ORDER_ORBHasShutdown, (CORBA::CompletionStatus)s.completion()); omniIOR_var ior; { omni_tracedmutex_lock sync(*omniIOR::lock); // Must hold mutex before reading pd_ior. ior = objref->pd_ior->duplicateNoLock(); } s.marshalRawString(ior->repositoryID()); (const IOP::TaggedProfileList&)ior->iopProfiles() >>= s; // Provide interim BiDir GIOP support. If this is a giopStream and this // is the client side of a bidirectional stream, mark the stream to // indicate that an object reference has been sent to the other end. // We assume all these references are callback objects. // The reason for doing so is that if subsequently this connection is // broken, the callback objects would not be able to callback to us. // We want the application to know about this. giopStream* gs = giopStream::downcast(&s); if (gs) { giopStrand& g = (giopStrand&)*gs; if (g.biDir && g.isClient()) { g.biDir_has_callbacks = 1; } }}char*omniObjRef::_toString(omniObjRef* objref){ cdrMemoryStream buf(CORBA::ULong(0),CORBA::Boolean(1)); buf.marshalOctet(omni::myByteOrder); _marshal(objref,buf); // turn the encapsulation into a hex string with "IOR:" prepended buf.rewindInputPtr(); size_t s = buf.bufSize(); CORBA::Char * data = (CORBA::Char *)buf.bufPtr(); char *result = new char[4+s*2+1]; result[4+s*2] = '\0'; result[0] = 'I'; result[1] = 'O'; result[2] = 'R'; result[3] = ':'; for (int i=0; i < (int)s; i++) { int j = 4 + i*2; int v = (data[i] & 0xf0); v = v >> 4; if (v < 10) result[j] = '0' + v; else result[j] = 'a' + (v - 10); v = ((data[i] & 0xf)); if (v < 10) result[j+1] = '0' + v; else result[j+1] = 'a' + (v - 10); } return result;}omniObjRef*omniObjRef::_unMarshal(const char* repoId, cdrStream& s){ CORBA::String_var id; IOP::TaggedProfileList_var profiles; id = IOP::IOR::unmarshaltype_id(s); profiles = new IOP::TaggedProfileList(); (IOP::TaggedProfileList&)profiles <<= s; if (profiles->length() == 0 && strlen(id) == 0) { // This is a nil object reference return 0; } // It is possible that we reach here with the id string = '\0'. // That is alright because the actual type of the object will be // verified using _is_a() at the first invocation on the object. // // Apparently, some ORBs such as ExperSoft's do that. Furthermore, // this has been accepted as a valid behaviour in GIOP 1.1/IIOP 1.1. // omniIOR* ior = new omniIOR(id._retn(),profiles._retn()); // Provide interim BiDir GIOP support. Check the stream where this IOR // comes from. If it is a giopStream and this is the server side of // a bidirectional stream, add the component tag TAG_OMNIORB_BIDIR to the // ior's IOP profile list. The component will be decoded in createObjRef. // // In the next revision to bidir giop, as documented in OMG doc. 2001-06-04 // and if it ever gets adopted in a future GIOP version, the tag component // TAG_BI_DIR_GIOP will be embedded in the IOR and this step will be // redundent. giopStream* gs = giopStream::downcast(&s); if (gs) { giopStrand& g = (giopStrand&)*gs; if (g.biDir && !g.isClient()) { // Check the POA policy to see if the servant's POA is willing // to use bidirectional on its callback objects. omniCurrent* current = omniCurrent::get(); omniCallDescriptor* desc = ((current)? current->callDescriptor() : 0); if (desc && desc->poa() && desc->poa()->acceptBiDirectional()) { const char* sendfrom = g.connection->peeraddress(); omniIOR::add_TAG_OMNIORB_BIDIR(sendfrom,*ior); } } } omniObjRef* objref = omni::createObjRef(repoId,ior,0); return objref;}omniObjRef*omniObjRef::_fromString(const char* str){ size_t s = (str ? strlen(str) : 0); if (s<4) OMNIORB_THROW(MARSHAL,MARSHAL_InvalidIOR,CORBA::COMPLETED_NO); const char *p = str; if (!((p[0] == 'I' || p[0] == 'i') && (p[1] == 'O' || p[1] == 'o') && (p[2] == 'R' || p[2] == 'r') && (p[3] == ':'))) OMNIORB_THROW(MARSHAL,MARSHAL_InvalidIOR,CORBA::COMPLETED_NO); s = (s-4)/2; // how many octets are there in the string p += 4; cdrMemoryStream buf((CORBA::ULong)s,0); for (int i=0; i<(int)s; i++) { int j = i*2; CORBA::Octet v=0; if (p[j] >= '0' && p[j] <= '9') { v = ((p[j] - '0') << 4); } else if (p[j] >= 'a' && p[j] <= 'f') { v = ((p[j] - 'a' + 10) << 4); } else if (p[j] >= 'A' && p[j] <= 'F') { v = ((p[j] - 'A' + 10) << 4); } else OMNIORB_THROW(MARSHAL,MARSHAL_InvalidIOR,CORBA::COMPLETED_NO); if (p[j+1] >= '0' && p[j+1] <= '9') { v += (p[j+1] - '0'); } else if (p[j+1] >= 'a' && p[j+1] <= 'f') { v += (p[j+1] - 'a' + 10); } else if (p[j+1] >= 'A' && p[j+1] <= 'F') { v += (p[j+1] - 'A' + 10); } else OMNIORB_THROW(MARSHAL,MARSHAL_InvalidIOR,CORBA::COMPLETED_NO); buf.marshalOctet(v); } buf.rewindInputPtr(); CORBA::Boolean b = buf.unmarshalBoolean(); buf.setByteSwapFlag(b); return _unMarshal(CORBA::Object::_PD_repoId,buf);}voidomniObjRef::_locateRequest(){ int retries = 0;#if defined(__DECCXX) && __DECCXX_VER < 60300000 // Work-around for bug in Compaq C++ optimiser volatile#endif int fwd = 0; if( _is_nil() ) _CORBA_invoked_nil_objref(); omniCallDescriptor dummy_calldesc(0,0,0,0,0,0,0); omniCurrent* current; unsigned long abs_secs = 0, abs_nanosecs = 0; if (pd_timeout_secs || pd_timeout_nanosecs) { omni_thread::get_time(&abs_secs,&abs_nanosecs, pd_timeout_secs, pd_timeout_nanosecs); } else if (orbParameters::supportPerThreadTimeOut && (current = omniCurrent::get()) && (current->timeout_secs() || current->timeout_nanosecs())) { if (current->timeout_absolute()) { abs_secs = current->timeout_secs(); abs_nanosecs = current->timeout_nanosecs(); } else { omni_thread::get_time(&abs_secs,&abs_nanosecs, current->timeout_secs(), current->timeout_nanosecs()); } } else if (orbParameters::clientCallTimeOutPeriod.secs || orbParameters::clientCallTimeOutPeriod.nanosecs) { omni_thread::get_time(&abs_secs,&abs_nanosecs, orbParameters::clientCallTimeOutPeriod.secs, orbParameters::clientCallTimeOutPeriod.nanosecs); } if (abs_secs || abs_nanosecs) dummy_calldesc.setDeadline(abs_secs,abs_nanosecs); while(1) { try{ omni::internalLock->lock(); if( omniObjTableEntry::downcast(pd_id) ) { // Its a local activated object, and we know its here. omni::internalLock->unlock(); return; } fwd = pd_flags.forward_location; _identity()->locateRequest(dummy_calldesc); return; } catch(const giopStream::CommFailure& ex) { if (ex.retry()) continue; if( fwd ) { RECOVER_FORWARD; continue; } if (is_COMM_FAILURE_minor(ex.minor())) { CORBA::COMM_FAILURE ex2(ex.minor(), ex.completed()); if( !_omni_callCommFailureExceptionHandler(this, retries++, ex2) ) throw ex2; } else { CORBA::TRANSIENT ex2(ex.minor(), ex.completed()); if( !_omni_callTransientExceptionHandler(this, retries++, ex2) ) throw ex2; } } catch(CORBA::COMM_FAILURE& ex) { if( fwd ) { RECOVER_FORWARD; continue; } if( !_omni_callCommFailureExceptionHandler(this, retries++, ex) ) throw; } catch(CORBA::TRANSIENT& ex) { if( !_omni_callTransientExceptionHandler(this, retries++, ex) ) throw; } catch(CORBA::OBJECT_NOT_EXIST& ex) { if( fwd ) { RECOVER_FORWARD; continue; } if( !_omni_callSystemExceptionHandler(this, retries++, ex) ) throw; } catch(CORBA::SystemException& ex) { if( !_omni_callSystemExceptionHandler(this, retries++, ex) ) throw; } catch(omniORB::LOCATION_FORWARD& ex) { if( CORBA::is_nil(ex.get_obj()) ) { CORBA::TRANSIENT ex2(TRANSIENT_NoUsableProfile, CORBA::COMPLETED_NO); if( omniORB::traceLevel > 10 ){ omniORB::logger log; log << "Received GIOP::LOCATION_FORWARD message that" " contains a nil object reference.\n"; } if( !_omni_callTransientExceptionHandler(this, retries++, ex2) ) throw ex2; } omni::locationForward(this,ex.get_obj()->_PR_getobj(),ex.is_permanent()); } }}voidomniObjRef::_setIdentity(omniIdentity* id){ ASSERT_OMNI_TRACEDMUTEX_HELD(*omni::internalLock, 1); if (id != pd_id) { if (pd_id) pd_id->loseRef(this); pd_id = id; if (pd_id) pd_id->gainRef(this); }}voidomniObjRef::_enableShortcut(omniServant*, const _CORBA_Boolean*){ // Default does nothing}OMNI_NAMESPACE_BEGIN(omni)/////////////////////////////////////////////////////////////////////////////// Handlers for Configuration Options ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////class verifyObjectExistsAndTypeHandler : public orbOptions::Handler {public: verifyObjectExistsAndTypeHandler() : orbOptions::Handler("verifyObjectExistsAndType", "verifyObjectExistsAndType = 0 or 1", 1, "-ORBverifyObjectExistsAndType < 0 | 1 >") {} void visit(const char* value,orbOptions::Source) throw (orbOptions::BadParam) { CORBA::Boolean v; if (!orbOptions::getBoolean(value,v)) { throw orbOptions::BadParam(key(),value, orbOptions::expect_boolean_msg); } orbParameters::verifyObjectExistsAndType = v; } void dump(orbOptions::sequenceString& result) { orbOptions::addKVBoolean(key(),orbParameters::verifyObjectExistsAndType, result); }};static verifyObjectExistsAndTypeHandler verifyObjectExistsAndTypeHandler_;/////////////////////////////////////////////////////////////////////////////// Module initialiser ///////////////////////////////////////////////////////////////////////////////class omni_ObjRef_initialiser : public omniInitialiser {public: omni_ObjRef_initialiser() { orbOptions::singleton().registerHandler(verifyObjectExistsAndTypeHandler_); } void attach() { } void detach() { }};static omni_ObjRef_initialiser initialiser;omniInitialiser& omni_ObjRef_initialiser_ = initialiser;OMNI_NAMESPACE_END(omni)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -