// -*- Mode: C++; -*- // Package : omniORB // omniObjRef.h Created on: 22/2/99 // Author : David Riddoch (djr) // // Copyright (C) 1996-1999 AT&T Research 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: // Base class for object references. // /* $Log: omniObjRef.h,v $ Revision 1.4.2.3 2006/07/18 16:21:24 dgrisby New experimental connection management extension; ORB core support for it. Revision 1.4.2.2 2005/11/09 12:22:18 dgrisby Local interfaces support. Revision 1.4.2.1 2003/03/23 21:04:12 dgrisby Start of omniORB 4.1.x development branch. Revision 1.2.2.12 2002/10/14 20:06:06 dgrisby Per objref / per thread timeouts. Revision 1.2.2.11 2001/11/12 13:46:07 dpg1 _unchecked_narrow, improved _narrow. Revision 1.2.2.10 2001/11/08 16:33:49 dpg1 Local servant POA shortcut policy. Revision 1.2.2.9 2001/09/19 17:26:43 dpg1 Full clean-up after orb->destroy(). Revision 1.2.2.8 2001/08/15 10:26:08 dpg1 New object table behaviour, correct POA semantics. Revision 1.2.2.7 2001/05/31 16:21:13 dpg1 object references optionally just store a pointer to their repository id string rather than copying it. Revision 1.2.2.6 2001/05/10 15:08:37 dpg1 _compatibleServant() replaced with _localServantTarget(). createIdentity() now takes a target string. djr's fix to deactivateObject(). Revision 1.2.2.5 2001/04/18 17:50:43 sll Big checkin with the brand new internal APIs. Scoped where appropriate with the omni namespace. Revision 1.2.2.4 2000/11/07 18:44:03 sll Renamed omniObjRef::_hash and _is_equivalent to __hash and __is_equivalent to avoid name clash with the member functions of CORBA::Object. Revision 1.2.2.3 2000/10/03 17:37:07 sll Changed omniIOR synchronisation mutex from omni::internalLock to its own mutex. Revision 1.2.2.2 2000/09/27 17:16:20 sll Replaced data member pd_iopProfiles with pd_ior which contains decoded members of the IOR. Removed _getRopeAndKey(), _getTheKey() and _iopProfiles(). Added new functions _getIOR(), _marshal(), _unMarshal(), _toString, _fromString(), _hash(), _is_equivalent(). Revision 1.2.2.1 2000/07/17 10:35:35 sll Merged from omni3_develop the diff between omni3_0_0_pre3 and omni3_0_0. Revision 1.3 2000/07/13 15:26:05 dpg1 Merge from omni3_develop for 3.0 release. Revision 1.1.2.4 2000/03/01 17:57:42 dpg1 New omniObjRef::_compatibleServant() function to support object references and servants written for languages other than C++. Revision 1.1.2.3 2000/02/22 12:25:38 dpg1 A few things made `publicly' accessible so omniORBpy can get its hands on them. Revision 1.1.2.2 1999/10/27 17:32:09 djr omni::internalLock and objref_rc_lock are now pointers. Revision 1.1.2.1 1999/09/24 09:51:48 djr Moved from omniORB2 + some new files. */ #ifndef __OMNIOBJREF_H__ #define __OMNIOBJREF_H__ OMNI_NAMESPACE_BEGIN(omni) class omniInternal; OMNI_NAMESPACE_END(omni) class omniIOR; class omniCallDescriptor; class omniIdentity; class omniLocalIdentity; class omniObjTableEntry; class omniRemoteIdentity; class omniServant; class omniObjRef { public: virtual void* _ptrToObjRef(const char* repoId) = 0; // The most derived class which overrides this virtual function will be // called to return a pointer to the object reference class identified by // . So for IDL type Echo, the returned pointer will be an // Echo_ptr. All object reference types should support widening to // CORBA::Object_ptr. // If this reference object cannot be widened to the class specified, a // null pointer will be returned. No attempt is made to contact the object // or create a new object refence of a more derived type. See _realNarrow. // must not be NULL. // This function does not throw any exceptions. // This function is thread-safe. virtual const char* _localServantTarget(); // Return a string which servant->_ptrToInterface() must accept for // the servant to be contacted with the local case optimisation. // This funtion is thread safe. inline const char* _mostDerivedRepoId() const { return pd_mostDerivedRepoId; } // The interface repository id of the most derived interface // supported by the object. May be the empty string '\0'. // This function is thread-safe. _CORBA_Boolean _real_is_a(const char* repoId); // Returns 1 if the object is really an instance of the type identified // by the IR repository ID . If the stub for the object type is // linked into the executable, the ORB can fully determine the _is_a // relation without the need to contact the object remotely. Otherwise, // contact the object implementation using _remote_is_a(). // This function is thread-safe. void* _realNarrow(const char* repoId); // If the actual type of the object can be narrowed to the requested // interface type identified by the IR repository ID , return // a valid object reference. Otherwise, return 0. The return value is // of type void* and can be casted to the T_ptr type of the interface // T directly. If necessary we contact the object itself to check the // inheritance relation. must be a type for which there exists // a proxy object factory. // This function is thread-safe. // Does not throw any exceptions. void* _uncheckedNarrow(const char* repoId); // Return a valid object reference to the interface type identified // by . We do not contact the object itself to check the // inheritance relation, so subsequent operations on this object may // fail because it actually does not implement the interface. This // function _always_ succeeds, no matter what interface we ask for. // must be a type for which there exists a proxy object // factory. // This function is thread-safe. // Does not throw any exceptions. void _assertExistsAndTypeVerified(); // If pd_flags.object_exists is zero, contact the object and verify // that it exists. // If pd_flags.type_verified is zero, ask the object if it supports // the interface we are exporting. // This function is thread-safe. _CORBA_Boolean _remote_is_a(const char* repoId); // Contacts the object implementation to determine whether it is an // instance of the type identified by . It is possible that // the implementation is a local servant of course. // May throw system exceptions. // This function is thread-safe. _CORBA_Boolean _remote_non_existent(); // Contacts to object implementation to determine whether it exists. // It is possible that the implementation is a local servant of course. // Returns 0 if the object exists, or 1 or throws OBJECT_NOT_EXIST if // not. May throw other system exceptions. // This function is thread-safe. void* _transientExceptionHandler(void*& cookie); // If a transientExceptionHandler_t has been installed for this object // by _transientExceptionHandler(void*,void*), returns this handler and its // associated opaque argument in cookie. // Otherwise return 0. // This function is thread-safe. void _transientExceptionHandler(void* new_handler, void* cookie); // Set the transientExceptionHandler_t of this object. By default, // i.e. when this function is not called for an object, the global // transientExceptionHandler_t will be invoked when a CORBA::TRANSIENT // exception is caught in a remote call from a proxy object. // The argument is an opaque argument that will be passed // to the exception handler. // This function is thread-safe. void* _commFailureExceptionHandler(void*& cookie); // If a commFailureExceptionHandler_t has been installed for this object // by _commFailureExceptionHandler(void*,void*), returns this handler and its // associated opaque argument in cookie. // Otherwise return 0. // This function is thread-safe. void _commFailureExceptionHandler(void* new_handler, void* cookie); // Set the commFailureExceptionHandler_t of this object. By default, // i.e. when this function is not called for an object, the global // commFailureExceptionHandler_t will be invoked when a CORBA::COMM_FAILURE // exception is caught in a remote call from a proxy object. // The argument is an opaque argument that will be passed // to the exception handler. // This function is thread-safe. void* _systemExceptionHandler(void*& cookie); // If a systemExceptionHandler_t has been installed for this object // by _systemExceptionHandler(void*,void*), returns this handler and its // associated opaque argument in cookie. // Otherwise return 0. // This function is thread-safe. void _systemExceptionHandler(void* new_handler, void* cookie); // Set the systemExceptionHandler_t of this object. By default, // i.e. when this function is not called for an object, the global // systemExceptionHandler_t will be invoked when a CORBA::SystemException // exception, other than CORBA::TRANSIENT and CORBA::COMM_FAILURE is caught // in a remote call from a proxy object. The handlers for CORBA::TRANSIENT // and CORBA::COMM_FAILURE are installed their own install functions. // The argument is an opaque argument that will be passed // to the exception handler. // This function is thread-safe. inline omniIdentity* _identity() { ASSERT_OMNI_TRACEDMUTEX_HELD(*omni::internalLock, 1); return pd_id; } // Must hold . inline int _isForwardLocation() const { ASSERT_OMNI_TRACEDMUTEX_HELD(*omni::internalLock, 1); return pd_flags.forward_location; } // Must hold . inline _CORBA_Boolean _is_nil() { return !pd_ior; } // This function is thread-safe. inline void _noExistentCheck() { pd_flags.type_verified = 1; pd_flags.object_exists = 1; } // This function instructs the ORB to skip the existence test // performed in _assertExistsAndTypeVerified(). // Really ought to only call this if you know no-one else // is accessing this reference, or holding . _CORBA_Boolean __is_equivalent(omniObjRef* other_obj); // Returns true if this and the other_obj is equivalent. In other // words, they both have the same object key and in the same address space. // Caller must not hold // other_obj must not be nil. // This function is thread-safe. _CORBA_ULong __hash(_CORBA_ULong maximum); // Returns the result of passing the object key through the ORB's hash // function. The return value is not larger than maximum. // Caller must not hold // This function is thread-safe. void _invoke(omniCallDescriptor&, _CORBA_Boolean do_assert=1); // Does the client-side work of making a request. Dispaches // the call to the object identity, and deals with exception // handlers, retries and location forwarding. omniIOR* _getIOR(); // Returns an omniIOR. The object contains all the fields in // the IOR of the object reference. The object is read-only // and shouldn't be modified. The returned object should be // released by calling its release() method. This // function is atomic and thread-safe. static void _marshal(omniObjRef*, cdrStream&); // Marshal this object reference to the cdrStream. static omniObjRef* _unMarshal(const char* repoId, cdrStream& s); // Unmarshal from the cdrStream an object reference. The // object reference is expected to implement the interface identified // by the repository ID . static char* _toString(omniObjRef*); static omniObjRef* _fromString(const char*); void _setIdentity(omniIdentity* id); // Set or change the identity to dispatch to. // Must hold . static void _shutdown(); // Called during ORB shutdown. Disables all object references. // Must not hold . virtual void _enableShortcut(omniServant* svt, const _CORBA_Boolean* invalid); // If is non-zero, it is a local activated servant. This // function is called by an object adapter to indicate that it is // acceptable to make future calls directly to the servant, avoiding // the object adapter. If the boolean pointed to by // becomes true, the servant is no longer valid and a normal // dispatch through _invoke() should be made. A zero pointer // indicates that the shortcut can no longer be made. This mechanism // has obvious race conditions, but that's the price you pay for // speed. // No concurrency control! inline void _setTimeout(unsigned long secs, unsigned long ns) { pd_timeout_secs = secs; pd_timeout_nanosecs = ns; } protected: virtual ~omniObjRef(); // Must not hold . omniObjRef(); // Constructor for nil object references. No operations should // be invoked on nil object references. This should be tested // in the public interface. omniObjRef(const char* intfRepoId, omniIOR* ior, omniIdentity* id, _CORBA_Boolean static_repoId = 0); // Constructed with an initial ref count of 1. If // is true, assumes that the string will remain valid // for the entire life time of the objref, meaning that there is no // need to copy it. void _locateRequest(); // Issues a GIOP LocateRequest. Throws OBJECT_NOT_EXIST, or // returns normally if the object does exist. // This function is thread-safe. private: omniObjRef(const omniObjRef&); omniObjRef& operator = (const omniObjRef&); // Not implemented. void _disable(); // Disable the object reference so all future invocations throw BAD_INV_ORDER // Must hold . /////////////////////////////////////////////// // Some friends need to access the internals // /////////////////////////////////////////////// friend class _OMNI_NS(omniInternal); friend class omniPy; friend void omni::duplicateObjRef(omniObjRef*); friend void omni::releaseObjRef(omniObjRef*); friend omniObjRef* omni::createObjRef(const char*,omniIOR*, _CORBA_Boolean,omniIdentity*); friend omniObjRef* omni::createLocalObjRef(const char*, const char*, omniObjTableEntry*, const omniIORHints&); friend void omni::revertToOriginalProfile(omniObjRef*); friend void omni::locationForward(omniObjRef*, omniObjRef*, _CORBA_Boolean); ////////////////// // Data members // ////////////////// int pd_refCount; // Protected by . char* pd_mostDerivedRepoId; // The interface repository id that we have been told is the // most derived interface of the object implementation. This // may be the same as the static type of this reference, or // it may be wrong (if the implementation has been replaced // by one of a more derived type), or it may be '\0' (if the // IOR contained no repoId). // Immutable. char* pd_intfRepoId; // The repository id of the interface that this reference is // presenting. That is, if this is a c++ , then this // will be the repository id for . Thus for an anonymous // object reference, this is the CORBA::Object repoId. Clearly // _ptrToObjRef(pd_intfRepoId) must be non-zero! // This may or may not be equal to , // but unlike it may *not* be the empty // string. // Immutable. omniIOR* pd_ior; // The decoded IOR of this object reference. // Mutable. Protected by . omniIdentity* pd_id; // An encapsulation of the current implementation of this // object. Either a local object, or the location and // key of a remote object. // Mutable. Protected by . omniObjRef* pd_next; omniObjRef** pd_prev; // Doubly linked list of all non-nil object references, so they may // be disabled at ORB shutdown. // Protected by . struct { unsigned forward_location : 1; // True if we have had a LOCATION_FORWARD. In this case the // identity (pd_id) is not the same as the one referred to in the // iop profiles. unsigned type_verified : 1; // True if we believe that the object implementation supports // the interface . If this is zero then we // must contact the object to confirm that it supports this // interface before making any invocations. unsigned object_exists : 1; // True if we have asked the object if it exists, and it says // yes. This is set to zero in the constructor, so that we // will contact the object and check that it exists before the // very first invocation. unsigned transient_exception_handler : 1; unsigned commfail_exception_handler : 1; unsigned system_exception_handler : 1; // True if a per-object exception handler has been installed // for this reference. unsigned static_repoId : 1; // True if pd_intfRepoId is static and should not be deleted when // this objref is destroyed. unsigned orb_shutdown : 1; // True if the ORB that created this objref has been shut down. } pd_flags; // Mutable. Protected by . unsigned long pd_timeout_secs; unsigned long pd_timeout_nanosecs; }; #endif // __OMNIOBJREF_H__