⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 giopbidir.cc

📁 编译工具
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- Mode: C++; -*-//                            Package   : omniORB2// giopBiDir.cc               Created on: 17/7/2001//                            Author    : Sai Lai Lo (sll)////    Copyright (C) 2001 AT&T Laboratories Cambridge////    This file is part of the omniORB library////    The omniORB library is free software; you can redistribute it and/or//    modify it under the terms of the GNU Library General Public//    License as published by the Free Software Foundation; either//    version 2 of the License, or (at your option) any later version.////    This library is distributed in the hope that it will be useful,//    but WITHOUT ANY WARRANTY; without even the implied warranty of//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU//    Library General Public License for more details.////    You should have received a copy of the GNU Library General Public//    License along with this library; if not, write to the Free//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA//    02111-1307, USA////// Description://	*** PROPRIETORY INTERFACE ***///*  $Log: giopBiDir.cc,v $  Revision 1.1.2.20  2005/03/02 13:25:39  dgrisby  Variable name clash.  Revision 1.1.2.19  2005/01/29 17:25:03  dgrisby  Memory leaks in bidir connection management.  Revision 1.1.2.18  2004/10/18 00:23:54  dgrisby  Bug in trying to set up bidirectional GIOP with GIOP 1.0 and 1.1.  Revision 1.1.2.17  2004/05/25 16:25:18  dgrisby  Typo in bidir changes.  Revision 1.1.2.16  2004/05/25 14:02:22  dgrisby  Properly close bidirectional connections.  Revision 1.1.2.15  2003/02/03 16:53:14  dgrisby  Force type in constructor argument to help confused compilers.  Revision 1.1.2.14  2002/11/26 14:51:50  dgrisby  Implement missing interceptors.  Revision 1.1.2.13  2002/08/23 14:15:02  dgrisby  Avoid exception with bidir when no POA.  Revision 1.1.2.12  2002/08/21 06:23:15  dgrisby  Properly clean up bidir connections and ropes. Other small tweaks.  Revision 1.1.2.11  2002/01/16 11:31:59  dpg1  Race condition in use of registerNilCorbaObject/registerTrackedObject.  (Reported by Teemu Torma).  Revision 1.1.2.10  2001/11/08 16:31:19  dpg1  Minor tweaks.  Revision 1.1.2.9  2001/09/19 17:26:49  dpg1  Full clean-up after orb->destroy().  Revision 1.1.2.8  2001/09/10 17:45:22  sll  Call stopIdleCounter when a strand is switched to bidirectional in  getBiDirServiceContext.  Revision 1.1.2.7  2001/09/03 17:32:05  sll  Make sure that acquireClient honours the deadline set in the calldescriptor.  Revision 1.1.2.6  2001/08/29 17:52:03  sll  Consult serverTransportRule to decide whether to accept the switch to  bidirectional on the server side.  Revision 1.1.2.5  2001/08/23 10:11:53  sll  Initialise BiDirPolicy constants properly for compilers with no namespace  support.  Revision 1.1.2.4  2001/08/21 11:02:14  sll  orbOptions handlers are now told where an option comes from. This  is necessary to process DefaultInitRef and InitRef correctly.  Revision 1.1.2.3  2001/08/17 17:12:36  sll  Modularise ORB configuration parameters.  Revision 1.1.2.2  2001/07/31 17:31:40  sll  strchr returns const char*.  Revision 1.1.2.1  2001/07/31 16:10:38  sll  Added GIOP BiDir support.  */#include <omniORB4/CORBA.h>#include <omniORB4/minorCode.h>#include <omniORB4/omniInterceptors.h>#include <omniORB4/objTracker.h>#include <exceptiondefs.h>#include <giopStrand.h>#include <giopRope.h>#include <giopBiDir.h>#include <giopStreamImpl.h>#include <giopStream.h>#include <GIOP_C.h>#include <GIOP_S.h>#include <giopServer.h>#include <initialiser.h>#include <objectAdapter.h>#include <tcp/tcpTransportImpl.h>#include <orbOptions.h>#include <orbParameters.h>#include <transportRules.h>OMNI_USING_NAMESPACE(omni)// XXX To-do// a) BiDirServerRope garbage collection. At the moment, the server//    side of a bidirectional connection is garbage collected in//    the same way as an ordinary connection. That is, it is closed after//    a period of inactivity. In fact, the connection should only be closed//    if all the object references unmarshal from the connection have//    been released. In other words, the reference count on the//    BiDirServerRope instance attached to the connection == 0.//////////////////////////////////////////////////////////////////////////////             Configuration options                                      //////////////////////////////////////////////////////////////////////////////CORBA::Boolean orbParameters::acceptBiDirectionalGIOP = 0;//   Applies to the server side. Set to 1 to indicates that the//   ORB may choose to accept a clients offer to use bidirectional//   GIOP calls on a connection. Set to 0 means the ORB should//   never accept any bidirectional offer and should stick to normal//   GIOP.////   Valid values = 0 or 1CORBA::Boolean orbParameters::offerBiDirectionalGIOP = 0;//   Applies to the client side. Set to 1 to indicates that the//   ORB may choose to use a connection to do bidirectional GIOP//   calls. Set to 0 means the ORB should never do bidirectional.////   Valid values = 0 or 1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#if defined(HAS_Cplusplus_Namespace) && defined(_MSC_VER)// MSVC++ does not give the variables external linkage otherwise. Its a bug.namespace BiDirPolicy {_init_in_def_( const CORBA::PolicyType	       BIDIRECTIONAL_POLICY_TYPE = 37; )_init_in_def_( const BidirectionalPolicyValue                NORMAL = 0; )_init_in_def_( const BidirectionalPolicyValue                BOTH = 1; )}#else_init_in_def_( const CORBA::PolicyType	       BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE = 37; )_init_in_def_( const BiDirPolicy::BidirectionalPolicyValue                BiDirPolicy::NORMAL = 0; )_init_in_def_( const BiDirPolicy::BidirectionalPolicyValue                BiDirPolicy::BOTH = 1; )#endifBiDirPolicy::BidirectionalPolicy::~BidirectionalPolicy() {}CORBA::Policy_ptrBiDirPolicy::BidirectionalPolicy::copy(){  if( _NP_is_nil() )  _CORBA_invoked_nil_pseudo_ref();  return new BidirectionalPolicy(pd_value);}void*BiDirPolicy::BidirectionalPolicy::_ptrToObjRef(const char* repoId){  OMNIORB_ASSERT(repoId );  if( omni::ptrStrMatch(repoId, BiDirPolicy::BidirectionalPolicy::_PD_repoId) )    return (BiDirPolicy::BidirectionalPolicy_ptr) this;  if( omni::ptrStrMatch(repoId, CORBA::Policy::_PD_repoId) )    return (CORBA::Policy_ptr) this;  if( omni::ptrStrMatch(repoId, CORBA::Object::_PD_repoId) )    return (CORBA::Object_ptr) this;  return 0;}BiDirPolicy::BidirectionalPolicy_ptrBiDirPolicy::BidirectionalPolicy::_duplicate(BiDirPolicy::BidirectionalPolicy_ptr obj){  if( !CORBA::is_nil(obj) )  obj->_NP_incrRefCount();  return obj;}BiDirPolicy::BidirectionalPolicy_ptrBiDirPolicy::BidirectionalPolicy::_narrow(CORBA::Object_ptr obj){  if( CORBA::is_nil(obj) )  return _nil();  BidirectionalPolicy_ptr p = (BidirectionalPolicy_ptr) obj->_ptrToObjRef(BidirectionalPolicy::_PD_repoId);  if( p )  p->_NP_incrRefCount();  return p ? p : _nil();}BiDirPolicy::BidirectionalPolicy_ptrBiDirPolicy::BidirectionalPolicy::_nil(){  static BidirectionalPolicy* _the_nil_ptr = 0;  if( !_the_nil_ptr ) {    omni::nilRefLock().lock();    if( !_the_nil_ptr ) {      _the_nil_ptr = new BidirectionalPolicy;      registerNilCorbaObject(_the_nil_ptr);    }    omni::nilRefLock().unlock();  }  return _the_nil_ptr;}const char*BiDirPolicy::BidirectionalPolicy::_PD_repoId = "IDL:omg.org/BiDirPolicy/BidirectionalPolicy:1.0";////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////OMNI_NAMESPACE_BEGIN(omni)////////////////////////////////////////////////////////////////////////typedef _CORBA_Unbounded_Sequence<IIOP::Address> ListenPointList;////////////////////////////////////////////////////////////////////////RopeLink BiDirServerRope::ropes;////////////////////////////////////////////////////////////////////////BiDirServerRope::BiDirServerRope(giopStrand* strand, giopAddress* addr) :   giopRope(addr,0),   pd_sendfrom((const char*)strand->connection->peeraddress()) {  pd_maxStrands = 1;  pd_oneCallPerConnection = 0;  strand->RopeLink::insert(pd_strands);}////////////////////////////////////////////////////////////////////////BiDirServerRope::~BiDirServerRope(){  giopAddressList::const_iterator i, last;  i    = pd_redirect_addresses.begin();  last = pd_redirect_addresses.end();  for (; i != last; i++) {    delete (*i);  }}////////////////////////////////////////////////////////////////////////BiDirServerRope*BiDirServerRope::addRope(giopStrand* strand, const giopAddressList& addrlist) {  ASSERT_OMNI_TRACEDMUTEX_HELD(*omniTransportLock,1);  OMNIORB_ASSERT(!strand->isClient() && strand->biDir == 1);  const char* sendfrom = strand->connection->peeraddress();  BiDirServerRope* br = 0;  // Check if there already exists a rope for the strand.  RopeLink* p = BiDirServerRope::ropes.next;  while ( p != &BiDirServerRope::ropes ) {    br = (BiDirServerRope*)p;    if (strcmp(sendfrom,br->pd_sendfrom) == 0) {      break;    }    else if (br->pd_refcount == 0 &&	     RopeLink::is_empty(br->pd_strands) &&	     !br->pd_nwaiting) {      // garbage rope, remove it      p = p->next;      br->RopeLink::remove();      delete br;    }    else {      p = p->next;    }    br = 0;  }  if (!br) {    giopAddress* addr = giopAddress::str2Address(strand->connection->peeraddress());    br = new BiDirServerRope(strand,addr);    br->RopeLink::insert(BiDirServerRope::ropes);  }  giopAddressList::const_iterator i, last;  i    = addrlist.begin();  last = addrlist.end();  for (; i != last; i++) {    CORBA::Boolean matched = 0;    giopAddressList::const_iterator j, k;    j = br->pd_redirect_addresses.begin();    k = br->pd_redirect_addresses.end();    for (; j != k; j++) {      if (omni::ptrStrMatch((*i)->address(),(*j)->address())) {	matched = 1;	break;      }    }    if (!matched) {      giopAddress* a = (*i)->duplicate();      br->pd_redirect_addresses.push_back(a);    }  }  return br;}////////////////////////////////////////////////////////////////////////intBiDirServerRope::selectRope(const giopAddressList& addrlist,			    omniIOR::IORInfo* info,			    Rope*& r) {  ASSERT_OMNI_TRACEDMUTEX_HELD(*omniTransportLock,1);  const char* sendfrom = 0;  omniIOR::IORExtraInfoList& cinfo = info->extraInfo();  for (CORBA::ULong index = 0; index < cinfo.length(); index++) {    if (cinfo[index]->compid == IOP::TAG_OMNIORB_BIDIR) {      sendfrom = ((BiDirInfo*)cinfo[index])->sendfrom;      break;    }  }  if (!sendfrom) return 0;  GIOP::Version v = info->version();  // Only GIOP 1.2 IORs can do bidirectional calls.  if (v.major != 1 || v.minor < 2) return 0;  BiDirServerRope* br;  RopeLink* p = BiDirServerRope::ropes.next;  while ( p != &BiDirServerRope::ropes ) {    br = (BiDirServerRope*)p;    if (br->match(sendfrom,addrlist)) {      br->realIncrRefCount();      r = (Rope*)br;      return 1;    }    else if (br->pd_refcount == 0 &&	     RopeLink::is_empty(br->pd_strands) &&	     !br->pd_nwaiting) {      // garbage rope, remove it      p = p->next;      br->RopeLink::remove();      delete br;    }    else {      p = p->next;    }  }  // Reach here because we cannot find a match.  return 0;}////////////////////////////////////////////////////////////////////////CORBA::BooleanBiDirServerRope::match(const char* sendfrom,		       const giopAddressList& addrlist) const {  if (strcmp(pd_sendfrom,sendfrom) != 0) return 0;  giopAddressList::const_iterator i, last;  i    = addrlist.begin();  last = addrlist.end();  for (; i != last; i++) {    giopAddressList::const_iterator j, k;    j = pd_redirect_addresses.begin();    k = pd_redirect_addresses.end();    for (; j != k; j++) {      if (omni::ptrStrMatch((*i)->address(),(*j)->address())) return 1;    }  }  return 0;}////////////////////////////////////////////////////////////////////////IOP_C*BiDirServerRope::acquireClient(const omniIOR* ior,			       const CORBA::Octet* key,			       CORBA::ULong keysize,			       omniCallDescriptor* calldesc) {  GIOP::Version v = ior->getIORInfo()->version();  giopStreamImpl* impl = giopStreamImpl::matchVersion(v);  if (!impl) {    impl = giopStreamImpl::maxVersion();    v = impl->version();  }  // Only use this connection to do calls with GIOP 1.2 or above.  OMNIORB_ASSERT(v.major > 1 || v.minor >= 2);  ASSERT_OMNI_TRACEDMUTEX_HELD(*omniTransportLock,0);  omni_tracedmutex_lock sync(*omniTransportLock);  OMNIORB_ASSERT(!pd_oneCallPerConnection && pd_maxStrands == 1);  giopStrand* s = 0;  if (pd_strands.next != &pd_strands) {    s = (giopStrand*)(pd_strands.next);  }  if (!s ||  s->state() == giopStrand::DYING) {    // We no longer have a working bidirectional connection.    OMNIORB_THROW(TRANSIENT,TRANSIENT_BiDirConnIsGone,CORBA::COMPLETED_NO);  }  OMNIORB_ASSERT(s->state() == giopStrand::ACTIVE);  // We do not check what GIOP version(s) the strand has been used for  // previously.  If ever we have 2 calls using 2 different versions  // (and both are 1.2 or above), we allow this to happen. Contrast  // this with the algorithm in giopRope::acquireClient.  GIOP_C* g;  if (!giopStreamList::is_empty(s->clients)) {    giopStreamList* gp = s->clients.next;    for (; gp != &s->clients; gp = gp->next) {      g = (GIOP_C*)gp;      if (g->state() == IOP_C::UnUsed) {	g->impl(impl);	g->initialise(ior,key,keysize,calldesc);	return g;      }    }

⌨️ 快捷键说明

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