// -*- c++ -*- /* * MICO --- an Open Source CORBA implementation * Copyright (c) 1997-2018 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_iop_h__ #define __mico_iop_h__ #ifndef HAVE_THREADS # define USE_IOP_CACHE #endif // KG-NOTE: Quick and dirty fix #undef USE_IOP_CACHE namespace MICO { class GIOPCodec; class GIOPInContext { CORBA::DataDecoder *_dc; CORBA::Buffer *_buf; CORBA::Boolean _delete_buf; CORBA::Boolean _delete_dc; public: GIOPInContext (GIOPCodec *, CORBA::Buffer *, CORBA::CodeSetCoder *csc = 0); ~GIOPInContext (); void converters (CORBA::CodeSetCoder *csc); CORBA::DataDecoder *dc() { return _dc; } void buffer (CORBA::Buffer *); CORBA::DataDecoder *_retn(); }; class GIOPOutContext { CORBA::DataEncoder *_ec; CORBA::Buffer *_buf; CORBA::Boolean _delete_buf; CORBA::Boolean _delete_ec; public: GIOPOutContext (GIOPCodec *, CORBA::CodeSetCoder *csc = 0); GIOPOutContext (CORBA::DataEncoder *); ~GIOPOutContext (); void converters (CORBA::CodeSetCoder *csc); CORBA::DataEncoder *ec() { return _ec; } void reset (); CORBA::Buffer *_retn(); }; #define GIOP_BYTEORDER_BIT 1 #define GIOP_FRAGMENT_BIT 2 class GIOPCodec; typedef GIOPCodec *GIOPCodec_ptr; typedef ObjVar GIOPCodec_var; class GIOPCodec : public CORBA::ServerlessObject { CORBA::DataDecoder *_dc_proto; CORBA::DataEncoder *_ec_proto; CORBA::ULong _headerlen; CORBA::ULong _size_offset; CORBA::UShort _giop_ver; CORBA::CodeSetCoder * _conv; CORBA::Codeset::CodesetId _csid; CORBA::Codeset::CodesetId _wcsid; CORBA::Boolean _codesets_sent; #ifdef HAVE_THREADS static bool S_request_key_initialized_; static MICOMT::Thread::ThreadKey S_request_key_; #endif // HAVE_THREADS CORBA::ULong put_header (GIOPOutContext &out, GIOP::MsgType); void put_size (GIOPOutContext &out, CORBA::ULong key); void put_contextlist (GIOPOutContext &out, const IOP::ServiceContextList &ctx, CORBA::Boolean codesets = FALSE); void put_target (GIOPOutContext &out, CORBA::Object_ptr obj); CORBA::Boolean put_args (GIOPOutContext &out, CORBA::ORBRequest *, CORBA::Boolean inp); CORBA::Boolean get_contextlist (GIOPInContext &in, IOP::ServiceContextList &ctx, CORBA::Boolean codesets = FALSE); CORBA::Boolean get_target (GIOPInContext &in, CORBA::Object_ptr obj); public: GIOPCodec (CORBA::DataDecoder *dc, CORBA::DataEncoder *ec, CORBA::UShort giop_ver = 0x0100); ~GIOPCodec (); CORBA::DataDecoder *dc_proto() { return _dc_proto; } CORBA::DataEncoder *ec_proto() { return _ec_proto; } CORBA::UShort version () const { return _giop_ver; } void version (CORBA::UShort ver) { _giop_ver = ver; } CORBA::ULong header_length () { return _headerlen; } CORBA::CodeSetCoder * converter () { return _conv; } CORBA::Codeset::CodesetId csid () { return _csid; } CORBA::Codeset::CodesetId wcsid () { return _wcsid; } CORBA::Boolean setup_codeset_ids (CORBA::Object_ptr); CORBA::Boolean put_invoke_request (GIOPOutContext &out, CORBA::ULong req_id, CORBA::Octet response_flags, CORBA::Object_ptr obj, CORBA::ORBRequest *req, CORBA::Principal_ptr pr); CORBA:: Boolean put_invoke_reply (GIOPOutContext &out, CORBA::ULong req_id, GIOP::ReplyStatusType, CORBA::Object_ptr obj, CORBA::ORBRequest *req, GIOP::AddressingDisposition); CORBA::Boolean put_invoke_reply_offset (GIOPOutContext &out, CORBA::ORBRequest *req); CORBA::Boolean put_cancel_request (GIOPOutContext &out, CORBA::ULong req_id); CORBA::Boolean put_locate_request (GIOPOutContext &out, CORBA::ULong req_id, CORBA::Object_ptr obj); CORBA::Boolean put_locate_reply (GIOPOutContext &out, CORBA::ULong req_id, GIOP::LocateStatusType, CORBA::Object_ptr obj, GIOP::AddressingDisposition); CORBA::Boolean put_bind_request (GIOPOutContext &out, CORBA::ULong req_id, const char *repoid, const CORBA::ORB::ObjectTag &); CORBA::Boolean put_bind_reply (GIOPOutContext &out, CORBA::ULong req_id, GIOP::LocateStatusType, CORBA::Object_ptr obj); CORBA::Boolean put_close_msg (GIOPOutContext &out); CORBA::Boolean put_error_msg (GIOPOutContext &out); CORBA::Boolean get_header (GIOPInContext &in, GIOP::MsgType &, CORBA::ULong &sz, CORBA::Octet &flags); CORBA::Boolean check_header (GIOPInContext &in, GIOP::MsgType &, CORBA::ULong &sz, CORBA::Octet &flags); CORBA::Boolean get_invoke_request (GIOPInContext &in, CORBA::ULong &req_id, CORBA::Octet &response_flags, CORBA::Object_ptr obj, CORBA::ORBRequest * &req, CORBA::Principal_ptr pr); CORBA::Boolean get_invoke_reply1 (GIOPInContext &in, CORBA::ULong &req_id, GIOP::ReplyStatusType &, IOP::ServiceContextList &ctx); CORBA::Boolean get_invoke_reply2 (GIOPInContext &in, CORBA::ULong req_id, GIOP::ReplyStatusType, CORBA::Object_ptr &obj, CORBA::ORBRequest *req, GIOP::AddressingDisposition &, IOP::ServiceContextList &ctx); CORBA::Boolean get_cancel_request (GIOPInContext &in, CORBA::ULong &req_id); CORBA::Boolean get_locate_request (GIOPInContext &in, CORBA::ULong &req_id, CORBA::Object_ptr obj); CORBA::Boolean get_locate_reply (GIOPInContext &in, CORBA::ULong &req_id, GIOP::LocateStatusType &, CORBA::Object_ptr &obj, GIOP::AddressingDisposition &); CORBA::Boolean get_bind_request (GIOPInContext &in, CORBA::String_out repoid, CORBA::ORB::ObjectTag &); CORBA::Boolean get_bind_reply (GIOPInContext &in, GIOP::LocateStatusType &, CORBA::Object_ptr &obj); CORBA::Boolean get_close_msg (GIOPInContext &in); CORBA::Boolean get_error_msg (GIOPInContext &in); CORBA::Boolean get_fragment_header (GIOPInContext &in, CORBA::ULong &req_id, CORBA::Boolean &has_id); static GIOPCodec_ptr _duplicate (GIOPCodec_ptr o) { if (o) o->_ref(); return o; } static GIOPCodec_ptr _nil () { return 0; } }; class GIOPRequest : public CORBA::ORBRequest { std::string _opname; CORBA::DataDecoder *_idc; CORBA::ULong _istart; CORBA::DataEncoder *_oec; CORBA::DataDecoder *_odc; CORBA::ULong _ostart; CORBA::Buffer _obuf; GIOPCodec_ptr _codec; CORBA::Boolean _is_except; public: GIOPRequest (const char *op, CORBA::DataDecoder *indata, GIOPCodec *); ~GIOPRequest (); void reset(const char *op, CORBA::DataDecoder *indata); const char *op_name(); CORBA::UShort version () const { return _codec->version (); } CORBA::Boolean get_in_args (CORBA::NVList_ptr iparams, CORBA::Context_ptr &ctx); CORBA::Boolean get_in_args (StaticAnyList *iparams, CORBA::Context_ptr &ctx); CORBA::Boolean get_in_args (CORBA::DataEncoder *); CORBA::Boolean get_out_args (CORBA::Any *res, CORBA::NVList_ptr oparams, CORBA::Exception *&ex); CORBA::Boolean get_out_args (CORBA::StaticAny *res, StaticAnyList *oparams, CORBA::Exception *&ex); CORBA::Boolean get_out_args (CORBA::DataEncoder *, CORBA::Boolean &is_except); CORBA::Boolean set_out_args (CORBA::Any *res, CORBA::NVList_ptr oparams); CORBA::Boolean set_out_args (CORBA::StaticAny *res, StaticAnyList *oparams); void set_out_args (CORBA::Exception *ex); CORBA::Boolean set_out_args (CORBA::DataDecoder *, CORBA::Boolean is_except); CORBA::Boolean copy_out_args (CORBA::ORBRequest *); CORBA::Boolean copy_in_args (CORBA::ORBRequest *); const char *type (); CORBA::ByteOrder input_byteorder (); CORBA::ByteOrder output_byteorder (); CORBA::CodeSetCoder * converter (); static GIOPRequest* _nil () { return 0; } static GIOPRequest* _duplicate (GIOPRequest *o) { if (o) o->_ref(); return o; } }; class GIOPSimpleProf : public CORBA::IORProfile { public: CORBA::Octet *_objkey; CORBA::Octet *_objkey_nc; CORBA::ULong _length; public: GIOPSimpleProf (); GIOPSimpleProf (const GIOPSimpleProf &); ~GIOPSimpleProf (); GIOPSimpleProf &operator= (const GIOPSimpleProf &); void encode (CORBA::DataEncoder &) const; const CORBA::Address *addr () const; ProfileId id () const; ProfileId encode_id () const; void objectkey (CORBA::Octet *, CORBA::Long length); void objectkey_nc (CORBA::Octet *, CORBA::Long length); const CORBA::Octet *objectkey (CORBA::Long &length) const; CORBA::Boolean reachable (); void print (std::ostream &) const; CORBA::IORProfile *clone () const; CORBA::Long compare (const CORBA::IORProfile &) const; CORBA::Boolean operator== (const CORBA::IORProfile &) const; CORBA::Boolean operator< (const CORBA::IORProfile &) const; }; #ifdef HAVE_THREADS class GIOPConnReader; class GIOPConnWriter; enum GIOPSide { UNSPECIFIED, CLIENT_SIDE, SERVER_SIDE }; #endif // HAVE_THREADS struct GIOPConnCallback; #ifdef HAVE_THREADS class GIOPConn : public CORBA::TransportCallback, public CORBA::DispatcherCallback, public MICOMT::StateRefCnt { #else class GIOPConn : public CORBA::TransportCallback, public CORBA::DispatcherCallback { #endif #ifdef USE_SL3 // kcg: we use CORBA::Object_var here to not need to use // forward declaration of various types from TransportSecurity namespace // The purpose of these variables is just to hold // transport security OwnCredentials, AcceptingContext and InitiatingContext // references as long as GIOP connection is alive. CORBA::Object_var init_ctx_; CORBA::Object_var accept_ctx_; CORBA::String_var creds_id_; CORBA::Object_var own_creds_; #endif // USE_SL3 CORBA::Dispatcher *_disp; CORBA::Transport *_transp; std::list _outbufs; MICOMT::Mutex write_lock_; CORBA::Buffer *_inbufs; CORBA::Buffer *_inbuf, *_infrag; CORBA::ULong _inlen; CORBA::Octet _inflags; GIOPConnCallback *_cb; GIOPCodec_ptr _codec; CORBA::Long _refcnt; MICOMT::Mutex refcnt_lock_; CORBA::Long _idle_tmout; CORBA::Boolean _have_tmout; CORBA::Boolean _have_wselect; GIOPInContext _inctx; CORBA::ULong _max_message_size; CORBA::ULong _id; CORBA::ULong _total_fragsize; std::map > _fragments; void do_write (); #ifdef HAVE_THREADS GIOPConnReader *_reader; GIOPConnWriter *_writer; MICOMT::Mutex _excl_mutex; GIOPSide side_; static MICOMT::Thread::ThreadKey S_reader_key_; static bool S_reader_key_initialized_; CORBA::Boolean _M_use_reader_thread; CORBA::Boolean _M_use_writer_thread; CORBA::Boolean input_ready(); void close_connection(); void check_idle () {}; void check_busy () {}; #else CORBA::Boolean input_ready() { return input_ready_callback( input() ); }; // void close_connection() { // _cb->callback (this, GIOPConnCallback::Closed); // }; void close_connection(); void check_idle (); void check_busy (); #endif // HAVE_THREADS public: void do_read ( const CORBA::Boolean break_after_read = FALSE ); void output_handler (CORBA::Buffer *); #ifdef HAVE_THREADS void terminate(); GIOPSide side() { return side_; } GIOPConn (CORBA::Dispatcher *, CORBA::Transport *, GIOPConnCallback *, GIOPCodec *, CORBA::Long tmout = 0, CORBA::ULong max_size = 0, MICO::GIOPSide side = UNSPECIFIED, CORBA::Boolean __reader_thread = FALSE, CORBA::Boolean __writer_thread = FALSE, CORBA::ULong id = 0xFFFFFFFFUL); #else GIOPConn (CORBA::Dispatcher *, CORBA::Transport *, GIOPConnCallback *, GIOPCodec *, CORBA::Long tmout = 0, CORBA::ULong max_size = 0, CORBA::ULong id = 0xFFFFFFFFUL); #endif virtual ~GIOPConn (); #ifdef HAVE_THREADS void start(); void output (CORBA::Buffer *); CORBA::Boolean check_events () { return FALSE; }; void ref (); CORBA::Boolean deref (CORBA::Boolean all = FALSE); void get_exclusive () { _excl_mutex.lock(); }; void release_exclusive () { _excl_mutex.unlock(); }; // added for debuging reason // because I'm not able to add breakpoint on line in .h file :-(( CORBA::Boolean active_ref(); void active_deref(); // three methods using TLS for `detecting' reader thread CORBA::Boolean is_this_reader_thread(); void set_as_reader_thread(); static void initialize_reader_key(); #else void start() {}; void output (CORBA::Buffer *b) { this->output_handler(b); }; CORBA::Boolean check_events (); void ref (); CORBA::Boolean deref (CORBA::Boolean all = FALSE); void get_exclusive () {}; void release_exclusive () {}; #endif CORBA::ULong id () { return _id; } void id (CORBA::ULong i) { _id = i; } CORBA::Boolean input_ready_callback(CORBA::Buffer *b); virtual void callback (CORBA::Transport *, CORBA::TransportCallback::Event); virtual void callback (CORBA::Dispatcher *, CORBA::DispatcherCallback::Event); CORBA::Buffer *input (); void flush (); CORBA::Transport *transport () { return _transp; } GIOPCodec *codec () { return _codec; } void cancel (CORBA::ULong reqid); void buffering (CORBA::Boolean dobuffering); CORBA::Dispatcher* dispatcher() { return _disp; } #ifdef USE_SL3 CORBA::Object_ptr initiating_context() { return CORBA::Object::_duplicate(init_ctx_); } void initiating_context(CORBA::Object_ptr ctx) { init_ctx_ = CORBA::Object::_duplicate(ctx); } CORBA::Object_ptr accepting_context() { return CORBA::Object::_duplicate(accept_ctx_); } void accepting_context(CORBA::Object_ptr ctx) { accept_ctx_ = CORBA::Object::_duplicate(ctx); } char* creds_id() { return CORBA::string_dup(creds_id_.in()); } void creds_id(const char* id) { creds_id_ = id; } CORBA::Object_ptr own_creds() { return CORBA::Object::_duplicate(own_creds_); } void own_creds(CORBA::Object_ptr creds) { own_creds_ = CORBA::Object::_duplicate(creds); } #endif // USE_SL3 }; struct GIOPConnCallback { enum Event { InputReady, Closed, Idle }; virtual CORBA::Boolean callback (GIOPConn *, Event) = 0; virtual CORBA::Boolean input_callback (GIOPConn *, CORBA::Buffer *) = 0; virtual ~GIOPConnCallback (); #ifdef HAVE_THREADS void send_orb_msg (GIOPConn *, ORBMsg::Event); //#else // void kill_conn (GIOPConn *conn, CORBA::Boolean redo = FALSE) { kill_conn_callback( conn, redo ); }; #endif }; inline CORBA::Boolean GIOPConn::input_ready_callback(CORBA::Buffer *b) { return _cb->input_callback (this, b); } struct GIOPConnMsg { GIOPConnMsg(GIOPConn *_conn, CORBA::Buffer *_b, GIOPConnCallback::Event _ev): conn(_conn), b(_b), ev(_ev) {}; GIOPConn *conn; CORBA::Buffer *b; GIOPConnCallback::Event ev; }; #ifdef HAVE_THREADS class GIOPConnWriter: public ActiveOperation { protected: GIOPConn *conn; public: GIOPConnWriter( GIOPConn *_conn ); virtual ~GIOPConnWriter(); void process( msg_type * msg ); void send_msg( msg_type * msg); virtual Operation *copy() const { return NULL; }; }; class GIOPConnReader: public MICOMT::Thread { protected: GIOPConn *conn; public: GIOPConnReader( GIOPConn *_conn ); void _run(void*); }; class InputHandler: public PassiveOperation { public: InputHandler(); // InputHandler( const MICO::InputHandler::InputHandler & ); InputHandler( ThreadPool& _tp ); void process( msg_type * msg ); virtual Operation *copy() const; }; class DummyDispatcher: public CORBA::Dispatcher { public: virtual ~DummyDispatcher () {}; void rd_event (CORBA::DispatcherCallback *, CORBA::Long fd) {}; void wr_event (CORBA::DispatcherCallback *, CORBA::Long fd) {}; void ex_event (CORBA::DispatcherCallback *, CORBA::Long fd) {}; void tm_event (CORBA::DispatcherCallback *, CORBA::ULong tmout) {}; void remove (CORBA::DispatcherCallback *, CORBA::Dispatcher::Event) {}; void run (CORBA::Boolean infinite = TRUE) {}; void move (CORBA::Dispatcher *) {}; CORBA::Boolean idle () const { return TRUE; }; virtual void block (CORBA::Boolean b) {}; virtual CORBA::Boolean isblocking () { return TRUE; }; }; class GIOPConnMgr { protected: DummyDispatcher dummyDisp; public: virtual ~GIOPConnMgr() {} virtual CORBA::Dispatcher *Dispatcher() { return &dummyDisp; }; }; #else class GIOPConnMgr { public: virtual ~GIOPConnMgr() {} //CORBA::Dispatcher *Dispatcher() { return _orb->dispatcher(); }; virtual CORBA::Dispatcher* Dispatcher() = 0; }; #endif // HAVE_THREADS class IIOPProxyInvokeRec { public: typedef CORBA::ULong MsgId; typedef CORBA::Codeset::CodesetId CodesetId; private: CORBA::ORBMsgId_var _id; MsgId _msgid; GIOPConn *_conn; CORBA::ORBRequest *_req; CORBA::Boolean _active; public: IIOPProxyInvokeRec () { _id = CORBA::ORBInvokeRec::_nil(); _msgid = 0; _conn = NULL; _req = CORBA::ORBRequest::_nil(); _active = FALSE; } ~IIOPProxyInvokeRec () { if (!CORBA::is_nil(_id)) { _id->set_invoke_hint(NULL); } } void free () { assert(0); } void init (CORBA::ORBMsgId idval, GIOPConn *connval, CORBA::ORBRequest *req = 0) { _id = CORBA::ORBInvokeRec::_duplicate(idval); _msgid = CORBA::ORB::get_msgid(idval); _conn = connval; _req = req; _active = TRUE; } CORBA::Boolean active() const { return _active; }; void deactivate() { _active = FALSE; }; GIOPConn *conn () const { return _conn; } CORBA::ORBRequest *request () const { return _req; } CORBA::ORBMsgId id () const { return CORBA::ORBInvokeRec::_duplicate(_id); } MsgId msgid () const { return _msgid; } }; class IIOPProxy : public CORBA::ObjectAdapter, public GIOPConnCallback, public GIOPConnMgr { typedef std::map > MapIdConn; struct addrcomp : std::binary_function { bool operator() (const CORBA::Address *a1, const CORBA::Address *a2) const { return a1->compare (*a2) < 0; } }; struct iorcomp : std::binary_function { bool operator() (const CORBA::IORProfile *ior1, const CORBA::IORProfile *ior2) const { if (ior1 && ior2) return (ior1->compare (*ior2) < 0); else if (ior1 && !ior2) return true; else return false; } }; typedef std::map MapAddrConn; typedef std::map > MapVerAddrConn; typedef std::map MapProfConn; typedef std::vector ProfIdVec; ProfIdVec _valid_profiles; MICOMT::Locked _ids; MICOMT::Locked _conns; MICOMT::Locked _prof_conns; CORBA::ORB_ptr _orb; CORBA::UShort _giop_ver; CORBA::ULong _max_message_size; CORBA::Address *_reroute; #ifdef USE_IOP_CACHE IIOPProxyInvokeRec *_cache_rec; CORBA::Boolean _cache_used; #endif IIOPProxyInvokeRec *create_invoke (); IIOPProxyInvokeRec *pull_invoke (CORBA::ORBMsgId); void add_invoke (IIOPProxyInvokeRec *); void del_invoke (IIOPProxyInvokeRec *); void abort_invoke (CORBA::ORBMsgId); void redo_invoke (CORBA::ORBMsgId); GIOPConn *make_conn (CORBA::Object_ptr, CORBA::Boolean&); GIOPConn *make_conn (const CORBA::Address *, CORBA::ULong timeout, CORBA::Boolean& timedout, CORBA::Boolean create = TRUE, CORBA::UShort version = 0 #ifdef USE_SL3 , const char* tcpip_creds_id = 0, const char* tls_creds_id = 0 #endif // USE_SL3 ); void conn_error (GIOPConn *, CORBA::Boolean send_error = TRUE); void deref_conn (GIOPConn *conn, CORBA::Boolean all = FALSE ); CORBA::Boolean handle_input (GIOPConn *, CORBA::Buffer *); void exec_invoke_reply (GIOPInContext &, CORBA::ORBMsgId, GIOP::ReplyStatusType, CORBA::Object_ptr, CORBA::ORBRequest *, GIOP::AddressingDisposition, GIOPConn *conn); CORBA::Boolean handle_invoke_reply (GIOPConn *conn, GIOPInContext &); CORBA::Boolean handle_locate_reply (GIOPConn *conn, GIOPInContext &); public: IIOPProxy (CORBA::ORB_ptr, CORBA::UShort giop_ver = 0x0100, CORBA::ULong max_size = 0); ~IIOPProxy (); void register_profile_id (CORBA::ULong id); void unregister_profile_id (CORBA::ULong id); const char *get_oaid () const; CORBA::Boolean has_object (CORBA::Object_ptr); CORBA::Boolean is_local () const; #ifdef USE_CSL2 CORBA::Principal_ptr get_principal (CORBA::Object_ptr); #endif /* USE_CSL2 */ CORBA::Boolean invoke (CORBA::ORBMsgId, CORBA::Object_ptr, CORBA::ORBRequest *, CORBA::Principal_ptr, CORBA::Boolean repsonse_exp); CORBA::Boolean bind (CORBA::ORBMsgId, const char *repoid, const CORBA::ORB::ObjectTag &, CORBA::Address *addr); CORBA::Boolean locate (CORBA::ORBMsgId, CORBA::Object_ptr); CORBA::Object_ptr skeleton (CORBA::Object_ptr); void cancel (CORBA::ORBMsgId); void shutdown (CORBA::Boolean wait_for_completion); void answer_invoke (CORBA::ORBMsgId, CORBA::Object_ptr, CORBA::ORBRequest *, CORBA::InvokeStatus); virtual CORBA::Boolean validate_connection(CORBA::Object_ptr, CORBA::PolicyList_out); virtual void timedout_invoke(CORBA::ORBMsgId); CORBA::Boolean callback (GIOPConn *, GIOPConnCallback::Event); CORBA::Boolean input_callback (GIOPConn *, CORBA::Buffer *); void kill_conn (GIOPConn *, CORBA::Boolean redo = FALSE); virtual CORBA::Dispatcher* Dispatcher(); void redirect (CORBA::Address *addr) { _reroute = addr; } }; class IIOPServerInvokeRec { public: typedef CORBA::ULong MsgId; private: CORBA::ORBRequest *_req; CORBA::Object_ptr _obj; CORBA::Principal_ptr _pr; CORBA::ORBMsgId_var _orbid; MsgId _orbmsgid; MsgId _reqid; GIOPConn *_conn; CORBA::Boolean _active; public: IIOPServerInvokeRec (); ~IIOPServerInvokeRec (); void free (); void init_invoke (GIOPConn *conn, MsgId reqid, CORBA::ORBMsgId orbid, CORBA::ORBRequest *req, CORBA::Object_ptr obj, CORBA::Principal_ptr pr); void init_locate (GIOPConn *conn, MsgId reqid, CORBA::ORBMsgId orbid, CORBA::Object_ptr obj); CORBA::Boolean active() const { return _active; }; void deactivate() { _active = FALSE; }; CORBA::ORBRequest *req() { return _req; } CORBA::ORBMsgId orbid() { return CORBA::ORBInvokeRec::_duplicate(_orbid); } MsgId orbmsgid() { return _orbmsgid; } void orbid (CORBA::ORBMsgId id) { _orbid = CORBA::ORBInvokeRec::_duplicate(id); } MsgId reqid() { return _reqid; } GIOPConn *conn() { return _conn; } }; class IIOPServer : public CORBA::ObjectAdapter, public CORBA::ORBCallback, public GIOPConnCallback, public GIOPConnMgr, public CORBA::TransportServerCallback { typedef CORBA::ULong MsgId; public: // this needs to be public typedef due to type usage in // IIOPServer_cleanup_idrecmap function typedef std::map > MapIdConn; private: typedef std::list ListConn; typedef std::vector VecTranspServ; #ifdef HAVE_THREADS public: class ThreadIdRecMapMember { public: ThreadIdRecMapMember() : scheduled_for_removal_(FALSE) {} MapIdConn map_; bool scheduled_for_removal_; }; typedef std::map*> ThreadIdRecMap; MICOMT::Thread::ThreadKey idrec_map_key_; #endif // HAVE_THREADS private: MICOMT::Locked _tservers; MICOMT::Locked _conns; #ifndef HAVE_THREADS MapIdConn _orbids; #else // HAVE_THREADS MICOMT::Mutex _orbids_mutex; ThreadIdRecMap _orbids; #endif // HAVE_THREADS CORBA::ORB_ptr _orb; #ifdef USE_IOP_CACHE IIOPServerInvokeRec *_cache_rec; CORBA::Boolean _cache_used; #endif CORBA::UShort _iiop_ver; CORBA::ULong _max_message_size; #ifdef HAVE_THREADS MICOMT::Thread::ThreadKey target_obj_key_; #endif // HAVE_THREADS IIOPServerInvokeRec *create_invoke(); IIOPServerInvokeRec *pull_invoke_reqid (MsgId, GIOPConn *conn); IIOPServerInvokeRec *pull_invoke_orbid (CORBA::ORBMsgId); void add_invoke (IIOPServerInvokeRec *); void del_invoke_reqid (MsgId, GIOPConn *conn); void del_invoke_orbid (IIOPServerInvokeRec *); void abort_invoke_orbid (IIOPServerInvokeRec *); void conn_error (GIOPConn *, CORBA::Boolean send_error = TRUE); void conn_closed (GIOPConn *); void deref_conn (GIOPConn *conn, CORBA::Boolean all = FALSE ); CORBA::Boolean handle_input (GIOPConn *, CORBA::Buffer *); CORBA::ORBMsgId exec_invoke_request (GIOPInContext &, CORBA::Object_ptr, CORBA::ORBRequest *, CORBA::Principal_ptr, CORBA::Boolean resp_exp, GIOPConn *conn, CORBA::ORBMsgId msgid); CORBA::Boolean handle_invoke_request (GIOPConn *conn, GIOPInContext &); CORBA::Boolean handle_locate_request (GIOPConn *conn, GIOPInContext &); CORBA::Boolean handle_cancel_request (GIOPConn *conn, GIOPInContext &); void handle_invoke_reply (CORBA::ORBMsgId); void handle_locate_reply (CORBA::ORBMsgId); void handle_bind_reply (CORBA::ORBMsgId); public: IIOPServer (CORBA::ORB_ptr, CORBA::UShort iiop_ver = 0x0100, CORBA::ULong max_size = 0); ~IIOPServer (); CORBA::Boolean listen (CORBA::Address*, CORBA::Address*, const CORBA::Address*&); CORBA::Boolean listen (CORBA::Address *, CORBA::Address *); CORBA::Boolean listen (); void shutdown(CORBA::Address* addr); // ObjectAdapter methods const char *get_oaid () const; CORBA::Boolean has_object (CORBA::Object_ptr); CORBA::Boolean is_local () const; #ifdef USE_CSL2 CORBA::Principal_ptr get_principal (CORBA::Object_ptr); #endif /* USE_CSL2 */ CORBA::Boolean invoke (CORBA::ORBMsgId, CORBA::Object_ptr, CORBA::ORBRequest *, CORBA::Principal_ptr, CORBA::Boolean repsonse_exp); CORBA::Boolean bind (CORBA::ORBMsgId, const char *repoid, const CORBA::ORB::ObjectTag &, CORBA::Address *addr); CORBA::Boolean locate (CORBA::ORBMsgId, CORBA::Object_ptr); CORBA::Object_ptr skeleton (CORBA::Object_ptr); void cancel (CORBA::ORBMsgId); void shutdown (CORBA::Boolean wait_for_completion); void answer_invoke (CORBA::ORBMsgId, CORBA::Object_ptr, CORBA::ORBRequest *, CORBA::InvokeStatus); virtual CORBA::Boolean validate_connection(CORBA::Object_ptr, CORBA::PolicyList_out); virtual void timedout_invoke(CORBA::ORBMsgId); // ORBCallback interface CORBA::Boolean waitfor (CORBA::ORB_ptr, CORBA::ORBMsgId, CORBA::ORBCallback::Event, CORBA::Long); void notify (CORBA::ORB_ptr, CORBA::ORBMsgId, CORBA::ORBCallback::Event); CORBA::Boolean callback (GIOPConn *, GIOPConnCallback::Event); CORBA::Boolean input_callback (GIOPConn *, CORBA::Buffer *); void callback (CORBA::TransportServer *, CORBA::TransportServerCallback::Event); void kill_conn (GIOPConn *, CORBA::Boolean redo = FALSE); virtual CORBA::Dispatcher* Dispatcher(); // kcg: needed in SL3 => replace ORB's internal iiop_server_instance // variable static IIOPServer* iiopserver_instance() { return iiopserver_instance_; } private: static IIOPServer* iiopserver_instance_; CORBA::Boolean shutdown_in_progress_; MICOMT::Mutex shutdown_in_progress_lock_; }; } #endif // __mico_iop_h__