// -*- c++ -*- /* * MICO --- an Open Source CORBA implementation * Copyright (c) 1997-2019 by The Mico Team * * This 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., 675 Mass Ave, Cambridge, MA 02139, USA. * * For more information, visit the MICO Home Page at * http://www.mico.org/ */ #ifndef __mico_orb_mico_h__ #define __mico_orb_mico_h__ #ifndef HAVE_THREADS # define USE_ORB_CACHE #endif namespace CORBA { class ObjectAdapter; //class ORBRequest; struct ORBCallback; typedef ORBRequest *ORBRequest_ptr; typedef ObjVar ORBRequest_var; typedef ObjOut ORBRequest_out; class PrincipalCurrent_impl : public CORBA::PrincipalCurrent { public: CORBA::Principal_ptr get_principal (); }; class ORBInvokeRec : public ServerlessObject { public: typedef ULong MsgId; private: MsgId _myid; RequestType _type; Boolean _have_result; Boolean _active; Object_ptr _obj; Object_ptr _target; Principal_ptr _principal; Boolean _response_expected; std::string _repoid; InvokeStatus _invoke_stat; LocateStatus _locate_stat; ObjectAdapter *_adapter; // Do not do any memory management on _req! On client side this is // just a `this' pointer pointing to object allocated on stack! // i.e. see _stub::, there is a // StaticRequest __req object which is passed this way // So server side needs to deal with this on its own ORBRequest *_req; ORBCallback *_cb; Boolean _cb_async_callback; ORB_ptr _orb; OctetSeq _objtag; Address *_addr; void *_req_hint; void *_inv_hint; GIOP::AddressingDisposition _ad; PInterceptor::ServerRequestInfo_impl* _sri; #ifdef USE_MESSAGING ULong relative_roundtrip_timeout_; Boolean timedout_; #endif // USE_MESSAGING public: ORBInvokeRec (MsgId); virtual ~ORBInvokeRec (); void free(); void init_invoke (ORB_ptr, Object_ptr target, ORBRequest *, Principal_ptr pr, Boolean response_expected, ORBCallback *, ObjectAdapter * = 0); void init_locate (ORB_ptr, Object_ptr, ORBCallback *, ObjectAdapter * = 0); void init_bind (ORB_ptr, const char *, const OctetSeq &tag, Address *, ORBCallback *, ObjectAdapter * = 0); void set_request_hint(void *hint) { _req_hint = hint; } void *get_request_hint() { return _req_hint; } void set_invoke_hint(void *hint) { _inv_hint = hint; } void *get_invoke_hint() { return _inv_hint; } Boolean active() const { return _active; }; void deactivate() { _active = FALSE; }; MsgId id () const { return _myid; } Boolean completed () const { return _have_result; } ObjectAdapter *oa () { return _adapter; } void oa (ObjectAdapter *oaval) { _adapter = oaval; } RequestType request_type () { return _type; } ORBRequest *request () { return _req; } const OctetSeq &tag () const { return _objtag; } ORBCallback *callback () { return _cb; } Principal_ptr principal () { return _principal; } PInterceptor::ServerRequestInfo_impl* requestinfo() { return _sri; } CORBA::Boolean response_expected() { return _response_expected; } void redo (); void set_answer_invoke (InvokeStatus, Object_ptr, ORBRequest *, GIOP::AddressingDisposition); void set_answer_bind (LocateStatus, Object_ptr); void set_answer_locate (LocateStatus, Object_ptr, GIOP::AddressingDisposition); Boolean get_answer_invoke (InvokeStatus &, Object_ptr &, ORBRequest *&, GIOP::AddressingDisposition &); Boolean get_answer_bind (LocateStatus &, Object_ptr &); Boolean get_answer_locate (LocateStatus &, Object_ptr &, GIOP::AddressingDisposition &); #ifdef USE_MESSAGING ULong relative_roundtrip_timeout() { return relative_roundtrip_timeout_; } Boolean timedout() { return timedout_; } void timedout(Boolean); #endif // USE_MESSAGING static ORBInvokeRec* _nil () { return 0; } static ORBInvokeRec* _duplicate (ORBInvokeRec *o) { if (o) o->_ref(); return o; } }; typedef ORBInvokeRec *ORBInvokeRec_ptr; typedef ObjVar ORBInvokeRec_var; typedef ObjOut ORBInvokeRec_out; class ORB : public ServerlessObject { public: typedef CORBA::ULong MsgId; private: #ifdef HAVE_THREADS class ResourceManager { ULong _connection_limit; ULong _request_limit; ULong _connection_count; MICOMT::Mutex conn_cnt_mutex; public: ResourceManager () { _connection_limit = 10; _request_limit = 10; _connection_count = 0; } inline ULong connection_limit (ULong NewLimit) { MICOMT::AutoLock l(conn_cnt_mutex); return _connection_limit = NewLimit; } inline ULong connection_limit (void) const { return _connection_limit; } inline ULong request_limit (ULong NewLimit) { return _request_limit = NewLimit; } inline ULong request_limit (void) const { return _request_limit; } // // Not used, but might be handy if we ever want to know how many con- // nections are open at any point in time... // inline ULong connection_count (void) const { return _connection_count; } inline CORBA::Boolean acquire_connection (void) { MICOMT::AutoLock l(conn_cnt_mutex); if (_connection_limit > 0) { if (_connection_count < _connection_limit) { _connection_count++; return TRUE; } return FALSE; } else { // connection checking disabled by -ORBConnLimit 0 _connection_count++; return TRUE; } } inline void release_connection (void) { MICOMT::AutoLock l(conn_cnt_mutex); _connection_count--; } } resourceManager; CORBA::Boolean threading_initialized_; MICOMT::Mutex threading_initialization_mutex_; void initialize_threading(); #endif // HAVE_THREADS typedef std::vector OAVec; typedef std::map > InvokeMap; typedef std::map > InitialRefMap; typedef std::map > ValueFactoryMap; typedef std::list isa_cacheList; std::string _default_init_ref; MICOMT::Locked _isa_cache; std::vector _bindaddrs; MICOMT::RWLocked _adapters; #ifndef HAVE_THREADS InvokeMap _invokes; #else // HAVE_THREADS typedef std::map*> ThreadIDInvokeMap; MICOMT::Locked _invokes; MICOMT::Thread::ThreadKey _invokes_key; #endif // HAVE_THREADS Dispatcher *_disp; IOR *_tmpl; MsgId _theid; #if !defined(HAVE_GCC_ATOMICS) && !defined(HAVE_SOLARIS_ATOMICS) MICOMT::Mutex _theid_lock; #endif // !HAVE_GCC_ATOMICS && !HAVE_SOLARIS_ATOMICS #ifndef HAVE_THREADS std::stack _currentid; #else // HAVE_THREADS MICOMT::Thread::ThreadKey _current_rec_key; CORBA::Boolean use_current_inv_stack_; MICOMT::Mutex run_lock_; MICOMT::Thread::ThreadID main_thread_id_; MICOMT::Mutex shutdown_lock_; #endif // HAVE_THREADS InitialRefMap _init_refs; MICOMT::Mutex _init_refs_lock; std::string _rcfile; DomainManager_var _def_manager; MICOMT::Locked _value_facs; Boolean _is_plugged; Boolean _is_running; Boolean _is_shutdown; Boolean _is_stopped; Boolean _wait_for_completion; OAVec _shutting_down_adapters; OctetSeq _terminal_id; #ifdef USE_ORB_CACHE ORBInvokeRec *_cache_rec; CORBA::Boolean _cache_used; #endif typedef std::map OptionMap; OptionMap removal_option_map_; typedef std::vector > OptionVec; CORBA::DispatcherFactory* dispatcher_factory_; Boolean is_local (Object_ptr); ObjectAdapter *get_oa (Object_ptr); ORBInvokeRec *create_invoke (MsgId); void add_invoke (ORBInvokeRec *); ORBInvokeRec *get_invoke (MsgId); void del_invoke (MsgId); // internal ORBMsgId handling ORBInvokeRec *get_invoke (ORBMsgId id) { return ORBInvokeRec::_duplicate(id); }; void do_shutdown (); CORBA::Object_ptr corbaloc_to_object (const char *); CORBA::Object_ptr corbaname_to_object (const char *); CORBA::Object_ptr iioploc_to_object (const char *); CORBA::Object_ptr iiopname_to_object (const char *); CORBA::Object_ptr file_to_object (const char *); CORBA::Object_ptr http_to_object (const char *); Boolean builtin_invoke (ORBMsgId, Object_ptr, ORBRequest *, Principal_ptr); Object_ptr _resolve_initial_references (const char *id); public: #ifdef HAVE_THREADS inline ResourceManager &resource_manager (void) { return resourceManager; } void set_main_thread_id(MICOMT::Thread::ThreadID id) { main_thread_id_ = id; } void set_use_current_inv_stack(CORBA::Boolean value) { use_current_inv_stack_ = value; } #endif // HAVE_THREADS typedef IfaceSequenceTmpl RequestSeq; typedef TSeqVar RequestSeq_var; typedef OctetSeq ObjectTag; typedef TSeqVar ObjectTag_var; ORB (int &argc, char **argv, const char *rcfile); virtual ~ORB (); char *object_to_string (Object_ptr); Object_ptr string_to_object (const char *); Object_ptr ior_to_object (IOR *); Boolean is_impl (Object_ptr); const char *rcfile(); static char *tag_to_string (const ObjectTag &); static ObjectTag *string_to_tag (const char *); void create_list (Long, NVList_out); void create_operation_list (OperationDef *, NVList_out); void create_named_value (NamedValue_out); void create_exception_list (ExceptionList_out); void create_context_list (ContextList_out); void create_environment (Environment_out); void get_default_context (Context_out); // mico-extension void get_default_domain_manager (DomainManager_out); CORBA::Boolean get_service_information ( CORBA::ServiceType service_type, CORBA::ServiceInformation_out service_information); void send_multiple_requests_oneway (const RequestSeq &); void send_multiple_requests_deferred (const RequestSeq &); Boolean poll_next_response (); void get_next_response (Request_out); Boolean work_pending (); void perform_work (); void run (); void shutdown (Boolean wait_for_completion); void destroy (); typedef char *OAid; typedef CORBA::ORB_InvalidName InvalidName; typedef CORBA::ORB_InvalidName_catch InvalidName_catch; typedef char *ObjectId; typedef StringSequenceTmpl ObjectIdList; typedef ObjectIdList *ObjectIdList_ptr; typedef TSeqVar ObjectIdList_var; ObjectIdList_ptr list_initial_services (); Object_ptr resolve_initial_references (const char *id) { MICOMT::AutoLock l(_init_refs_lock); return _resolve_initial_references(id); } Boolean set_initial_reference (const char *id, Object_ptr obj); // added according to PI spec void register_initial_reference (const char *id, Object_ptr obj); // end Boolean set_default_initial_reference (const char *); Boolean plugged () { return _is_plugged; } void plugged (Boolean which) { _is_plugged = which; } const Octet *terminal_id (ULong &length); void terminal_id (const Octet *val, ULong len); static Boolean is_mobile_key (const CORBA::Octet *); virtual TypeCode_ptr create_struct_tc (const char *rep_id, const char *name, const StructMemberSeq &); virtual TypeCode_ptr create_union_tc (const char *rep_id, const char *name, TypeCode_ptr disc_type, const UnionMemberSeq &); virtual TypeCode_ptr create_enum_tc (const char *rep_id, const char *name, const EnumMemberSeq &); virtual TypeCode_ptr create_exception_tc (const char *rep_id, const char *name, const StructMemberSeq &); virtual TypeCode_ptr create_alias_tc (const char *rep_id, const char *name, TypeCode_ptr orig_type); virtual TypeCode_ptr create_interface_tc (const char *rep_id, const char *name); virtual TypeCode_ptr create_string_tc (ULong bound); virtual TypeCode_ptr create_wstring_tc (ULong bound); virtual TypeCode_ptr create_fixed_tc (UShort digits, Short scale); virtual TypeCode_ptr create_sequence_tc (ULong bound, TypeCode_ptr el_type); virtual TypeCode_ptr create_recursive_sequence_tc (ULong bound, ULong offset); virtual TypeCode_ptr create_array_tc (ULong length, TypeCode_ptr el_type); virtual TypeCode_ptr create_value_tc (const char *rep_id, const char *name, ValueModifier mod, TypeCode_ptr concrete_base, const ValueMemberSeq &members); virtual TypeCode_ptr create_value_box_tc (const char *rep_id, const char *name, TypeCode_ptr boxed_type); virtual TypeCode_ptr create_native_tc (const char *rep_id, const char *name); virtual TypeCode_ptr create_recursive_tc (const char *rep_id); virtual TypeCode_ptr create_abstract_interface_tc (const char *rep_id, const char *name); virtual TypeCode_ptr create_local_interface_tc(const char* repo_id, const char* name); // begin-value ValueFactory register_value_factory (const char *repoid, ValueFactory factory); void unregister_value_factory (const char *repoid); ValueFactory lookup_value_factory (const char *repoid); // end-value CORBA::Policy_ptr create_policy (CORBA::PolicyType type, const CORBA::Any &any); // begin-mico-extension const std::vector &bindaddrs () const { return _bindaddrs; } void bindaddrs (const std::vector &b) { _bindaddrs = b; } void dispatcher (Dispatcher *); Dispatcher *dispatcher () { return _disp; } IOR *ior_template () { return _tmpl; } void register_oa (ObjectAdapter *); void unregister_oa (ObjectAdapter *); void register_profile_id (CORBA::ULong id); void unregister_profile_id (CORBA::ULong id); MsgId new_msgid (); #ifdef USE_CSL2 Principal_ptr get_principal (Object_ptr); #endif // USE_CSL2 ORBMsgId new_orbid (MsgId msgid = 0); static MsgId get_msgid (ORBMsgId rec) { return !CORBA::is_nil(rec) ? rec->id() : 0; }; ORBMsgId get_orbid (MsgId id) { return get_invoke(id); }; //FIXME: hopefully nobody is going to shot me for this :-) void set_request_hint(ORBMsgId id, void *hint) { //ORBInvokeRec_var rec = get_invoke (id); assert( !CORBA::is_nil(id) ); id->set_request_hint( hint ); }; void *get_request_hint(ORBMsgId id) { //ORBInvokeRec_var rec = get_invoke (id); assert( !CORBA::is_nil(id) ); return id->get_request_hint(); }; void set_invoke_hint(ORBMsgId id, void *hint) { //ORBInvokeRec_var rec = get_invoke (id); assert( !CORBA::is_nil(id) ); id->set_invoke_hint( hint ); }; void *get_invoke_hint(ORBMsgId id) { //ORBInvokeRec_var rec = get_invoke (id); assert( !CORBA::is_nil(id) ); return id->get_invoke_hint(); }; ORBMsgId invoke_async (Object_ptr, ORBRequest *, Principal_ptr, Boolean rply = TRUE, ORBCallback * = 0, ORBMsgId = 0); ORBMsgId locate_async (Object_ptr, ORBCallback * = 0, ORBMsgId = 0); ORBMsgId bind_async (const char *repoid, const ObjectTag &, Address *, ORBCallback * = 0, ORBMsgId = 0); InvokeStatus invoke (Object_ptr &, ORBRequest *, Principal_ptr, Boolean rply = TRUE); LocateStatus locate (Object_ptr &); LocateStatus bind (const char *repoid, const ObjectTag &, Address *, Object_ptr &); Object_ptr bind (const char *repoid, const char *addr = 0); Object_ptr bind (const char *repoid, const ObjectTag &, const char *addr = 0); void cancel (ORBMsgId); void cancel (MsgId); Boolean wait (ORBMsgId, Long tmout = -1); // Long wait (vector &, Long tmout = -1); void answer_invoke (ORBMsgId, InvokeStatus, Object_ptr, ORBRequest *, GIOP::AddressingDisposition); void answer_bind (ORBMsgId, LocateStatus, Object_ptr); void answer_locate (ORBMsgId, LocateStatus, Object_ptr, GIOP::AddressingDisposition); void answer_shutdown (ObjectAdapter *); InvokeStatus get_invoke_reply (ORBMsgId, Object_out, ORBRequest *&, GIOP::AddressingDisposition &); LocateStatus get_locate_reply (ORBMsgId, Object_out, GIOP::AddressingDisposition &); LocateStatus get_bind_reply (ORBMsgId, Object_out); ORBRequest *request (ORBMsgId); RequestType request_type (ORBMsgId); void redo_request (ORBMsgId); ImplementationDef *get_impl (Object_ptr); InterfaceDef *get_iface (Object_ptr); Object *get_component (Object_ptr); Boolean is_a (Object_ptr, const char *repoid); Boolean non_existent (Object_ptr); ORBInvokeRec *get_current_invoke_rec (); CORBA::Dispatcher* create_dispatcher(); void dispatcher_factory(CORBA::DispatcherFactory* fact); void register_option_for_removal(const char* opt, bool arg); void register_options_for_removal(OptionVec& options); OptionMap options_for_removal() { return this->removal_option_map_; } Boolean validate_connection (CORBA::Object_ptr obj, CORBA::PolicyList_out inconsistent_policies); #ifdef HAVE_THREADS Boolean remove_thread_invocations_map(void*); #endif // HAVE_THREADS // end-mico-extension static ORB_ptr _duplicate (ORB_ptr o) { if (o) o->_ref(); return o; } static ORB_ptr _nil () { return 0; } }; typedef ObjVar ORB_var; typedef ObjOut ORB_out; // ORB initialization typedef char *ORBid; extern ORB_ptr ORB_init (int &argc, char **argv, const char *id = ""); extern ORB_ptr ORB_instance (const char *id, Boolean create=TRUE); class ObjectAdapter { public: typedef CORBA::ULong MsgId; virtual const char *get_oaid () const = 0; virtual Boolean has_object (Object_ptr) = 0; virtual Boolean is_local () const = 0; #ifdef USE_CSL2 virtual CORBA::Principal_ptr get_principal (CORBA::Object_ptr) = 0; #endif // USE_CSL2 virtual Boolean invoke (ORBMsgId, Object_ptr, ORBRequest *, Principal_ptr, Boolean response_exp = TRUE) = 0; virtual Boolean bind (ORBMsgId, const char *repoid, const ORB::ObjectTag &, Address *addr) = 0; virtual Boolean locate (ORBMsgId, Object_ptr) = 0; virtual Object_ptr skeleton (Object_ptr) = 0; virtual void cancel (ORBMsgId) = 0; virtual void shutdown (Boolean wait_for_completion) = 0; virtual void answer_invoke (ORBMsgId, CORBA::Object_ptr, CORBA::ORBRequest *, CORBA::InvokeStatus) = 0; virtual Boolean validate_connection (CORBA::Object_ptr obj, CORBA::PolicyList_out inconsistent_policies) = 0; virtual void timedout_invoke (ORBMsgId) = 0; virtual ~ObjectAdapter (); }; } #endif // __mico_orb_mico_h__