From a9aae6a4eedc88acb6f91ac0b9fce02f57570b70 Mon Sep 17 00:00:00 2001 From: fredk Date: Thu, 28 Jan 1999 22:11:59 +0000 Subject: *** empty log message *** --- TAO/tao/Connect.cpp | 66 ++++- TAO/tao/Connect.h | 36 ++- TAO/tao/GIOP.cpp | 219 +++++++--------- TAO/tao/GIOP.h | 11 +- TAO/tao/IIOP_Acceptor.cpp | 40 +++ TAO/tao/IIOP_Acceptor.h | 55 ++++ TAO/tao/IIOP_Connector.cpp | 231 +++++++++++++++++ TAO/tao/IIOP_Connector.h | 52 ++++ TAO/tao/IIOP_ORB.cpp | 128 +++------ TAO/tao/IIOP_Object.cpp | 164 +++++++----- TAO/tao/IIOP_Object.h | 161 +++++------- TAO/tao/IIOP_Object.i | 222 ++++++++-------- TAO/tao/IIOP_Profile.cpp | 626 +++++++++++++++++++++++++++++++++++++++++++++ TAO/tao/IIOP_Profile.h | 140 ++++++++++ TAO/tao/IIOP_Transport.cpp | 271 ++++++++++++++++++++ TAO/tao/IIOP_Transport.h | 105 ++++++++ TAO/tao/Invocation.cpp | 194 +++++--------- TAO/tao/Invocation.h | 2 +- TAO/tao/Makefile | 9 +- TAO/tao/ORB.cpp | 47 ++-- TAO/tao/ORB.h | 1 - TAO/tao/ORB_Core.cpp | 248 +++++------------- TAO/tao/ORB_Core.h | 46 ++-- TAO/tao/ORB_Core.i | 24 +- TAO/tao/Object.cpp | 2 +- TAO/tao/Pluggable.cpp | 193 ++++++++++++++ TAO/tao/Pluggable.h | 189 ++++++++++++++ TAO/tao/Server_Request.cpp | 2 +- TAO/tao/Stub.h | 36 ++- TAO/tao/corba.h | 9 + TAO/tao/decode.cpp | 82 ++---- TAO/tao/encode.cpp | 17 +- TAO/tao/params.cpp | 2 +- TAO/tao/params.h | 8 +- TAO/tao/params.i | 8 +- 35 files changed, 2702 insertions(+), 944 deletions(-) create mode 100644 TAO/tao/IIOP_Acceptor.cpp create mode 100644 TAO/tao/IIOP_Acceptor.h create mode 100644 TAO/tao/IIOP_Connector.cpp create mode 100644 TAO/tao/IIOP_Connector.h create mode 100644 TAO/tao/IIOP_Profile.cpp create mode 100644 TAO/tao/IIOP_Profile.h create mode 100644 TAO/tao/IIOP_Transport.cpp create mode 100644 TAO/tao/IIOP_Transport.h create mode 100644 TAO/tao/Pluggable.cpp create mode 100644 TAO/tao/Pluggable.h (limited to 'TAO/tao') diff --git a/TAO/tao/Connect.cpp b/TAO/tao/Connect.cpp index b776a26c7e6..224f37477bd 100644 --- a/TAO/tao/Connect.cpp +++ b/TAO/tao/Connect.cpp @@ -42,16 +42,43 @@ ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Connect_Timeprobe_Description, #endif /* ACE_ENABLE_TIMEPROBES */ +TAO_IIOP_Handler_Base::TAO_IIOP_Handler_Base (ACE_Thread_Manager *t) + : TAO_SVC_HANDLER (t) +{ +} + +TAO_IIOP_Handler_Base::TAO_IIOP_Handler_Base (TAO_ORB_Core *orb_core) + : TAO_SVC_HANDLER (orb_core->thr_mgr (), 0, 0) +{ +} + +TAO_IIOP_Handler_Base::TAO_IIOP_Handler_Base (ACE_Thread_Manager *t, int x, int y) + : TAO_SVC_HANDLER (t, 0, 0) +{ +} + +// @@ For pluggable protocols, added a reference to the corresponding transport obj. TAO_Server_Connection_Handler::TAO_Server_Connection_Handler (ACE_Thread_Manager *t) - : TAO_SVC_HANDLER (t ? t : TAO_ORB_Core_instance()->thr_mgr (), 0, 0), + : TAO_IIOP_Handler_Base (t ? t : TAO_ORB_Core_instance()->thr_mgr (), 0, 0), orb_core_ (TAO_ORB_Core_instance ()) { + iiop_transport_ = new TAO_IIOP_Server_Transport(this); } +// @@ For pluggable protocols, added a reference to the corresponding transport obj. +//@@ iiop_transport_(new TAO_IIOP_Transport(TAO_IOP_TAG_INTERNET_IOP, this)) TAO_Server_Connection_Handler::TAO_Server_Connection_Handler (TAO_ORB_Core *orb_core) - : TAO_SVC_HANDLER (orb_core->thr_mgr (), 0, 0), + : TAO_IIOP_Handler_Base (orb_core), orb_core_ (orb_core) { + iiop_transport_ = new TAO_IIOP_Server_Transport(this); +} + +TAO_Transport * +TAO_Server_Connection_Handler::transport (void) +{ + // @@ For now return nothing since all is not in place! + return iiop_transport_; } int @@ -385,8 +412,7 @@ TAO_Server_Connection_Handler::send_response (TAO_OutputCDR &output) { ACE_FUNCTION_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_SEND_RESPONSE_START); - TAO_SVC_HANDLER *this_ptr = this; - TAO_GIOP::send_request (this_ptr, + TAO_GIOP::send_request (this->iiop_transport_, output, this->orb_core_); } @@ -487,8 +513,7 @@ TAO_Server_Connection_Handler::send_error (CORBA::ULong request_id, ACE_ENDTRY; // hand it to the next lower layer - TAO_SVC_HANDLER *this_ptr = this; - TAO_GIOP::send_request (this_ptr, output, this->orb_core_); + TAO_GIOP::send_request (this->iiop_transport_, output, this->orb_core_); } } @@ -523,14 +548,13 @@ TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) int result = 0; int error_encountered = 0; CORBA::Boolean response_required = 0; - TAO_SVC_HANDLER *this_ptr = this; CORBA::ULong request_id = 0; ACE_TRY_NEW_ENV { // Try to recv a new request. TAO_GIOP::Message_Type type = - TAO_GIOP::recv_request (this_ptr, input, this->orb_core_); + TAO_GIOP::recv_request (this->iiop_transport_, input, this->orb_core_); // Check to see if we've been cancelled cooperatively. if (this->orb_core_->orb ()->should_shutdown () != 0) @@ -659,11 +683,13 @@ TAO_Server_Connection_Handler::handle_input (ACE_HANDLE) return result; } +// @@ For pluggable protocols, added a reference to the corresponding transport obj. TAO_Client_Connection_Handler::TAO_Client_Connection_Handler (ACE_Thread_Manager *t) - : TAO_SVC_HANDLER (t == 0 ? TAO_ORB_Core_instance ()->thr_mgr () : t, 0, 0), + : TAO_IIOP_Handler_Base (t == 0 ? TAO_ORB_Core_instance ()->thr_mgr () : t, 0, 0), expecting_response_ (0), input_available_ (0) { + iiop_transport_ = new TAO_IIOP_Client_Transport(this); } TAO_ST_Client_Connection_Handler::TAO_ST_Client_Connection_Handler (ACE_Thread_Manager *t) @@ -679,17 +705,30 @@ TAO_MT_Client_Connection_Handler::TAO_MT_Client_Connection_Handler (ACE_Thread_M ACE_SYNCH_CONDITION (TAO_ORB_Core_instance ()->leader_follower_lock ())); } +// @@ Need to get rid of the Transport Objects! TAO_Client_Connection_Handler::~TAO_Client_Connection_Handler (void) { + delete this->iiop_transport_; + this->iiop_transport_ = 0; +} + +TAO_Transport * +TAO_Client_Connection_Handler::transport (void) +{ + return this->iiop_transport_; } TAO_ST_Client_Connection_Handler::~TAO_ST_Client_Connection_Handler (void) { + delete this->iiop_transport_; + this->iiop_transport_ = 0; } TAO_MT_Client_Connection_Handler::~TAO_MT_Client_Connection_Handler (void) { delete this->cond_response_available_; + delete this->iiop_transport_; + this->iiop_transport_ = 0; } int @@ -804,6 +843,9 @@ TAO_Client_Connection_Handler::check_unexpected_data (void) return -1; } +// @@ this seems odd that the connection handler would call methods in the +// GIOP object. Some of this mothod's functionality should be moved +// to GIOP. fredk int TAO_ST_Client_Connection_Handler::send_request (TAO_ORB_Core* orb_core, TAO_OutputCDR &stream, @@ -823,7 +865,7 @@ TAO_ST_Client_Connection_Handler::send_request (TAO_ORB_Core* orb_core, // be dynamically linked in (wouldn't that be cool/freaky?) // Send the request - int success = (int) TAO_GIOP::send_request (this, + int success = (int) TAO_GIOP::send_request (this->iiop_transport_, stream, orb_core); if (!success) @@ -899,7 +941,7 @@ TAO_MT_Client_Connection_Handler::send_request (TAO_ORB_Core *orb_core, if (!is_twoway) { // Send the request - int success = (int) TAO_GIOP::send_request (this, + int success = (int) TAO_GIOP::send_request (this->iiop_transport_, stream, orb_core); @@ -920,7 +962,7 @@ TAO_MT_Client_Connection_Handler::send_request (TAO_ORB_Core *orb_core, this->calling_thread_ = ACE_Thread::self (); // Send the request - int success = (int) TAO_GIOP::send_request (this, + int success = (int) TAO_GIOP::send_request (this->iiop_transport_, stream, orb_core); diff --git a/TAO/tao/Connect.h b/TAO/tao/Connect.h index 634445acbba..ed5fa5d878b 100644 --- a/TAO/tao/Connect.h +++ b/TAO/tao/Connect.h @@ -32,11 +32,25 @@ // Forward Decls class TAO_OA_Parameters; +class TAO_Transport; +class TAO_IIOP_Transport; +class TAO_IIOP_Client_Transport; +class TAO_IIOP_Server_Transport; typedef ACE_Svc_Handler TAO_SVC_HANDLER; -class TAO_Export TAO_Client_Connection_Handler : public TAO_SVC_HANDLER +class TAO_IIOP_Handler_Base : public TAO_SVC_HANDLER +{ +public: + TAO_IIOP_Handler_Base (ACE_Thread_Manager *t); + TAO_IIOP_Handler_Base (TAO_ORB_Core *orb_core); + TAO_IIOP_Handler_Base (ACE_Thread_Manager *t, int x, int y); + + virtual TAO_Transport *transport (void) = 0; +}; + +class TAO_Export TAO_Client_Connection_Handler : public TAO_IIOP_Handler_Base { // = TITLE // used on the client side and returned by the @@ -72,8 +86,15 @@ public: virtual int close (u_long flags = 0); // Object termination hook. + virtual TAO_Transport *transport (void); + protected: + TAO_IIOP_Client_Transport *iiop_transport_; + // @@ New transport object reference. + // The handler is responsible for creating this object when + // it is instantiated. fredk + int check_unexpected_data (void); // This method checks for unexpected data @@ -142,7 +163,7 @@ protected: class TAO_ORB_Core; -class TAO_Export TAO_Server_Connection_Handler : public TAO_SVC_HANDLER +class TAO_Export TAO_Server_Connection_Handler : public TAO_IIOP_Handler_Base { // = TITLE // Handles requests on a single connection in a server. @@ -183,9 +204,14 @@ public: // to zero if the request is for a oneway or // non-zero if for a two-way and to any necessary // response (including errors). In case of errors, -1 is returned - // and additional information carried in . + // and additional information carried in . + + TAO_Transport *transport (void); protected: + TAO_IIOP_Server_Transport *iiop_transport_; + // @@ New transport object reference. + virtual int handle_locate (TAO_InputCDR &msg, TAO_OutputCDR &response, CORBA::Boolean &response_required, @@ -223,8 +249,4 @@ protected: # include "tao/Connect.i" #endif /* __ACE_INLINE__ */ -typedef ACE_Strategy_Acceptor - TAO_ACCEPTOR; - #endif /* TAO_CONNECT_H */ diff --git a/TAO/tao/GIOP.cpp b/TAO/tao/GIOP.cpp index 72438e1fe8a..cd91afe9096 100644 --- a/TAO/tao/GIOP.cpp +++ b/TAO/tao/GIOP.cpp @@ -41,6 +41,12 @@ // @@ there is lots of unverified I/O here. In all cases, if an // error is detected when marshaling or unmarshaling, it should be // reported. +// @@ Some dependance on the specific underlying transport protocol used. +// This must be removed in order to support pluggable protocols. +// TAO_Connector and TAO_Transport objects will be introduced +// to abstract away the specific transport protocol used. We will +// just expose behavior (methods) to all transport protocols that +// can be used with GIOP! fredk #include "tao/corba.h" #include "tao/Timeprobe.h" @@ -182,19 +188,19 @@ operator>>(TAO_InputCDR &cdr, ++i) cdr >> x[i]; } - return cdr.good_bit (); } CORBA::Boolean -TAO_GIOP::send_request (TAO_SVC_HANDLER *handler, +TAO_GIOP::send_request (TAO_Transport *transport, TAO_OutputCDR &stream, TAO_ORB_Core *orb_core) { + ACE_FUNCTION_TIMEPROBE (TAO_GIOP_SEND_REQUEST_START); - char *buf = (char *) stream.buffer (); - size_t buflen = stream.total_length (); + char *buf = (char *) stream.buffer (); // ptr to first buffer + size_t total_len = stream.total_length (); // length of all buffers // assert (buflen == (stream.length - stream.remaining)); @@ -209,15 +215,18 @@ TAO_GIOP::send_request (TAO_SVC_HANDLER *handler, // networking infrastructure (e.g., IPSEC). size_t header_len = TAO_GIOP_HEADER_LEN; + // @@ Ug, not sure what to do with this IIOP specific code! + // An idea would be to change this to ->use_lite_protocol + // that way it is not IIOP specific. fredk size_t offset = TAO_GIOP_MESSAGE_SIZE_OFFSET; - if (orb_core->orb_params ()->use_IIOP_lite_protocol ()) + if (orb_core->orb_params ()->use_lite_protocol ()) { header_len = TAO_IIOP_LITE_HEADER_LEN; offset = TAO_IIOP_LITE_MESSAGE_SIZE_OFFSET; } - CORBA::ULong bodylen = buflen - header_len; - + CORBA::ULong bodylen = total_len - header_len; + #if !defined (TAO_ENABLE_SWAP_ON_WRITE) *ACE_reinterpret_cast(CORBA::ULong*,buf + offset) = bodylen; #else @@ -237,85 +246,35 @@ TAO_GIOP::send_request (TAO_SVC_HANDLER *handler, #if 0 TAO_GIOP::dump_msg ("send", ACE_reinterpret_cast (u_char *, buf), - buflen); -#endif /* 0 */ + total_len); +#endif - TAO_SOCK_Stream &peer = handler->peer (); + // this guarantees to send all data (bytes) or return an error + ssize_t n = transport->send (stream.begin ()); - const int TAO_WRITEV_MAX = IOV_MAX; - iovec iov[TAO_WRITEV_MAX]; - int iovcnt = 0; - - for (const ACE_Message_Block *i = stream.begin (); - i != stream.end (); - i = i->cont ()) - { - iov[iovcnt].iov_base = i->rd_ptr (); - iov[iovcnt].iov_len = i->length (); - iovcnt++; - - // The buffer is full make a OS call. - - // @@ TODO this should be optimized on a per-platform basis, for - // instance, some platforms do not implement writev() there we - // should copy the data into a buffer and call send_n(). In - // other cases there may be some limits on the size of the - // iovec, there we should set TAO_WRITEV_MAX to that limit. - if (iovcnt == TAO_WRITEV_MAX) - { - ssize_t n = peer.sendv_n (iov, - iovcnt); - if (n == -1) - { - if (TAO_orbdebug) - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) closing conn %d after fault %p\n", - peer.get_handle (), - "GIOP::send_request")); - handler->handle_close (); - return 0; - } - else if (n == 0) - { - if (TAO_orbdebug) - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) GIOP::send_request (): " - "EOF, closing conn %d\n", - peer.get_handle ())); - handler->handle_close (); - return 0; - } - - iovcnt = 0; - } + if (n == -1) { + if (TAO_orbdebug) { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) closing conn %d after fault %p\n", + transport->handle (), "GIOP::send_request ()")); } - - if (iovcnt != 0) + transport->close_conn (); + return 0 ; + } + + // @@ Don't know about this one, when will we get a 0 from the write if we + // assume that there is data to write. I would only expect a 0 if there + // was nothing to send or if nonblocking. + if (n == 0) + { + if (TAO_orbdebug) { - ssize_t n = peer.sendv_n (iov, - iovcnt); - if (n == -1) - { - if (TAO_orbdebug) - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) closing conn %d after fault %p\n", - peer.get_handle (), - "GIOP::send_request")); - handler->handle_close (); - return 0; - } - else if (n == 0) - { - if (TAO_orbdebug) - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) GIOP::send_request (): " - "EOF, closing conn %d\n", - peer.get_handle ())); - handler->handle_close (); - return 0; - } - iovcnt = 0; + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) GIOP::send_request (): ", + "EOF, closing conn %d\n", transport->handle())); } + transport->close_conn(); + return 0; + } return 1; } @@ -335,8 +294,8 @@ TAO_GIOP::send_request (TAO_SVC_HANDLER *handler, // orderly disconnect as provided by TCP. This quality of service is // required to write robust distributed systems.) -static const char -close_message [TAO_GIOP_HEADER_LEN] = +// static CORBA::Octet +static const char close_message [TAO_GIOP_HEADER_LEN] = { 'G', 'I', 'O', 'P', TAO_GIOP_MessageHeader::MY_MAJOR, @@ -347,8 +306,7 @@ close_message [TAO_GIOP_HEADER_LEN] = }; void -TAO_GIOP::close_connection (TAO_Client_Connection_Handler *&handler, - void *) +TAO_GIOP::close_connection (TAO_Transport *transport, void *) { // It's important that we use a reliable shutdown after we send this // message, so we know it's received. @@ -360,20 +318,19 @@ TAO_GIOP::close_connection (TAO_Client_Connection_Handler *&handler, (const u_char *) close_message, TAO_GIOP_HEADER_LEN); - ACE_HANDLE which = handler->peer ().get_handle (); - if (handler->peer ().send_n (close_message, - TAO_GIOP_HEADER_LEN) == -1) - { - if (TAO_orbdebug) + // @@ Carlos, can you please check the return value on this? + ACE_HANDLE which = transport->handle (); + if (transport->send ((const u_char *) close_message, TAO_GIOP_HEADER_LEN) == -1) + { + if (TAO_orbdebug) ACE_ERROR ((LM_ERROR, "(%P|%t) error closing connection %d\n", which)); - } - handler->handle_close (); - handler = 0; + } + + transport->close_conn (); ACE_DEBUG ((LM_DEBUG, - "(%P|%t) shut down socket %d\n", - which)); + "(%P|%t) shut down transport, handle %d\n", which)); } // Send an "I can't understand you" message -- again, the message is @@ -394,38 +351,39 @@ error_message [TAO_GIOP_HEADER_LEN] = }; void -TAO_GIOP::send_error (TAO_SVC_HANDLER *&handler) +TAO_GIOP::send_error (TAO_Transport *transport) { TAO_GIOP::dump_msg ("send_error", (const u_char *) error_message, TAO_GIOP_HEADER_LEN); - - ACE_HANDLE which = handler->peer ().get_handle (); - if (handler->peer ().send_n (error_message, - TAO_GIOP_HEADER_LEN) == -1) - { - if (TAO_orbdebug != 0) - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) error sending error to %d\n", - which)); - - } - if (TAO_orbdebug) - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) aborted socket %d\n", - which)); - handler = 0; + ACE_HANDLE which = transport->handle (); + // @@ Carlos, can you please check to see if should have + // it's reply checked? + if (transport->send ((const u_char *)error_message, TAO_GIOP_HEADER_LEN) == -1) + { + if (TAO_orbdebug != 0) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) error sending error to %d\n", + which)); + } + + if (TAO_orbdebug) { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) aborted transport handle %d\n", transport->handle ())); + } + // @@ + transport->close_conn (); + transport = 0; } ssize_t -TAO_GIOP::read_buffer (TAO_SOCK_Stream &peer, +TAO_GIOP::read_buffer (TAO_Transport *transport, char *buf, size_t len) { ACE_FUNCTION_TIMEPROBE (TAO_GIOP_READ_BUFFER_START); - ssize_t bytes_read = peer.recv_n (buf, - len); + ssize_t bytes_read = transport->receive (buf, len); + if (bytes_read == -1 && errno == ECONNRESET) { // We got a connection reset (TCP RSET) from the other side, @@ -459,15 +417,14 @@ TAO_GIOP::read_buffer (TAO_SOCK_Stream &peer, // buffering. How fast could it be with both optimizations applied? TAO_GIOP::Message_Type -TAO_GIOP::recv_request (TAO_SVC_HANDLER *&handler, +TAO_GIOP::recv_request (TAO_Transport *transport, TAO_InputCDR &msg, - TAO_ORB_Core* orb_core) + TAO_ORB_Core* orb_core) { ACE_FUNCTION_TIMEPROBE (TAO_GIOP_RECV_REQUEST_START); TAO_GIOP::Message_Type retval; CORBA::ULong message_size; - TAO_SOCK_Stream &connection = handler->peer (); // Read the message header off the wire. // @@ -482,7 +439,9 @@ TAO_GIOP::recv_request (TAO_SVC_HANDLER *&handler, CDR::mb_align (&msg.start_); ssize_t header_len = TAO_GIOP_HEADER_LEN; - if (orb_core->orb_params ()->use_IIOP_lite_protocol ()) + + // @@ would like to use use_lite_protocol, fredk + if (orb_core->orb_params ()->use_lite_protocol ()) header_len = 5; if (CDR::grow (&msg.start_, @@ -491,7 +450,7 @@ TAO_GIOP::recv_request (TAO_SVC_HANDLER *&handler, return TAO_GIOP::CommunicationError; char *header = msg.start_.rd_ptr (); - ssize_t len = TAO_GIOP::read_buffer (connection, + ssize_t len = TAO_GIOP::read_buffer (transport, header, header_len); // Read the header into the buffer. @@ -503,8 +462,8 @@ TAO_GIOP::recv_request (TAO_SVC_HANDLER *&handler, case 0: if (TAO_orbdebug) ACE_DEBUG ((LM_DEBUG, - "(%t) End of connection %d\n", - connection.get_handle ())); + "(%t) End of connection, transport handle %d\n", + transport->handle ())); return TAO_GIOP::EndOfFile; // @@ should probably find some way to report this without // an exception, since for most servers it's not an error. @@ -542,9 +501,9 @@ TAO_GIOP::recv_request (TAO_SVC_HANDLER *&handler, message_size, orb_core) == -1) { - TAO_GIOP::send_error (handler); - return TAO_GIOP::EndOfFile; - // We didn't really receive anything useful here. + TAO_GIOP::send_error (transport); + return TAO_GIOP::EndOfFile; // We didn't really receive + // anything useful here. } // Make sure we have the full length in memory, growing the buffer @@ -570,7 +529,7 @@ TAO_GIOP::recv_request (TAO_SVC_HANDLER *&handler, // Read the rest of this message into the buffer. - len = TAO_GIOP::read_buffer (connection, + len = TAO_GIOP::read_buffer (transport, payload, (size_t) message_size); @@ -581,8 +540,8 @@ TAO_GIOP::recv_request (TAO_SVC_HANDLER *&handler, case 0: if (TAO_orbdebug) ACE_DEBUG ((LM_DEBUG, - "(%P|%t) TAO_GIOP::recv_request body, EOF on handle %d\n", - connection.get_handle ())); + "(%P|%t) TAO_GIOP::recv_request body, EOF on transport handle %d\n", + transport->handle ())); break; /* NOTREACHED */ case -1: @@ -688,7 +647,7 @@ TAO_GIOP::parse_header (TAO_InputCDR &cdr, CORBA::ULong &message_size, TAO_ORB_Core *orb_core) { - if (orb_core->orb_params ()->use_IIOP_lite_protocol ()) + if (orb_core->orb_params ()->use_lite_protocol ()) return TAO_GIOP::parse_header_lite (cdr, do_byte_swap, message_type, @@ -765,7 +724,7 @@ TAO_GIOP::start_message (TAO_GIOP::Message_Type type, TAO_OutputCDR &msg, TAO_ORB_Core* orb_core) { - if (orb_core->orb_params ()->use_IIOP_lite_protocol ()) + if (orb_core->orb_params ()->use_lite_protocol ()) return TAO_GIOP::start_message_lite (type, msg); else return TAO_GIOP::start_message_std (type, msg); diff --git a/TAO/tao/GIOP.h b/TAO/tao/GIOP.h index fa234570eb4..1f4f2e13bdc 100644 --- a/TAO/tao/GIOP.h +++ b/TAO/tao/GIOP.h @@ -49,6 +49,7 @@ typedef CORBA::ULong TAO_IOP_Profile_ID; enum { + TAO_IOP_TAG_INVALID = -1, // TAO_IOP_TAG_INTERNET_IOP = 0, // IIOP TAO_IOP_TAG_MULTIPLE_COMPONENTS = 1, // DCE-CIOP // = This is a subset of the list of other profile tags. @@ -310,7 +311,7 @@ public: MessageError = 6 // by both. }; - static void close_connection (TAO_Client_Connection_Handler *&handle, + static void close_connection (TAO_Transport *transport, void *ctx); // Close a connection, first sending GIOP::CloseConnection. @@ -319,12 +320,12 @@ public: TAO_ORB_Core* orb_core); // Build the header for a message of type into stream . - static CORBA::Boolean send_request (TAO_SVC_HANDLER *handler, + static CORBA::Boolean send_request (TAO_Transport *transport, TAO_OutputCDR &stream, TAO_ORB_Core* orb_core); // Send message, returns TRUE if success, else FALSE. - static TAO_GIOP::Message_Type recv_request (TAO_SVC_HANDLER *&handler, + static TAO_GIOP::Message_Type recv_request (TAO_Transport *transport, TAO_InputCDR &msg, TAO_ORB_Core *orb_core); // Reads message, returns message type from header. @@ -334,10 +335,10 @@ public: size_t len); // Print out a message header. - static void send_error (TAO_SVC_HANDLER *&handler); + static void send_error (TAO_Transport *transport); // Send an error message back to a caller. - static ssize_t read_buffer (TAO_SOCK_Stream &peer, + static ssize_t read_buffer (TAO_Transport *transport, char *buf, size_t len); // Loop on data read ... this is required since won't block diff --git a/TAO/tao/IIOP_Acceptor.cpp b/TAO/tao/IIOP_Acceptor.cpp new file mode 100644 index 00000000000..47436fddf31 --- /dev/null +++ b/TAO/tao/IIOP_Acceptor.cpp @@ -0,0 +1,40 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// +// = FILENAME +// +// = DESCRIPTION +// +// = AUTHOR +// +// ============================================================================ + +#include "tao/corba.h" + +CORBA::ULong +TAO_IIOP_Acceptor::tag (void) +{ + return this->tag_; +} + +TAO_IIOP_Acceptor::TAO_IIOP_Acceptor (void) + : base_acceptor_ (), + tag_(TAO_IOP_TAG_INTERNET_IOP) +{ +} + +TAO_Profile * +TAO_IIOP_Acceptor::create_profile (TAO_ObjectKey& object_key) +{ + return 0; +} + +ACE_Event_Handler* +TAO_IIOP_Acceptor::acceptor (void) +{ + return &base_acceptor_; +} diff --git a/TAO/tao/IIOP_Acceptor.h b/TAO/tao/IIOP_Acceptor.h new file mode 100644 index 00000000000..a2b48ab77fa --- /dev/null +++ b/TAO/tao/IIOP_Acceptor.h @@ -0,0 +1,55 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// +// = FILENAME +// +// = DESCRIPTION +// +// = AUTHOR +// +// ============================================================================ + +#ifndef TAO_ACCEPTOR_H +# define TAO_ACCEPTOR_H + +#include + +typedef ACE_Strategy_Acceptor + TAO_IIOP_BASE_ACCEPTOR; +// was defined in Conect.h + +// TAO IIOP_Acceptor concrete call defination + +class TAO_Export TAO_IIOP_Acceptor : public TAO_Acceptor +{ +public: + // TAO_IIOP_Acceptor (ACE_INET_Addr &addr); + // Create Acceptor object using addr. + + TAO_IIOP_Acceptor (void); + // Create Acceptor object using addr. + + CORBA::ULong tag (void); + // The tag, each concrete class will have a specific tag value. + + virtual TAO_Profile *create_profile (TAO_ObjectKey& object_key); + // create profile object for this Acceptor using the SAP + // (service access point, Host and Port) and object_key. + + virtual ACE_Event_Handler* acceptor (void); + // Return the underlying acceptor object, ACE_Acceptor + +private: + + TAO_IIOP_BASE_ACCEPTOR base_acceptor_; + + CORBA::ULong tag_; + +}; + +#endif /* TAO_ACCEPTOR_H */ diff --git a/TAO/tao/IIOP_Connector.cpp b/TAO/tao/IIOP_Connector.cpp new file mode 100644 index 00000000000..8449bc31186 --- /dev/null +++ b/TAO/tao/IIOP_Connector.cpp @@ -0,0 +1,231 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// +// = FILENAME +// +// = DESCRIPTION +// +// = AUTHOR +// +// ============================================================================ + +#include "tao/corba.h" + +CORBA::ULong +TAO_IIOP_Connector::tag (void) +{ + return this->tag_; +} + +TAO_IIOP_Connector::TAO_IIOP_Connector (void) + : tag_(TAO_IOP_TAG_INTERNET_IOP), + base_connector_() +{ +} + +TAO_Transport * +TAO_IIOP_Connector::connect(TAO_Profile *profile, CORBA::Environment &env) +{ + if (profile->tag () != TAO_IOP_TAG_INTERNET_IOP) + TAO_THROW_ENV_RETURN (CORBA::INTERNAL (CORBA::COMPLETED_NO), env, 0); + + TAO_IIOP_Profile *iiop_profile = + ACE_dynamic_cast(TAO_IIOP_Profile*,profile); + + if (iiop_profile == 0) + TAO_THROW_ENV_RETURN (CORBA::INTERNAL (CORBA::COMPLETED_NO), env, 0); + + +// Establish the connection and get back a . +// @@ We do not have the ORB core +// #if defined (TAO_ARL_USES_SAME_CONNECTOR_PORT) +// if (this->orb_core_->arl_same_port_connect ()) +// { +// ACE_INET_Addr local_addr (this->orb_core_->orb_params ()->addr ()); +// local_addr.set_port_number (server_addr_p->get_port_number ()); +// +// // Set the local port number to use. +// if (con->connect (iiop_profile->hint (), +// iiop_profile->object_addr (), +// 0, +// local_addr, +// 1) == -1); +// { +// // Give users a clue to the problem. +// ACE_DEBUG ((LM_ERROR, "(%P|%t) %s:%u, connection to " +// "%s failed (%p)\n", +// __FILE__, +// __LINE__, +// iiop_profile->addr_to_string (), +// "errno")); +// +// TAO_THROW_ENV_RETURN_VOID (CORBA::TRANSIENT (CORBA::COMPLETED_NO), env); +// } +// } +// else +//#endif /* TAO_ARL_USES_SAME_CONNECTOR_PORT */ + if (base_connector_.connect (iiop_profile->hint (), + iiop_profile->object_addr ()) == -1) + { // Give users a clue to the problem. + if (TAO_orbdebug) + ACE_DEBUG ((LM_ERROR, "(%P|%t) %s:%u, connection to " + "%s failed (%p)\n", + __FILE__, + __LINE__, + profile->addr_to_string (), + "errno")); + + TAO_THROW_ENV_RETURN (CORBA::TRANSIENT (CORBA::COMPLETED_NO), env, 0); + } + + // the connect call will set the hint () stored in the Profile + // object. + + return iiop_profile->transport (); +} + +int +TAO_IIOP_Connector::open(TAO_Resource_Factory *trf, ACE_Reactor *reactor) +{ + if (this->base_connector_.open (reactor, + trf->get_null_creation_strategy (), + trf->get_cached_connect_strategy (), + trf->get_null_activation_strategy ()) != 0) + return -1; + return 0; +} + +int +TAO_IIOP_Connector::close () +{ + this->base_connector_.close (); + return 0; +} + +int +TAO_IIOP_Connector::preconnect(char* preconnections) +{ +#if 0 + if (preconnections) + { + ACE_INET_Addr dest; + TAO_Client_Connection_Handler *handler; + ACE_Unbounded_Stack handlers; + + char *nextptr = 0; + char *where = 0; + for (where = ACE::strsplit_r (preconnections, ",", nextptr); + where != 0; + where = ACE::strsplit_r (0, ",", nextptr)) + { + char *tport = 0; + char *thost = where; + char *sep = ACE_OS::strchr (where, ':'); + + if (sep) + { + *sep = '\0'; + tport = sep + 1; + + dest.set (ACE_OS::atoi (tport), thost); + + // Try to establish the connection + handler = 0; + if (this->base_connector_.connect (handler, dest) == 0) + { + // Save it for later so we can mark it as idle + handlers.push (handler); + } + else + ACE_ERROR ((LM_ERROR, + "(%P|%t) Unable to preconnect to host '%s', port %d.\n", + dest.get_host_name (), + dest.get_port_number ())); + } + else + ACE_ERROR ((LM_ERROR, + "(%P|%t) Yow! Couldn't find a ':' separator in '%s' spec.\n", + where)); + } + + // Walk the stack of handlers and mark each one as idle now. + handler = 0; + while (handlers.pop (handler) == 0) + handler->idle (); + + } +#else + int successes = 0; + if (preconnections) + { + ACE_INET_Addr dest; + ACE_Unbounded_Stack dests; + + char *nextptr = 0; + char *where = 0; + for (where = ACE::strsplit_r (preconnections, ",", nextptr); + where != 0; + where = ACE::strsplit_r (0, ",", nextptr)) + { + char *tport = 0; + char *thost = where; + char *sep = ACE_OS::strchr (where, ':'); + + if (sep) + { + *sep = '\0'; + tport = sep + 1; + + dest.set (atoi(tport), thost); + dests.push (dest); + } + else + ACE_ERROR ((LM_ERROR, + "(%P|%t) Yow! Couldn't find a ':' separator in '%s' spec.\n", where)); + } + + // Create an array of addresses from the stack, as well as an + // array of eventual handlers. + size_t num_connections = dests.size (); + ACE_INET_Addr *remote_addrs = 0; + TAO_Client_Connection_Handler **handlers = 0; + char *failures = 0; + + ACE_NEW_RETURN (remote_addrs, + ACE_INET_Addr[num_connections], + -1); + ACE_NEW_RETURN (handlers, + TAO_Client_Connection_Handler*[num_connections], + -1); + ACE_NEW_RETURN (failures, + char[num_connections], + -1); + + // Fill in the remote address array + size_t index = 0; + while (dests.pop (remote_addrs[index]) == 0) + handlers[index++] = 0; + + // Finally, try to connect. + this->base_connector_.connect_n (num_connections, + handlers, + remote_addrs, + failures); + // Loop over all the failures and set the handlers that + // succeeded to idle state. + for (index = 0; index < num_connections; index++) + { + if (! failures[index]) + { + handlers[index]->idle (); + successes++; + } + } + } +#endif /* 0 */ + return successes; +} diff --git a/TAO/tao/IIOP_Connector.h b/TAO/tao/IIOP_Connector.h new file mode 100644 index 00000000000..91d750bf245 --- /dev/null +++ b/TAO/tao/IIOP_Connector.h @@ -0,0 +1,52 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// +// = FILENAME +// +// = DESCRIPTION +// +// = AUTHOR +// +// ============================================================================ + +#ifndef IIOP_CONNECTOR_H +# define IIOP_CONNECTOR_H +#include +class TAO_Connector; +class TAO_Client_Connection_Handler; + +typedef ACE_Strategy_Connector + TAO_IIOP_BASE_CONNECTOR; + +class TAO_Export TAO_IIOP_Connector : public TAO_Connector +{ + public: + + TAO_IIOP_Connector (void); + // Constructor. Do we want to pass in the tag here or + // should it be statically defined? + + int preconnect(char* preconnections); + int open(TAO_Resource_Factory *trf, ACE_Reactor *reactor); + int close(void); + CORBA::ULong tag (void); + + TAO_Transport* connect(TAO_Profile *profile, + CORBA::Environment &env); + // connect will be called from TAO_GIOP_Invocation::start + +private: + + CORBA::ULong tag_; + // IIOP tag. + + TAO_IIOP_BASE_CONNECTOR base_connector_; + // The connector initiating connection requests for IIOP. + +}; + +#endif /* IIOP_CONNECTOR_H */ diff --git a/TAO/tao/IIOP_ORB.cpp b/TAO/tao/IIOP_ORB.cpp index 6677ddaabbb..0c9f61dac05 100644 --- a/TAO/tao/IIOP_ORB.cpp +++ b/TAO/tao/IIOP_ORB.cpp @@ -91,20 +91,23 @@ IIOP_ORB::object_to_string (CORBA::Object_ptr obj, // This only works for IIOP objrefs. If we're handed an objref // that's not an IIOP objref, fail -- application must use an // ORB that's configured differently. - IIOP_Object *iiopobj = - ACE_dynamic_cast (IIOP_Object*, obj->_stubobj ()); + // IIOP_Object *iiopobj = + // ACE_dynamic_cast (IIOP_Object*, obj->_stubobj ()); - if (iiopobj == 0) + if (obj->_stubobj () == 0) return CORBA::string_copy ((CORBA::String) iiop_prefix); + TAO_IIOP_Profile *iiop_profile = + ACE_dynamic_cast (TAO_IIOP_Profile *, obj->_stubobj ()->profile_in_use ()); + CORBA::String_var key; TAO_POA::encode_sequence_to_string (key.inout(), - iiopobj->profile.object_key); + iiop_profile->object_key ()); u_int buflen = (ACE_OS::strlen (iiop_prefix) + 1 /* major # */ + 1 /* minor # */ + 2 /* double-slash separator */ + - ACE_OS::strlen (iiopobj->profile.host) + + ACE_OS::strlen (iiop_profile->host_) + 1 /* colon separator */ + 5 /* port number */ + 1 /* slash separator */ + @@ -115,10 +118,11 @@ IIOP_ORB::object_to_string (CORBA::Object_ptr obj, ACE_OS::sprintf (buf, "%s%c.%c//%s:%d/%s", iiop_prefix, - digits [iiopobj->profile.iiop_version.major], - digits [iiopobj->profile.iiop_version.minor], - iiopobj->profile.host, - iiopobj->profile.port, + digits [iiop_profile->version ()->major], + digits [iiop_profile->version ()->minor], + // @@ UGLY! + iiop_profile->host_, + iiop_profile->port_, key.in ()); return buf; } @@ -174,7 +178,7 @@ ior_string_to_object (const char *str, mb.wr_ptr (len); TAO_InputCDR stream (&mb, byte_order); - CORBA::Object_ptr objref; + CORBA::Object_ptr objref=0; if (stream.decode (CORBA::_tc_Object, &objref, 0, env) != CORBA::TypeCode::TRAVERSE_CONTINUE) @@ -184,7 +188,6 @@ ior_string_to_object (const char *str, } // Destringify URL style IIOP objref. - static CORBA::Object_ptr iiop_string_to_object (const char *string, CORBA::Environment &env) @@ -200,77 +203,12 @@ iiop_string_to_object (const char *string, // gets thoroughly excercised/debugged! Without a typeID, the // _narrow will be required to make an expensive remote "is_a" call. + // Now make the IIOP_Object ... IIOP_Object *data; + ACE_NEW_RETURN (data, IIOP_Object ((char *) 0), CORBA::Object::_nil ()); - // null type ID. - ACE_NEW_RETURN (data, IIOP_Object ((char *) 0), - CORBA::Object::_nil ()); - - // Remove the "N.N//" prefix, and verify the version's one - // that we accept - - if (isdigit (string [0]) && isdigit (string [2]) && string [1] == '.' - && string [3] == '/' && string [4] == '/') - { - data->profile.iiop_version.major = (char) (string [0] - '0'); - data->profile.iiop_version.minor = (char) (string [2] - '0'); - string += 5; - } - else - { - env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO)); - data->_decr_refcnt (); - return CORBA::Object::_nil (); - } - - if (data->profile.iiop_version.major != IIOP::MY_MAJOR - || data->profile.iiop_version.minor > IIOP::MY_MINOR) - { - env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO)); - data->_decr_refcnt (); - return CORBA::Object::_nil (); - } - - // Pull off the "hostname:port/" part of the objref - - // Copy the string because we are going to modify it... - CORBA::String_var copy = CORBA::string_dup (string); - - char *start = copy.inout (); - char *cp = ACE_OS::strchr (start, ':'); - if (cp == 0) - { - env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO)); - data->_decr_refcnt (); - return CORBA::Object::_nil (); - } - - data->profile.host = CORBA::string_alloc (1 + cp - start); - for (cp = data->profile.host; - *start != ':'; - *cp++ = *start++) - continue; - - *cp = 0; start++; - - cp = ACE_OS::strchr (start, '/'); - - if (cp == 0) - { - env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO)); - CORBA::string_free (data->profile.host); - data->profile.host = 0; - data->_decr_refcnt (); - return CORBA::Object::_nil (); - } - - data->profile.port = (short) ACE_OS::atoi (start); - data->profile.reset_object_addr (); - start = ++cp; - - // Parse the object key - TAO_POA::decode_string_to_sequence (data->profile.object_key, - start); + // init address info in profile + data->profile_in_use ()->parse_string (string, env); // Create the CORBA level proxy. TAO_ServantBase *servant = @@ -321,9 +259,12 @@ IIOP_ORB::_get_collocated_servant (STUB_Object *sobj) if (this->optimize_collocation_objects_ && sobj != 0) { - IIOP_Object *iiopobj = - ACE_dynamic_cast (IIOP_Object*, sobj); + IIOP_Object *iiopobj = + ACE_dynamic_cast (IIOP_Object*, sobj); + TAO_IIOP_Profile *iiop_profile = + ACE_dynamic_cast (TAO_IIOP_Profile *, sobj->profile_in_use ()); + // Make sure users passed in an IIOP_Object otherwise, we don't // know what to do next. if (iiopobj == 0) @@ -338,27 +279,28 @@ IIOP_ORB::_get_collocated_servant (STUB_Object *sobj) } #if 0 ACE_DEBUG ((LM_DEBUG, - "IIOP_ORB: checking collocation for <%s:%d>\n", - iiopobj->profile.object_addr ().get_host_name (), - iiopobj->profile.object_addr ().get_port_number ())); + "IIOP_ORB: checking collocation for <%s:%d>\n", + iiop_profile->object_addr ().get_host_name(), + iiop_profile->object_addr ().get_port_number())); #endif + CORBA::Environment env; - TAO_ObjectKey_var objkey = iiopobj->key (env); + TAO_ObjectKey_var objkey = iiop_profile->_key (env); if (env.exception ()) { #if 0 ACE_DEBUG ((LM_DEBUG, "IIOP_ORB: cannot find key for <%s:%d>\n", - iiopobj->profile.object_addr ().get_host_name (), - iiopobj->profile.object_addr ().get_port_number ())); + iiop_profile->object_addr ().get_host_name (), + iiop_profile->object_addr ().get_port_number ())); #endif return 0; } // Check if the object requested is a collocated object. TAO_POA *poa = TAO_ORB_Core_instance ()-> - get_collocated_poa (iiopobj->profile.object_addr ()); + get_collocated_poa (iiop_profile->object_addr()); if (poa != 0) { @@ -369,8 +311,8 @@ IIOP_ORB::_get_collocated_servant (STUB_Object *sobj) #if 0 ACE_DEBUG ((LM_DEBUG, "IIOP_ORB: cannot find servant for <%s:%d>\n", - iiopobj->profile.object_addr ().get_host_name (), - iiopobj->profile.object_addr ().get_port_number ())); + iiop_profile->object_addr ().get_host_name (), + iiop_profile->object_addr().get_port_number())); #endif return 0; } @@ -378,8 +320,8 @@ IIOP_ORB::_get_collocated_servant (STUB_Object *sobj) #if 0 ACE_DEBUG ((LM_DEBUG, "IIOP_ORB: object at <%s:%d> is collocated\n", - iiopobj->profile.object_addr ().get_host_name (), - iiopobj->profile.object_addr ().get_port_number ())); + iiop_profile->object_addr().get_host_name(), + iiop_profile->object_addr().get_port_number())); #endif return servant; } diff --git a/TAO/tao/IIOP_Object.cpp b/TAO/tao/IIOP_Object.cpp index f4e5e049d13..ebda9a677fe 100644 --- a/TAO/tao/IIOP_Object.cpp +++ b/TAO/tao/IIOP_Object.cpp @@ -51,27 +51,6 @@ ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_IIOP_Object_Timeprobe_Description, #endif /* ACE_ENABLE_TIMEPROBES */ -void -IIOP::Profile::set (const char *h, - CORBA::UShort p, - const TAO_opaque &key, - const ACE_INET_Addr &addr) -{ - this->port = p; - this->object_addr_ = addr; - - delete [] this->host; - - if (h) - { - ACE_NEW (this->host, - char[ACE_OS::strlen (h) + 1]); - ACE_OS::strcpy (this->host, h); - } - - this->object_key = key; -} - // Quick'n'dirty hash of objref data, for partitioning objrefs into // sets. // @@ -81,24 +60,8 @@ CORBA::ULong IIOP_Object::hash (CORBA::ULong max, CORBA::Environment &env) { - CORBA::ULong hashval; - - env.clear (); - - // Just grab a bunch of convenient bytes and hash them; could do - // more (hostname, full key, exponential hashing) but no real need - // to do so except if performance requires a more costly hash. - - hashval = profile.object_key.length () * profile.port; - hashval += profile.iiop_version.minor; - - if (profile.object_key.length () >= 4) - { - hashval += profile.object_key [1]; - hashval += profile.object_key [3]; - } - - return hashval % max; + // we rely on the profile object to has it's address info + return profile_in_use_->hash (max, env); } int operator==(const TAO_opaque& rhs, @@ -128,13 +91,12 @@ int operator!=(const TAO_opaque& rhs, // object.) // // NOTE that this must NOT go across the network! - +// @@ Not sure what meaning this now has when multiple protocols are used for +// the same object!! CORBA::Boolean IIOP_Object::is_equivalent (CORBA::Object_ptr other_obj, CORBA::Environment &env) { - env.clear (); - if (CORBA::is_nil (other_obj) == 1) return 0; @@ -144,7 +106,7 @@ IIOP_Object::is_equivalent (CORBA::Object_ptr other_obj, return 0; // Compare the profiles - return this->profile == other_iiop_obj->profile; + return this->profile_in_use_->is_equivalent (other_iiop_obj->profile_in_use_, env); } // Memory managment @@ -167,15 +129,77 @@ IIOP_Object::_decr_refcnt (void) return this->refcount_; } + if (this->profile_in_use_ !=0 && + this->profile_in_use_ != this->profile_ && + this->profile_in_use_ != this->fwd_profile_) + { + this->profile_in_use_->reset_hint (); + delete this->profile_in_use_; + } + + this->profile_in_use_ = 0; + + if (this->profile_) + { + this->profile_->reset_hint (); + delete this->profile_; + this->profile_ = 0; + } + + if (fwd_profile_) + { + this->fwd_profile_->reset_hint (); + delete this->fwd_profile_; + this->fwd_profile_ = 0; + } delete this; return 0; } -// TAO extensions -TAO_ObjectKey* -IIOP_Object::key (CORBA::Environment &) +// Note that if the repository ID (typeID) is NULL, it will make +// narrowing rather expensive, though it does ensure that type-safe +// narrowing code gets thoroughly exercised/debugged! Without a +// typeID, the _narrow will be required to make an expensive remote +// "is_a" call. + +IIOP_Object::IIOP_Object (const char *host, + const CORBA::UShort port, + const TAO_ObjectKey &objkey, + char *repository_id) + : STUB_Object (repository_id), + profile_ (0), + profile_in_use_ (0), + fwd_profile_ (0), + fwd_profile_lock_ptr_ (0), + fwd_profile_success_ (0), + // what about ACE_SYNCH_MUTEX refcount_lock_ + refcount_ (1), + use_locate_request_ (0), + first_locate_request_ (0) +{ + profile_ = profile_in_use_ = new TAO_IIOP_Profile (host, port, objkey); + this->fwd_profile_lock_ptr_ = + TAO_ORB_Core_instance ()->client_factory ()->create_iiop_profile_lock (); +} + +// Constructor. It will usually be used by the server side. +IIOP_Object::IIOP_Object (char *repository_id, + const ACE_INET_Addr &addr, + const TAO_ObjectKey &objkey) + : STUB_Object (repository_id), + profile_ (0), + profile_in_use_ (0), + fwd_profile_ (0), + fwd_profile_lock_ptr_ (0), + fwd_profile_success_ (0), + // what about ACE_SYNCH_MUTEX refcount_lock_ + refcount_ (1), + use_locate_request_ (0), + first_locate_request_ (0) { - return new TAO_ObjectKey (this->profile.object_key); + profile_ = profile_in_use_ = new TAO_IIOP_Profile (addr, objkey); + this->fwd_profile_lock_ptr_ = + TAO_ORB_Core_instance ()->client_factory ()->create_iiop_profile_lock (); } // THREADING NOTE: Code below this point is of course thread-safe (at @@ -236,7 +260,7 @@ private: // which does all the work. void -IIOP_Object::do_static_call (CORBA::Environment &env, +IIOP_Object::do_static_call (CORBA::Environment &TAO_IN_ENV, const TAO_Call_Data *info, void** args) @@ -260,9 +284,9 @@ IIOP_Object::do_static_call (CORBA::Environment &env, // Simply let these exceptions propagate up // (if any of them occurs.) - call.start (env); + call.start (TAO_IN_ENV); - status = call.invoke (env); + status = call.invoke (TAO_IN_ENV); this->first_locate_request_ = 0; @@ -291,9 +315,9 @@ IIOP_Object::do_static_call (CORBA::Environment &env, for (;;) { // Start the call by constructing the request message header. - TAO_TRY_VAR_EX (env, SYSEX1) + TAO_TRY_VAR_EX (TAO_IN_ENV, SYSEX1) { - call.start (env); + call.start (TAO_IN_ENV); TAO_CHECK_ENV_EX (SYSEX1); ACE_TIMEPROBE (TAO_IIOP_OBJECT_DO_STATIC_CALL_INVOCATION_START); @@ -315,7 +339,7 @@ IIOP_Object::do_static_call (CORBA::Environment &env, if (this->fwd_profile_success_ == 1) { this->fwd_profile_success_ = 0; - env.clear (); + TAO_IN_ENV.clear (); TAO_GOTO (roundtrip_continue_label); } } @@ -323,14 +347,14 @@ IIOP_Object::do_static_call (CORBA::Environment &env, } TAO_ENDTRY; - this->put_params (env, info, call, args); - TAO_CHECK_ENV_RETURN_VOID (env); + this->put_params (TAO_IN_ENV, info, call, args); + TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); ACE_TIMEPROBE (TAO_IIOP_OBJECT_DO_STATIC_CALL_PUT_PARAMS); - TAO_TRY_VAR_EX (env, SYSEX2) + TAO_TRY_VAR_EX (TAO_IN_ENV, SYSEX2) { - status = call.invoke (info->excepts, info->except_count, env); + status = call.invoke (info->excepts, info->except_count, TAO_IN_ENV); TAO_CHECK_ENV_EX (SYSEX2); } TAO_CATCH (CORBA_SystemException, ex) @@ -350,7 +374,7 @@ IIOP_Object::do_static_call (CORBA::Environment &env, if (this->fwd_profile_success_ == 1) { this->fwd_profile_success_ = 0; - env.clear (); + TAO_IN_ENV.clear (); TAO_GOTO (roundtrip_continue_label); } } @@ -384,7 +408,7 @@ IIOP_Object::do_static_call (CORBA::Environment &env, // (ASG) will do 03/22/98. // @@ IMHO this should be handled in the stub // (coryan) - switch (pdp->tc->kind (env)) + switch (pdp->tc->kind (TAO_IN_ENV)) { case CORBA::tk_string: { @@ -411,7 +435,7 @@ IIOP_Object::do_static_call (CORBA::Environment &env, // different policies for different kinds of // structures). if (pdp->value_size == 0) - call.get_value (pdp->tc, ptr, env); + call.get_value (pdp->tc, ptr, TAO_IN_ENV); else { // @@ (ASG) - I think we must completely @@ -421,12 +445,12 @@ IIOP_Object::do_static_call (CORBA::Environment &env, // assert (value_size == tc->size()); *(void **)ptr = new CORBA::Octet [pdp->value_size]; - call.get_value (pdp->tc, *(void **)ptr, env); + call.get_value (pdp->tc, *(void **)ptr, TAO_IN_ENV); } - if (env.exception ()) + if (TAO_IN_ENV.exception ()) { - dexc (env, "do_static_call, get reply parameter"); + dexc (TAO_IN_ENV, "do_static_call, get reply parameter"); return; } } @@ -438,7 +462,7 @@ IIOP_Object::do_static_call (CORBA::Environment &env, if (status != TAO_GIOP_LOCATION_FORWARD) { // @@ What is the right exception to throw in this case? - env.exception (new CORBA::COMM_FAILURE (CORBA::COMPLETED_MAYBE)); + TAO_IN_ENV.exception (new CORBA::COMM_FAILURE (CORBA::COMPLETED_MAYBE)); return; } TAO_LABEL (roundtrip_continue_label); @@ -452,9 +476,9 @@ IIOP_Object::do_static_call (CORBA::Environment &env, ACE_TIMEPROBE (TAO_IIOP_OBJECT_DO_STATIC_CALL_INVOCATION_CTOR); // Start the call by constructing the request message header. - TAO_TRY_VAR_EX (env, SYSEX3) + TAO_TRY_VAR_EX (TAO_IN_ENV, SYSEX3) { - call.start (env); + call.start (TAO_IN_ENV); TAO_CHECK_ENV_EX (SYSEX3); ACE_TIMEPROBE (TAO_IIOP_OBJECT_DO_STATIC_CALL_INVOCATION_START); } @@ -475,7 +499,7 @@ IIOP_Object::do_static_call (CORBA::Environment &env, if (this->fwd_profile_success_ == 1) { this->fwd_profile_success_ = 0; - env.clear (); + TAO_IN_ENV.clear (); TAO_GOTO (oneway_continue_label); } } @@ -483,11 +507,11 @@ IIOP_Object::do_static_call (CORBA::Environment &env, } TAO_ENDTRY; - this->put_params (env, info, call, args); - TAO_CHECK_ENV_RETURN_VOID (env); + this->put_params (TAO_IN_ENV, info, call, args); + TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); ACE_TIMEPROBE (TAO_IIOP_OBJECT_DO_STATIC_CALL_PUT_PARAMS); - /* TAO_GIOP_ReplyStatusType status = */ call.invoke (env); + /* TAO_GIOP_ReplyStatusType status = */ call.invoke (TAO_IN_ENV); // @@ and lock this if (this->fwd_profile_ != 0) diff --git a/TAO/tao/IIOP_Object.h b/TAO/tao/IIOP_Object.h index f6ea1ff8830..c6048259e84 100644 --- a/TAO/tao/IIOP_Object.h +++ b/TAO/tao/IIOP_Object.h @@ -26,79 +26,6 @@ class TAO_GIOP_Invocation; -class TAO_Export IIOP -{ - // = TITLE - // This class provides a namespace. -public: - // = IIOP Protocol version is distinct from GIOP version. - enum - { - MY_MAJOR = 1, - MY_MINOR = 0 - }; - - struct Version - { - CORBA::Octet major; - CORBA::Octet minor; - - Version (CORBA::Octet maj = MY_MAJOR, - CORBA::Octet min = MY_MINOR); - }; - - struct TAO_Export Profile - // = TITLE - // IOR support ... Profile is encapsulated in an IIOP profile - // entry within an IOR. Note that this structure is specified - // by CORBA 2.0, so we can't screw with it too much. - { - Version iiop_version; - TAO_opaque object_key; - char *host; - CORBA::UShort port; - - Profile (void); - // Default constructor - - Profile (const char *host, - CORBA::UShort port, - const TAO_opaque &object_key, - const ACE_INET_Addr &addr); - // Called by server. - - Profile (const Profile &src); - // Copy constructor. - - ~Profile (void); - // Destructor. - - void reset_object_addr (void); - // Sets cache from and - - ACE_INET_Addr &object_addr (void); - // Returns the for this profile. - - Profile &operator= (const Profile &src); - // copy operator - - int operator== (const Profile &src); - // comparison - - protected: - - void set (const char *h, - CORBA::UShort p, - const TAO_opaque &key, - const ACE_INET_Addr &addr); - // Workhorse - - ACE_INET_Addr object_addr_; - // Cached instance of for use in making - // invocations, etc. - }; -}; - class TAO_Export IIOP_Object : public STUB_Object { // = TITLE @@ -157,30 +84,62 @@ public: // Construct from a repository (type) ID. IIOP_Object (char *repository_id, - const char *host, - CORBA::UShort port, - const TAO_opaque &object_key, - const ACE_INET_Addr &addr); - // Construct from a repository ID and IIOP profile information. + const TAO_Profile *profile); + // Construct from a repository ID and a profile ID. + + IIOP_Object (char *repository_id, + const TAO_Profile &profile); + // Construct from a repository ID and a profile ID. + + // @@ IIOP_Object should take a IIOP_Profile object and not + // this connection specific information like hostname, port etc. + IIOP_Object (const char *host, + const CORBA::UShort p, + const TAO_ObjectKey &objkey, + char *repository_id = 0); + // This constructor will usually be used by the client side. + + IIOP_Object (char *repository_id, + const ACE_INET_Addr &addr, + const TAO_ObjectKey &objkey); + // Constructor used typically by the server side. // = Memory management. virtual CORBA::ULong _incr_refcnt (void); virtual CORBA::ULong _decr_refcnt (void); - virtual TAO_ObjectKey *key (CORBA_Environment &TAO_IN_ENV = CORBA_Environment::default_environment ()); + // @@ Doesn't belong here!! This is profile specific, thus it is now + // kept in the Profile Object! fredk + // TAO_ObjectKey *key (CORBA_Environment &_env = CORBA_Environment::default_environment ()); // Return the object key as an out parameter. Caller should release // return value when finished with it. - IIOP::Profile profile; - // Profile for this object. + TAO_Profile *set_profile_in_use (void); + + TAO_Profile *set_profile_in_use (TAO_Profile *pfile); + // Makes a copy of the profile and frees the existing profile_in_use. - IIOP::Profile *get_fwd_profile (void); + // @@ replaces direct acces to the iiop_profile, the OLD way of + // of doing it! fredk + TAO_Profile *profile_in_use(void); + // returns a pointer to the profile_in_use object. This object + // retains ownership of this object. + + virtual TAO_Profile *get_profile(void); + // returns null if profile_in_use == null + // otherwise return a pointer to a new profile object. + // The caller is responsible for freeing this memory! + + TAO_Profile *get_fwd_profile (void); + //@@ IIOP::Profile *get_fwd_profile (void); // THREAD-SAFE. Returns the current forwarding profile. - IIOP::Profile *get_fwd_profile_i (void); + TAO_Profile *get_fwd_profile_i (void); + //@@ IIOP::Profile *get_fwd_profile_i (void); // NON-THREAD-SAFE. Returns the current forwarding profile. - IIOP::Profile *set_fwd_profile (IIOP::Profile *new_profile); + TAO_Profile *set_fwd_profile (const TAO_Profile *new_profile); + //@@ IIOP::Profile *set_fwd_profile (IIOP::Profile *new_profile); // THREAD-SAFE. Sets a new value for the forwarding profile and // returns the current value. @@ -193,10 +152,20 @@ public: void use_locate_requests (CORBA::Boolean use_it); // set the flags to use locate_requests. - TAO_Client_Connection_Handler *&handler (void); - // Return the pointer by reference. - - void reset_handler (void); + // Previously, the handler pointer was stored here and used as the + // hint when the connect was performed. After the connect it was used + // for communicating with the handler. Now, these operations take + // place via the *selected* profile. Thus there is a + // profile->{hint(),cleanup_hint(),reset_hint(),idle()}. reads and + // writes the the underlying socket are performed using the new + // transport object. profile->transport ().{receive(),send()} + // + // NOTE, After the connection is successful, the selected profile will + // be referenece in + // profile_in_use_, profile_in_use() + + //TAO_Client_Connection_Handler *&handler (void); + //@@ void reset_handler (void); // Reset the . Usually used on errors. protected: @@ -214,7 +183,15 @@ protected: // vs. twoway invocations. protected: - IIOP::Profile *fwd_profile_; + // @@ For now, we keep track of transport specific profiles here, + // but in the next iteration this will go away ... only transport + // neutral info is kept here => IIOP_Object should also go away! + // fredk + TAO_IIOP_Profile *profile_; + TAO_IIOP_Profile *profile_in_use_; + // this is the profile that we are currently sending/receiving with + + TAO_IIOP_Profile *fwd_profile_; // Store the forwarding profile ACE_Lock* fwd_profile_lock_ptr_; @@ -235,13 +212,17 @@ protected: CORBA::Boolean first_locate_request_; // distinguishes the first from following calls - TAO_Client_Connection_Handler *handler_; + // TAO_Client_Connection_Handler *handler_; // This handler is going to be used to keep track of the last client // connection handler used by the stub. It is also used as a "hint" // to the cached connector. Note that all changes to this pointer // are made by the cached connector, i.e., under the lock of the // cached connector. Don't modify this pointer at will except in the // case of error, in which case should be set to zero. + // @@ Change this in order to support pluggable protocols, i.e. multiple + // transport layer protocols at the GIOP level. Replace this with + // a refernece to the TAO_IIOP_Connector object which will reference + // both the new TAO_IIOP_Transport and specific service handler. fredk ~IIOP_Object (void); // Destructor is to be called only through _decr_refcnt() diff --git a/TAO/tao/IIOP_Object.i b/TAO/tao/IIOP_Object.i index 25335384472..60ac259bc7d 100644 --- a/TAO/tao/IIOP_Object.i +++ b/TAO/tao/IIOP_Object.i @@ -1,133 +1,148 @@ // $Id$ -ACE_INLINE -IIOP::Version::Version (CORBA::Octet maj, CORBA::Octet min) - : major (maj), - minor (min) -{ -} +// @@ Get rid of profile specific stuff, it is now in it's own class and +// file. fredk ACE_INLINE -IIOP::Profile::Profile (const char *h, - CORBA::UShort p, - const TAO_opaque &key, - const ACE_INET_Addr &addr) - : host (0) -{ - this->set (h, p, key, addr); -} - -ACE_INLINE -IIOP::Profile::Profile (void) - : host (0), - port (0) -{ -} - -ACE_INLINE -IIOP::Profile::Profile (const IIOP::Profile &src) - : host (0) -{ - this->set (src.host, - src.port, - src.object_key, - src.object_addr_); -} - -ACE_INLINE -IIOP::Profile::~Profile (void) -{ - delete [] this->host; -} - -ACE_INLINE IIOP::Profile & -IIOP::Profile::operator= (const IIOP::Profile &src) -{ - this->set (src.host, - src.port, - src.object_key, - src.object_addr_); - return *this; -} - -ACE_INLINE int -IIOP::Profile::operator== (const IIOP::Profile &rhs) -{ - return - this->object_key == rhs.object_key && - this->port == rhs.port && - ACE_OS::strcmp (this->host, rhs.host) == 0 && - this->iiop_version.minor == rhs.iiop_version.minor && - this->iiop_version.major == rhs.iiop_version.major; -} - -ACE_INLINE void -IIOP::Profile::reset_object_addr (void) +IIOP_Object::~IIOP_Object (void) { - this->object_addr_.set (this->port, this->host); -} + // Cleanup hint + if (profile_in_use_ != 0 && + profile_in_use_ != profile_ && + profile_in_use_ != fwd_profile_) + { + this->profile_in_use_->reset_hint (); + delete this->profile_in_use_; + } + + this->profile_in_use_ = 0; + + if (this->profile_ != 0) + { + this->profile_->reset_hint (); + delete this->profile_; + this->profile_ = 0; + } + + if (this->fwd_profile_) + { + this->fwd_profile_ ->reset_hint (); + delete this->fwd_profile_; + this->fwd_profile_ = 0; + } -ACE_INLINE ACE_INET_Addr & -IIOP::Profile::object_addr (void) -{ - return this->object_addr_; + assert (this->refcount_ == 0); } ACE_INLINE -IIOP_Object::~IIOP_Object (void) +IIOP_Object::IIOP_Object (char *repository_id) + : STUB_Object (repository_id), + profile_ (0), + profile_in_use_ (0), + fwd_profile_ (0), + fwd_profile_lock_ptr_ (0), + fwd_profile_success_ (0), + // what about ACE_SYNCH_MUTEX refcount_lock_ + refcount_ (1), + use_locate_request_ (0), + first_locate_request_ (0) { - assert (this->refcount_ == 0); - delete this->fwd_profile_; - delete this->fwd_profile_lock_ptr_; - - // Cleanup hint - if (this->handler_ != 0) - this->handler_->cleanup_hint (); + this->profile_ = this->profile_in_use_ = new TAO_IIOP_Profile; + this->fwd_profile_lock_ptr_ = + TAO_ORB_Core_instance ()->client_factory ()->create_iiop_profile_lock (); } ACE_INLINE -IIOP_Object::IIOP_Object (char *repository_id) +IIOP_Object::IIOP_Object (char *repository_id, + const TAO_Profile &profile) : STUB_Object (repository_id), + profile_ (0), + profile_in_use_ (0), fwd_profile_ (0), + fwd_profile_lock_ptr_ (0), fwd_profile_success_ (0), + // what about ACE_SYNCH_MUTEX refcount_lock_ refcount_ (1), use_locate_request_ (0), - first_locate_request_ (0), - handler_ (0) + first_locate_request_ (0) { - this->fwd_profile_lock_ptr_ = + // @@ XXX need to verify type and deal with wrong types + const TAO_IIOP_Profile &pfile = ACE_dynamic_cast (const TAO_IIOP_Profile &, profile); + this->profile_ = this->profile_in_use_ = new TAO_IIOP_Profile (pfile); + this->fwd_profile_lock_ptr_ = TAO_ORB_Core_instance ()->client_factory ()->create_iiop_profile_lock (); } ACE_INLINE IIOP_Object::IIOP_Object (char *repository_id, - const char *host, - CORBA::UShort port, - const TAO_opaque &object_key, - const ACE_INET_Addr &addr) + const TAO_Profile *profile) : STUB_Object (repository_id), - profile (host, port, object_key, addr), + profile_ (0), + profile_in_use_ (0), fwd_profile_ (0), + fwd_profile_lock_ptr_ (0), fwd_profile_success_ (0), + // what about ACE_SYNCH_MUTEX refcount_lock_ refcount_ (1), use_locate_request_ (0), - first_locate_request_ (0), - handler_ (0) + first_locate_request_ (0) { + // @@ XXX need to verify type and deal with wrong types + const TAO_IIOP_Profile *pfile = ACE_dynamic_cast (const TAO_IIOP_Profile *, profile); + this->profile_ = this->profile_in_use_ = new TAO_IIOP_Profile (pfile); this->fwd_profile_lock_ptr_ = TAO_ORB_Core_instance ()->client_factory ()->create_iiop_profile_lock (); } +ACE_INLINE +TAO_Profile * +IIOP_Object::profile_in_use (void) +{ + return this->profile_in_use_; +} ACE_INLINE -IIOP::Profile * +TAO_Profile * +IIOP_Object::set_profile_in_use (TAO_Profile *pfile) +{ + if (pfile->tag () == TAO_IOP_TAG_INTERNET_IOP) + { + TAO_IIOP_Profile *p = + ACE_dynamic_cast (TAO_IIOP_Profile *, pfile); + return (this->profile_in_use_ = p); + } else { + return 0; + } +} + +ACE_INLINE +TAO_Profile * +IIOP_Object::set_profile_in_use (void) +{ + return this->profile_in_use_ = this->profile_; +} + +ACE_INLINE +TAO_Profile * +IIOP_Object::get_profile (void) +{ + // @@ should verify type ... but the STUB object needs redoing anyway + // for multiple protocols so willdeal with it then. + if (profile_in_use_) + return new TAO_IIOP_Profile (ACE_dynamic_cast(TAO_IIOP_Profile *, profile_in_use_)); + else + return 0; +} + +ACE_INLINE +TAO_Profile * IIOP_Object::get_fwd_profile_i (void) { return this->fwd_profile_; } ACE_INLINE -IIOP::Profile * +TAO_Profile * IIOP_Object::get_fwd_profile (void) { ACE_MT (ACE_GUARD_RETURN (ACE_Lock, @@ -138,23 +153,28 @@ IIOP_Object::get_fwd_profile (void) } +// set_fwd_profile is currently called with either an arg of NULL +// or with a pointer to another IIOP_Object's profile_in_use_. ACE_INLINE -IIOP::Profile * -IIOP_Object::set_fwd_profile (IIOP::Profile *new_profile) +TAO_Profile * +IIOP_Object::set_fwd_profile (const TAO_Profile *new_profile) { ACE_MT (ACE_GUARD_RETURN (ACE_Lock, guard, *this->fwd_profile_lock_ptr_, 0)); - IIOP::Profile *old = this->fwd_profile_; + TAO_Profile *old = this->fwd_profile_; if (new_profile != 0) { delete this->fwd_profile_; + this->fwd_profile_ = 0; + // @@ HACK, need to verify type here! + const TAO_IIOP_Profile *iiop_pfile = + ACE_dynamic_cast(const TAO_IIOP_Profile *, new_profile); ACE_NEW_RETURN (this->fwd_profile_, - IIOP::Profile (), + TAO_IIOP_Profile(iiop_pfile), 0); - *this->fwd_profile_ = *new_profile; - // use the copy operator on IIOP_Profile + // use the copy constructor! } return old; } @@ -189,17 +209,3 @@ IIOP_Object::use_locate_requests (CORBA::Boolean use_it) this->use_locate_request_ = 0; } } - -ACE_INLINE TAO_Client_Connection_Handler *& -IIOP_Object::handler (void) -{ - return this->handler_; -} - -ACE_INLINE void -IIOP_Object::reset_handler (void) -{ - this->handler_->cleanup_hint (); - this->handler_ = 0; -} - diff --git a/TAO/tao/IIOP_Profile.cpp b/TAO/tao/IIOP_Profile.cpp new file mode 100644 index 00000000000..08388dbed0c --- /dev/null +++ b/TAO/tao/IIOP_Profile.cpp @@ -0,0 +1,626 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// +// = FILENAME +// +// = DESCRIPTION +// +// = AUTHOR +// +// ============================================================================ + +#include "tao/corba.h" + +TAO_IIOP_Profile::TAO_IIOP_Profile (const ACE_INET_Addr& addr, + const char *object_key) + : version_(DEF_IIOP_MAJOR, DEF_IIOP_MINOR), + host_(0), + port_(0), + tag_(TAO_IOP_TAG_INTERNET_IOP), + body_(), + object_key_(), + hint_(0), + object_addr_ (addr) +{ + this->set(addr); + int l = ACE_OS::strlen (object_key); + this->object_key_.length (l); + + for (int i = 0; i < l; ++i) + this->object_key_[i] = object_key[i]; + + this->create_body (); +} + +TAO_IIOP_Profile::TAO_IIOP_Profile (const ACE_INET_Addr& addr, + const TAO_ObjectKey& object_key) + : version_(DEF_IIOP_MAJOR, DEF_IIOP_MINOR), + host_(0), + port_(0), + tag_(TAO_IOP_TAG_INTERNET_IOP), + body_(), + hint_(0), + object_addr_ (addr), + object_key_ (object_key) +{ + this->set(addr); + this->create_body (); +} + +TAO_IIOP_Profile::TAO_IIOP_Profile (const ACE_INET_Addr& addr, + const Version& version, + const char *object_key) + : version_(version), + host_(0), + port_(0), + tag_(TAO_IOP_TAG_INTERNET_IOP), + body_(), + object_key_(), + hint_(0), + object_addr_ (addr) +{ + this->set(addr); + int l = ACE_OS::strlen (object_key); + this->object_key_.length (l); + + for (int i = 0; i < l; ++i) + this->object_key_[i] = object_key[i]; + + this->create_body (); +} + +TAO_IIOP_Profile::TAO_IIOP_Profile (const ACE_INET_Addr& addr, + const Version& version, + const TAO_ObjectKey& object_key) + : version_(version), + host_(0), + port_(0), + tag_(TAO_IOP_TAG_INTERNET_IOP), + body_(), + hint_(0), + object_addr_ (addr), + object_key_ (object_key) +{ + this->set(addr); + this->create_body (); +} + +TAO_IIOP_Profile::TAO_IIOP_Profile (const char* host, + CORBA::UShort port, + const TAO_ObjectKey& object_key) + : version_(DEF_IIOP_MAJOR, DEF_IIOP_MINOR), + host_(0), + port_(port), + tag_(TAO_IOP_TAG_INTERNET_IOP), + body_(), + hint_(0), + object_addr_(port, host), + object_key_(object_key) +{ + + if (host) + { + ACE_NEW (this->host_, + char[ACE_OS::strlen (host) + 1]); + ACE_OS::strcpy (this->host_, host); + } + + this->create_body (); +} + +TAO_IIOP_Profile::TAO_IIOP_Profile (const char* host, + CORBA::UShort port, + const Version& version, + const TAO_ObjectKey& object_key) + : version_(version), + host_(0), + port_(port), + tag_(TAO_IOP_TAG_INTERNET_IOP), + body_(), + hint_(0), + object_key_(object_key), + object_addr_(port, host) +{ + + ACE_NEW (this->host_, + char[ACE_OS::strlen (host) + 1]); + ACE_OS::strcpy (this->host_, host); + + this->create_body (); +} + +TAO_IIOP_Profile::TAO_IIOP_Profile (const TAO_IIOP_Profile *pfile) + : version_(pfile->version_), + host_(0), + port_(pfile->port_), + tag_(pfile->tag_), + body_(pfile->body_), + object_key_(pfile->object_key_), + hint_(0), + object_addr_(pfile->object_addr_) +{ + + ACE_NEW (this->host_, + char[ACE_OS::strlen (pfile->host_) + 1]); + ACE_OS::strcpy (this->host_, pfile->host_); + hint_ = pfile->hint_; + +} + +TAO_IIOP_Profile::TAO_IIOP_Profile (const TAO_IIOP_Profile &pfile) + : version_(pfile.version_), + host_(0), + port_(pfile.port_), + tag_(pfile.tag_), + body_(pfile.body_), + object_key_(pfile.object_key_), + hint_(0), + object_addr_(pfile.object_addr_) +{ + + ACE_NEW (this->host_, + char[ACE_OS::strlen (pfile.host_) + 1]); + ACE_OS::strcpy (this->host_, pfile.host_); + hint_ = pfile.hint_; + +} + +TAO_IIOP_Profile::TAO_IIOP_Profile (const Version &version) + : version_(version), + host_(0), + port_(0), + tag_(TAO_IOP_TAG_INTERNET_IOP), + body_(), + object_key_(), + hint_(0), + object_addr_ () +{ +} + +TAO_IIOP_Profile::TAO_IIOP_Profile (void) + : version_(DEF_IIOP_MAJOR, DEF_IIOP_MINOR), + host_(0), + port_(0), + tag_(TAO_IOP_TAG_INTERNET_IOP), + body_(), + object_key_(), + hint_(0), + object_addr_ () +{ +} + +int +TAO_IIOP_Profile::set (const ACE_INET_Addr& addr) +{ + char temphost[MAXHOSTNAMELEN + 1]; + const char *temphost2 = 0; + + this->port_ = addr.get_port_number(); + + if (TAO_ORB_Core_instance ()->orb_params ()->use_dotted_decimal_addresses ()) + { + temphost2 = addr.get_host_addr (); + if (temphost2 == 0) + return -1; + } + else + { + if (addr.get_host_name (temphost, sizeof temphost) != 0) + return -1; + + temphost2 = temphost; + } + + ACE_NEW_RETURN (this->host_, + char[ACE_OS::strlen (temphost2) + 1], + -1); + ACE_OS::strcpy (this->host_, temphost2); + + return 0; + +} + +TAO_IIOP_Profile:: ~TAO_IIOP_Profile () +{ + delete [] this->host_; + this->host_ = 0; +} + +CORBA::ULong +TAO_IIOP_Profile::tag (void) +{ + return this->tag_; +} + +TAO_Transport * +TAO_IIOP_Profile::transport (void) +{ + // do I need to do a dynamic cast here? + if (hint_) { + return hint_->transport (); + } + return 0; +} + +const TAO_ObjectKey & +TAO_IIOP_Profile::object_key (void) const +{ + return this->object_key_; +} + +TAO_ObjectKey & +TAO_IIOP_Profile::object_key (TAO_ObjectKey& objkey) +{ + this->object_key_ = objkey; + return this->object_key_; +} + +TAO_ObjectKey * +TAO_IIOP_Profile::_key (CORBA::Environment &env) +{ + return new TAO_ObjectKey (this->object_key_); +} + +// return codes: +// -1 -> error +// 0 -> can't understand this version +// 1 -> success. +int +TAO_IIOP_Profile::parse (TAO_InputCDR& cdr, + CORBA::Boolean &continue_decoding, + CORBA::Environment &env) +{ + CORBA::ULong encap_len = cdr.length (); + + // Read and verify major, minor versions, ignoring IIOP + // profiles whose versions we don't understand. + // + // XXX this doesn't actually go back and skip the whole + // encapsulation... + if (!(cdr.read_octet (this->version_.major) + && this->version_.major == TAO_IIOP_Profile::DEF_IIOP_MAJOR + && cdr.read_octet (this->version_.minor) + && this->version_.minor <= TAO_IIOP_Profile::DEF_IIOP_MINOR)) + { + ACE_DEBUG ((LM_DEBUG, "detected new v%d.%d IIOP profile", + this->version_.major, + this->version_.minor)); + return 0; + } + + if (this->host_) { + delete [] this->host_; + this->host_ = 0; + } + + // Get host and port + if (cdr.decode (CORBA::_tc_string, + &this->host_, + 0, + env) != CORBA::TypeCode::TRAVERSE_CONTINUE + || !cdr.read_ushort (this->port_)) + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + ACE_DEBUG ((LM_DEBUG, "error decoding IIOP host/port")); + return -1; + } + + this->object_addr_.set (this->port_, this->host_); + + // ... and object key. + + // @@ This is a hack. This code was moved from encode.cpp + // but it is not clear to me what is going on. So I have + // passed a reference to continue_decoding into this method + // continue_decoding is used in IIOP_Object::decode () + continue_decoding = cdr.decode (TC_opaque, + &this->object_key_, + 0, + env) == CORBA::TypeCode::TRAVERSE_CONTINUE; + + if (cdr.length () != 0) + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + ACE_DEBUG ((LM_DEBUG, + "%d bytes out of %d left after IIOP profile data\n", + cdr.length (), encap_len)); + return -1; + } + return 1; +} + +int +TAO_IIOP_Profile::parse_string (const char *string, + CORBA::Environment &env) +{ + + if (!string || !*string) + return 0; + + // Remove the "N.N//" prefix, and verify the version's one + // that we accept + + if (isdigit (string [0]) && isdigit (string [2]) && string [1] == '.' + && string [3] == '/' && string [4] == '/') + { + this->version_.set_version ((char) (string [0] - '0'), (char) (string [2] - '0')); + string += 5; + } + else + { + env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO)); + } + + if (this->version_.major != TAO_IIOP_Profile::DEF_IIOP_MAJOR + || this->version_.minor > TAO_IIOP_Profile::DEF_IIOP_MINOR) + { + env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO)); + return -1; + } + + // Pull off the "hostname:port/" part of the objref + // Copy the string because we are going to modify it... + CORBA::String_var copy = CORBA::string_dup (string); + + char *start = copy.inout (); + char *cp = ACE_OS::strchr (start, ':'); + + if (cp == 0) + { + env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO)); + return -1; + } + + if (this->host_) + { + delete [] this->host_; + this->host_ = 0; + } + + this->host_ = CORBA::string_alloc (1 + cp - start); + for (cp = this->host_; *start != ':'; *cp++ = *start++) + continue; + + *cp = 0; start++; // increment past : + + cp = ACE_OS::strchr (start, '/'); + + if (cp == 0) + { + env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO)); + CORBA::string_free (this->host_); + return -1; + } + + this->port_ = (CORBA::UShort) ACE_OS::atoi (start); + + this->object_addr_.set (this->port_, this->host_); + + start = ++cp; // increment past the / + + TAO_POA::decode_string_to_sequence (this->object_key_, start); + + return 1; +} + + + + + + +// TAO_InputCDR cdr (body.get_buffer (), body.length (), body[0]); +// +// @@ +// CORBA::Boolean byte_order; +// cdr >> CORBA::Any::to_boolean (byte_order); +// cdr >> this->version_.major; +// cdr >> this->version_.minor; +// cdr >> this->host_ (); +// cdr >> this->port_; +// cdr >> this->object_key_; +// this->object_addr_.set(this->port_, this->host_); +// } + +const TAO_opaque& +TAO_IIOP_Profile::body (void) const +{ + return this->body_; +} + +void +TAO_IIOP_Profile::create_body (void) +{ + TAO_OutputCDR cdr; +} +// @@ +// cdr << TAO_ENCAP_BYTE_ORDER; +// cdr << this->version_.major; +// cdr << this->version_.minor; +// cdr << this->host_; +// cdr << this->port_; +// cdr << this->object_key_; +// +// // Create a copy by making a temporary TAO_opaque object. +// // @@ TODO the CDR stream may contain several fragments, need to +// // merge them... +// this->body_ = TAO_opaque (cdr.length (), // length +// cdr.length (), // maximum +// cdr.buffer (), // buffer +// 0); // not own +// } + +CORBA::Boolean +TAO_IIOP_Profile::is_equivalent (TAO_Profile *other_profile, + CORBA::Environment &env) +{ + env.clear (); + + TAO_IIOP_Profile *iiop_profile = + ACE_dynamic_cast (TAO_IIOP_Profile *, other_profile); + + ACE_ASSERT (iiop_profile->object_key_.length () < UINT_MAX); + + return ( this->tag_ == iiop_profile->tag_ + && this->object_key_ == iiop_profile->object_key_ + && this->port_ == iiop_profile->port_ + && ACE_OS::strcmp (this->host_, iiop_profile->host_) == 0 + && this->version () == iiop_profile->version ()); +} + +CORBA::ULong +TAO_IIOP_Profile::hash (CORBA::ULong max, + CORBA::Environment &env) +{ + CORBA::ULong hashval; + + env.clear (); + + // Just grab a bunch of convenient bytes and hash them; could do + // more (hostname, full key, exponential hashing) but no real need + // to do so except if performance requires a more costly hash. + + hashval = this->object_key_.length () * this->port_; + hashval += this->version_.minor; + + if (this->object_key_.length () >= 4) + { + hashval += this->object_key_ [1]; + hashval += this->object_key_ [3]; + } + + return hashval % max; +} + +ACE_INET_Addr& +TAO_IIOP_Profile::object_addr (const ACE_INET_Addr *addr) +{ + if (addr != 0) + this->object_addr_ = *addr; + else if (this->host_) + this->object_addr_.set (this->port_, this->host_); + return this->object_addr_; +} + +ACE_INET_Addr& +TAO_IIOP_Profile::object_addr (void) +{ + return this->object_addr_; +} + +char * +TAO_IIOP_Profile::addr_to_string(void) +{ + static char s[MAXHOSTNAMELEN + MAXHOSTNAMELEN]; + ACE_OS::sprintf (s, "%s:%d", + this->host_, port_); + return s; +} + +char * +TAO_IIOP_Profile::host (void) +{ + return this->host_; +} + +char * +TAO_IIOP_Profile::host (const char *h) +{ + if (this->host_) + { + delete [] this->host_; + this->host_ = 0; + } + + if (h) + { + ACE_NEW_RETURN (this->host_, + char[ACE_OS::strlen (h) + 1], + 0); + ACE_OS::strcpy (this->host_, h); + } + + return this->host_; +} + +CORBA::UShort +TAO_IIOP_Profile::port (void) +{ + return this->port_; +} + +CORBA::UShort +TAO_IIOP_Profile::port (CORBA::UShort p) +{ + return this->port_ = p; +} + +Version * +TAO_IIOP_Profile::version (void) +{ + return &this->version_; +} + +Version * +TAO_IIOP_Profile::version (Version *v) +{ + this->version_ = *v; + return &this->version_; +} + +void +TAO_IIOP_Profile::reset_hint (void) +{ + if (this->hint_) + { + this->hint_->cleanup_hint (); + this->hint_ = 0; + } +} + +TAO_Client_Connection_Handler *& +TAO_IIOP_Profile::hint(void) +{ + return this->hint_; +} + +TAO_Profile * +TAO_IIOP_Profile::_nil (void) +{ + return (TAO_IIOP_Profile *)0; +} + +TAO_IIOP_Profile & +TAO_IIOP_Profile::operator= (const TAO_IIOP_Profile &src) +{ + this->version_ = src.version_; + + this->object_key_ = src.object_key_; + + this->object_addr_.set (src.object_addr_); + + this->port_ = src.port_; + + if (this->host_) + { + delete [] this->host_; + this->host_ = 0; + } + + if (src.host_) + { + ACE_NEW_RETURN (this->host_, + char[ACE_OS::strlen (src.host_) + 1], + *this); + ACE_OS::strcpy (this->host_, src.host_); + } + + return *this; +} + +// TAO_IIOP_Profile::decode (TAO_InputCDR &str) +// { +// diff --git a/TAO/tao/IIOP_Profile.h b/TAO/tao/IIOP_Profile.h new file mode 100644 index 00000000000..f83b72af625 --- /dev/null +++ b/TAO/tao/IIOP_Profile.h @@ -0,0 +1,140 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// +// = FILENAME +// +// = DESCRIPTION +// +// = AUTHOR +// +// ============================================================================ + +#ifndef IIOP_PROFILE_H +# define IIOP_PROFILE_H + +// TAO IIOP_Profile concrete Profile definitions +class TAO_Export TAO_IIOP_Profile : public TAO_Profile +{ +public: + enum + { + DEF_IIOP_MAJOR = 1, + DEF_IIOP_MINOR = 0 + }; + + TAO_IIOP_Profile (const ACE_INET_Addr& addr, + const char *object_key); + + TAO_IIOP_Profile (const ACE_INET_Addr& addr, + const TAO_ObjectKey& object_key); + + TAO_IIOP_Profile (const ACE_INET_Addr& addr, + const Version& version, + const char *object_key); + + TAO_IIOP_Profile (const ACE_INET_Addr& addr, + const Version& version, + const TAO_ObjectKey& object_key); + + TAO_IIOP_Profile (const char* host, + CORBA::UShort port, + const TAO_ObjectKey& object_key); + + TAO_IIOP_Profile (const char* host, + CORBA::UShort port, + const Version& version, + const TAO_ObjectKey& object_key); + + TAO_IIOP_Profile (const TAO_IIOP_Profile *pfile); + + TAO_IIOP_Profile (const TAO_IIOP_Profile &pfile); + + TAO_IIOP_Profile (const Version& version); + + TAO_IIOP_Profile (void); + + ~TAO_IIOP_Profile (void); + + CORBA::ULong tag (void); + // The tag, each concrete class will have a specific tag value. + + TAO_Transport* transport (void); + + int parse (TAO_InputCDR& cdr, + CORBA::Boolean& continue_decoding, + CORBA::Environment &env); + + int parse_string (const char *string, CORBA::Environment &env); + + const TAO_ObjectKey &object_key (void) const; + TAO_ObjectKey &object_key (TAO_ObjectKey& objkey); + // @@ depricated + TAO_ObjectKey *_key (CORBA::Environment &env); + + const TAO_opaque& body (void) const; + // Create IIOP_Profile Object from marshalled data. + + + CORBA::Boolean is_equivalent (TAO_Profile *other_profile, + CORBA::Environment &env); + + + CORBA::ULong hash (CORBA::ULong max, + CORBA::Environment &env); + + char *addr_to_string(void); + + ACE_INET_Addr &object_addr (const ACE_INET_Addr *addr); + ACE_INET_Addr &object_addr (void); + + char *host (void); + char *host (const char *h); + + CORBA::UShort port (void); + CORBA::UShort port (CORBA::UShort p); + + Version *version (void); + Version *version (Version *v); + + TAO_Client_Connection_Handler *&hint (void); + void reset_hint (void); + + TAO_Profile *_nil (void); + TAO_IIOP_Profile &operator= (const TAO_IIOP_Profile &src); + + // @@ Move these to privte when decode is done! + char *host_; + // Maybe just a to reduce memory allocation.. + CORBA::UShort port_; + // TCP port number + +private: + int set (const ACE_INET_Addr& addr); + + CORBA::ULong tag_; + // The tag, + + TAO_opaque body_; + // marshaled profile (CDR). + + Version version_; + // IIOP version number. + + void create_body (void); + // does the work for add_profile. + + TAO_ObjectKey object_key_; + // object_key associated with this profile. + + ACE_INET_Addr object_addr_; + // Cached instance of for use in making + // invocations, etc. + + TAO_Client_Connection_Handler *hint_; +}; + +#endif /* TAO_PROFILE_H */ diff --git a/TAO/tao/IIOP_Transport.cpp b/TAO/tao/IIOP_Transport.cpp new file mode 100644 index 00000000000..2720ddd1486 --- /dev/null +++ b/TAO/tao/IIOP_Transport.cpp @@ -0,0 +1,271 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// +// = FILENAME +// +// = DESCRIPTION +// +// = AUTHOR +// +// ============================================================================ + +#include "tao/corba.h" + +TAO_IIOP_Transport::TAO_IIOP_Transport (TAO_IIOP_Handler_Base* handler) + : tag_(TAO_IOP_TAG_INTERNET_IOP), + handler_(handler) +{ +} + +TAO_IIOP_Transport::~TAO_IIOP_Transport () +{ +} + +TAO_IIOP_Server_Transport::TAO_IIOP_Server_Transport (TAO_Server_Connection_Handler *handler) + : TAO_IIOP_Transport(handler), + server_handler_ (0) +{ + server_handler_ = handler; +} + +TAO_IIOP_Client_Transport::TAO_IIOP_Client_Transport (TAO_Client_Connection_Handler *handler) + : TAO_IIOP_Transport(handler), + client_handler_ (0) +{ + client_handler_ = handler; +} + +TAO_IIOP_Server_Transport::~TAO_IIOP_Server_Transport () +{ +} + +TAO_IIOP_Client_Transport::~TAO_IIOP_Client_Transport () +{ +} + +CORBA::ULong +TAO_IIOP_Transport::tag (void) +{ + return this->tag_; +} + +TAO_Client_Connection_Handler * +TAO_IIOP_Client_Transport::client_handler (void) +{ + return this->client_handler_; +} + +TAO_Server_Connection_Handler * +TAO_IIOP_Server_Transport::server_handler (void) +{ + return this->server_handler_; +} + +TAO_IIOP_Handler_Base *& +TAO_IIOP_Transport::handler (void) +{ + return this->handler_; +} + +int +TAO_IIOP_Transport::idle (void) +{ + return this->handler_->idle(); +} + +int +TAO_IIOP_Transport::is_nil (TAO_Transport *obj) +{ + return obj == 0; +} + +TAO_Transport * +TAO_IIOP_Transport::_nil (void) +{ + return (TAO_IIOP_Transport *)0; +} + +void +TAO_IIOP_Transport::resume_conn (ACE_Reactor *reactor) +{ + int result = reactor->resume_handler (this->handler_); + // @@ Are these needed!! + ACE_UNUSED_ARG (result); + ACE_ASSERT (result == 0); +} + +void +TAO_IIOP_Transport::close_conn () +{ + this->handler_->handle_close (); +} + +ACE_HANDLE +TAO_IIOP_Transport::handle(void) +{ + return this->handler_->get_handle (); +} + +int +TAO_IIOP_Client_Transport::send_request (TAO_ORB_Core *orb_core, + TAO_OutputCDR &stream, + int twoway) +{ + return this->client_handler_->send_request (orb_core, stream, twoway); +} + +// int +// TAO_IIOP_Server_Transport::send_response (TAO_OutputCDR &response) +// { +// this->server_handler_->send_response (response); +// return 1; +// } + +// @@ TODO: this is a good candidate for an ACE routine, even more, +// all the code to write a Message_Block chain could be encapsulated +// in ACE. +ssize_t +TAO_IIOP_Transport::do_sendv (const iovec *iov, int iovcnt, int total_bytes) +{ + ssize_t writelen = 0; + ACE_HANDLE h = this->handler_->get_handle (); + + // @@ would using writev instead of readv affect performance + // on WIN32?? fredk + ssize_t n = ACE_OS::sendv (h, iov, iovcnt); + + if (n == -1 || n == total_bytes) + { + // either an error occured or we sent all the bytes! + // in either case we are done. + return n; + } + + // for some reason we didn't send all the data. Keep trying. + // should be the exception ... we also copy the iovec to a temp + // var so it can be manipulated without violating the const'ness + // of iov. + iovec *tmp_iov = ACE_const_cast(iovec *, iov); + writelen = n; + int s = 0; + ssize_t offset = n; + + // iovcnt > 0, iov{0] ... iov[iovcnt-1] + while ( writelen < total_bytes ) + { + // if n < iov_len then not all the bytes were sent from the current iov buf + // NOTE, we do a ACE_const_cast so that we can have n = -1. That is, iov_len + // is an unsigned long but n is a signed long. + while (s < iovcnt && offset >= tmp_iov[s].iov_len) + { + offset -= tmp_iov[s].iov_len; + s++; + } // while + + char* base = ACE_reinterpret_cast (char*, tmp_iov[s].iov_base); + size_t len = tmp_iov[s].iov_len; + + tmp_iov[s].iov_base = base + offset; + tmp_iov[s].iov_len = len - offset; + n = ACE_OS::sendv (h, (const iovec *)(iov + s), iovcnt - s); + tmp_iov[s].iov_base = base; + tmp_iov[s].iov_len = len; + + if ( n == -1 ) + return n; + + offset += n; + writelen += n; + + } // outer while (s < iovcnt), that is send *all* data! + return writelen; +} + +ssize_t +TAO_IIOP_Transport::send (const ACE_Message_Block *mblk) +{ +// if ( this->handler_ == 0) +// return -1; + // For the most part this was copied from GIOP::send_request + // and friends. + const int TAO_WRITEV_MAX = 16; + iovec iov[TAO_WRITEV_MAX]; + int iovcnt = 0, totlen=0; + ssize_t n=0, nbytes=0; + for (const ACE_Message_Block *i = mblk; i ; i = i->cont ()) { + // Make sure there is something to send! + if (i->length () > 0) { + iov[iovcnt].iov_base = i->rd_ptr (); + iov[iovcnt].iov_len = i->length (); + totlen += i->length (); + iovcnt++; + + + // The buffer is full make a OS call. + // @@ TODO this should be optimized on a per-platform basis, for + // instance, some platforms do not implement writev() there we + // should copy the data into a buffer and call send_n(). In + // other cases there may be some limits on the size of the + // iovec, there we should set TAO_WRITEV_MAX to that limit. + if (iovcnt == TAO_WRITEV_MAX) + { + if ( (n = do_sendv ((const iovec *) iov, iovcnt, totlen)) < 1) + return n; + + nbytes += n; + iovcnt = totlen = 0; + + } // iovcnt == TAO_WRITEV_MAX + } // i->length () > 0 + } // for ( over message blocks, in groups of TAO_WRITEV_MAX ) + + // check for remaining buffers to be sent! + if (iovcnt != 0) + { + if ( (n = do_sendv ((const iovec *)iov, iovcnt, totlen)) < 0 ) + return 0; + + nbytes += n; + + } // iovcnt != 0 + + return nbytes; // success +} + +ssize_t +TAO_IIOP_Transport::send (const u_char *buf, size_t len) +{ + // @@ could have used handler_->peer()->send_n() + return ACE::send_n (this->handler_->get_handle(), buf, len); +} + +ssize_t +TAO_IIOP_Transport::send (const iovec *iov, int iovcnt) +{ + int totlen = 0; + for (int i = 0; i <= iovcnt ; i++) + totlen += iov[i].iov_len; + return do_sendv (iov, iovcnt, totlen); +} + +ssize_t +TAO_IIOP_Transport::receive(char *buf, size_t len) +{ + return ACE::recv_n (this->handler_->get_handle (), buf, len); +} + +ssize_t +TAO_IIOP_Transport::receive(char *buf, size_t len, int flags) +{ + return ACE::recv_n (this->handler_->get_handle (), buf, len, flags); +} + +ssize_t +TAO_IIOP_Transport::receive(iovec *iov, int iovcnt) +{ + return ACE_OS::readv(this->handler_->get_handle (), iov, iovcnt); +} diff --git a/TAO/tao/IIOP_Transport.h b/TAO/tao/IIOP_Transport.h new file mode 100644 index 00000000000..b69b9ea0e39 --- /dev/null +++ b/TAO/tao/IIOP_Transport.h @@ -0,0 +1,105 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// +// = FILENAME +// +// = DESCRIPTION +// +// = AUTHOR +// +// ============================================================================ + +#ifndef IIOP_TRANSPORT_H +# define IIOP_TRANSPORT_H + +class TAO_Transport; + +class TAO_IIOP_Transport : public TAO_Transport +{ +public: + + TAO_IIOP_Transport (TAO_IIOP_Handler_Base* handler); + ~TAO_IIOP_Transport (); + + CORBA::ULong tag (void); + + void close_conn (void); + void resume_conn (ACE_Reactor *reactor); + + int idle (void); + + TAO_IIOP_Handler_Base*& handler (void); + virtual int is_nil (TAO_Transport *obj); + virtual TAO_Transport *_nil (void); + + ACE_HANDLE handle(void); + + virtual ssize_t send (const ACE_Message_Block *mblk); + virtual ssize_t send (const u_char *buf, size_t len); + virtual ssize_t send (const iovec *iov, int iovcnt); + + virtual ssize_t receive (char *buf, size_t len); + virtual ssize_t receive (char *buf, size_t len, int flags); + virtual ssize_t receive (iovec *iov, int iovcnt); + + int send_request (TAO_ORB_Core *orb_core, + TAO_OutputCDR &stream, + int twoway) {return -1;}; + +protected: + + TAO_IIOP_Handler_Base *handler_; + // the connection service handler used for accessing + // lower layer communication protocols. + + CORBA::ULong tag_; + // IIOP tag. + + ssize_t do_sendv (const iovec *iov, int iovcnt, int total_bytes); + +}; + +class TAO_IIOP_Client_Transport : public TAO_IIOP_Transport +{ +public: + + TAO_IIOP_Client_Transport (TAO_Client_Connection_Handler *handler); + // constructor. Note, TAO_IIOP_Handler_Base is the base + // class for both TAO_Client_Connection_Handler and + // TAO_Server_Connection_Handler. + + ~TAO_IIOP_Client_Transport(); + // destructor + + TAO_Client_Connection_Handler* client_handler (void); + + int send_request (TAO_ORB_Core *orb_core, + TAO_OutputCDR &stream, + int twoway); +private: + TAO_Client_Connection_Handler *client_handler_; +}; + +class TAO_IIOP_Server_Transport : public TAO_IIOP_Transport +{ +public: + + TAO_IIOP_Server_Transport (TAO_Server_Connection_Handler *handler); + + ~TAO_IIOP_Server_Transport (); + // destructor + + TAO_Server_Connection_Handler* server_handler (void); + +// virtual int send_response (TAO_OutputCDR &response); + +private: + TAO_Server_Connection_Handler *server_handler_; +}; + +#endif /* IIOP_TRANSPORT_H */ + diff --git a/TAO/tao/Invocation.cpp b/TAO/tao/Invocation.cpp index 5a4b170c5ff..15f7f05e260 100644 --- a/TAO/tao/Invocation.cpp +++ b/TAO/tao/Invocation.cpp @@ -84,10 +84,11 @@ TAO_GIOP_Invocation::TAO_GIOP_Invocation (IIOP_Object *data, ACE_MIN (sizeof (me), sizeof (this->my_request_id_))); } +// @@ this should be a call to the transport object's idle() method. fredk TAO_GIOP_Invocation::~TAO_GIOP_Invocation (void) { - if (this->data_->handler () != 0) - this->data_->handler ()->idle (); + if (this->data_->profile_in_use ()->transport () != 0) + this->data_->profile_in_use ()->transport ()->idle (); } // The public API involves creating an invocation, starting it, filling @@ -125,81 +126,11 @@ TAO_GIOP_Invocation::start (CORBA::Boolean is_roundtrip, if (this->data_ == 0) TAO_THROW (CORBA::MARSHAL (CORBA::COMPLETED_NO)); - // Get a pointer to the connector, which might be in thread-specific - // storage, depending on the concurrency model. - TAO_CONNECTOR *con = this->orb_core_->connector (); - - // Determine the object key and the address to which we'll need a - // connection. - const TAO_opaque *key; - ACE_INET_Addr *server_addr_p = 0; - - { - ACE_MT (ACE_GUARD (ACE_Lock, guard, data_->get_fwd_profile_lock ())); - - if (data_->get_fwd_profile_i () != 0) - { - key = &data_->get_fwd_profile_i ()->object_key; - server_addr_p = &data_->get_fwd_profile_i ()->object_addr (); - } - else - { - key = &data_->profile.object_key; - server_addr_p = &data_->profile.object_addr (); - } - } - - if (server_addr_p == 0) - TAO_THROW (CORBA::INTERNAL (CORBA::COMPLETED_NO)); - - // Establish the connection and get back a - // . -#if defined (TAO_ARL_USES_SAME_CONNECTOR_PORT) - if (this->orb_core_->arl_same_port_connect ()) - { - ACE_INET_Addr local_addr (this->orb_core_->orb_params ()->addr ()); - local_addr.set_port_number (server_addr_p->get_port_number ()); - - // Set the local port number to use. - - if (con->connect (this->data_->handler (), - *server_addr_p, - 0, - local_addr, - 1) == -1) - { - // Give users a clue to the problem. - ACE_DEBUG ((LM_ERROR, "(%P|%t) %s:%u, connection to " - "%s (%s):%hu failed (%p) (using local port #: %d)\n", - __FILE__, - __LINE__, - server_addr_p->get_host_name (), - server_addr_p->get_host_addr (), - server_addr_p->get_port_number (), - local_addr.get_port_number (), - "errno")); - - TAO_THROW (CORBA::TRANSIENT (CORBA::COMPLETED_NO)); - } - } - else -#endif /* TAO_ARL_USES_SAME_CONNECTOR_PORT */ - if (con->connect (this->data_->handler (), - *server_addr_p) == -1) - { - // Give users a clue to the problem. - if (TAO_orbdebug) - ACE_DEBUG ((LM_ERROR, "(%P|%t) %s:%u, connection to " - "%s (%s):%hu failed (%p)\n", - __FILE__, - __LINE__, - server_addr_p->get_host_name (), - server_addr_p->get_host_addr (), - server_addr_p->get_port_number (), - "errno")); - - TAO_THROW (CORBA::TRANSIENT (CORBA::COMPLETED_NO)); - } + // Get a pointer to the connector registry, which might be in + // thread-specific storage, depending on the concurrency model. + TAO_Connector_Registry *conn_reg = this->orb_core_->connector_registry (); + TAO_Profile *profile = conn_reg->connect (this->data_, TAO_IN_ENV); + const TAO_ObjectKey *key = &profile->object_key(); ACE_TIMEPROBE (TAO_GIOP_INVOCATION_START_CONNECT); @@ -325,7 +256,7 @@ TAO_GIOP_Invocation::write_request_header const char* opname, CORBA::Principal_ptr principal) { - if (this->orb_core_->orb_params ()->use_IIOP_lite_protocol ()) + if (this->orb_core_->orb_params ()->use_lite_protocol ()) return this->write_request_header_lite (svc_ctx, request_id, is_roundtrip, @@ -351,13 +282,20 @@ TAO_GIOP_Invocation::invoke (CORBA::Boolean is_roundtrip, { // Send Request, return on error or if we're done - if (this->data_->handler ()->send_request (this->orb_core_, - this->out_stream_, - is_roundtrip) == -1) + TAO_Transport *transport = this->data_->profile_in_use ()->transport (); + // @@ This should be call to GIOP::send_request and not + // handler(). All the Invocation processing must be isolated + // from transport specific processing! fredk + // @@ UGLY!! + if (transport == 0 || + transport->send_request (this->orb_core_, + this->out_stream_, + is_roundtrip) == -1) { // send_request () closed the connection; we just set the // handler to 0 here. - this->data_->reset_handler (); + // @@ STILL UGLY + this->data_->profile_in_use ()->reset_hint (); // // @@ highly desirable to know whether we wrote _any_ data; if @@ -397,16 +335,18 @@ TAO_GIOP_Invocation::close_connection (void) data_->get_fwd_profile_lock (), TAO_GIOP_SYSTEM_EXCEPTION)); - IIOP::Profile *old = data_->set_fwd_profile (0); + TAO_Profile *old = data_->set_fwd_profile (0); delete old; + old = 0; // sets the forwarding profile to 0 and deletes the old one; data_->reset_first_locate_request (); // resets the flag of the first call locate request to true } - this->data_->handler ()->handle_close (); - this->data_->reset_handler (); + // @@ get rid of transport/handler specific code here! fredk + this->data_->profile_in_use ()->transport ()->close_conn (); + this->data_->profile_in_use ()->reset_hint (); return TAO_GIOP_LOCATION_FORWARD; } @@ -425,6 +365,7 @@ TAO_GIOP_Invocation::location_forward (TAO_InputCDR &inp_stream, // This object pointer will be now extracted. CORBA::Object_ptr object_ptr = 0; + TAO_Transport *transport = this->data_->profile_in_use ()->transport (); TAO_TRY_VAR (TAO_IN_ENV) { @@ -438,20 +379,22 @@ TAO_GIOP_Invocation::location_forward (TAO_InputCDR &inp_stream, { // Handle the exception for this level here and throw it out again. dexc (TAO_TRY_ENV, "invoke, location forward (decode)"); - this->data_->handler ()->handle_close (); + transport->close_conn (); TAO_RETHROW_SAME_ENV_RETURN (TAO_GIOP_SYSTEM_EXCEPTION); } TAO_ENDTRY; - // The object pointer has to be changed to a IIOP_Object pointer + // The object pointer has to be changed to a STUB_Object pointer // in order to extract the profile. - IIOP_Object *iiopobj = - ACE_dynamic_cast (IIOP_Object *, object_ptr->_stubobj ()); + STUB_Object *stubobj = object_ptr->_stubobj (); + // @@ ACE_dynamic_cast (STUB_Object*, object_ptr->_stubobj ()); - if (iiopobj == 0) + if (stubobj == 0) { - this->data_->handler ()->handle_close (); + // @@ or this->data_->transport()->close_conn (); + // @@ or this->data_->hint ()->handle_close (); + transport->close_conn (); TAO_THROW_RETURN (CORBA::UNKNOWN (CORBA::COMPLETED_NO), TAO_GIOP_SYSTEM_EXCEPTION); } @@ -466,7 +409,9 @@ TAO_GIOP_Invocation::location_forward (TAO_InputCDR &inp_stream, // related to correctness.) // the copy method on IIOP::Profile will be used to copy the content - data_->set_fwd_profile (&iiopobj->profile); + + // @@ Ug, what is going on here, fredk + data_->set_fwd_profile (stubobj->profile_in_use ()); // store the new profile in the forwarding profile // note: this has to be and is thread safe @@ -529,15 +474,16 @@ TAO_GIOP_Twoway_Invocation::invoke (CORBA::ExceptionList &exceptions, // (explicitly coded) handlers called. We assume a POSIX.1c/C/C++ // environment. - TAO_SVC_HANDLER *handler = this->data_->handler (); - TAO_GIOP::Message_Type m = TAO_GIOP::recv_request (handler, + TAO_Transport *transport = this->data_->profile_in_use ()->transport (); + TAO_GIOP::Message_Type m = TAO_GIOP::recv_request (transport, this->inp_stream_, this->orb_core_); + // @@ More ugliness, having to deal withe the handler here! + // @@ this->orb_core_->reactor ()->resume_handler (transport->handler ()); + transport->resume_conn (this->orb_core_->reactor ()); + // suspend was called in TAO_Client_Connection_Handler::handle_input - int result = this->orb_core_->reactor ()->resume_handler (handler); - ACE_UNUSED_ARG (result); - ACE_ASSERT (result == 0); switch (m) { @@ -572,7 +518,7 @@ TAO_GIOP_Twoway_Invocation::invoke (CORBA::ExceptionList &exceptions, case TAO_GIOP::EndOfFile: // @@ This should only refer to "getting GIOP MessageError" message only. - this->data_->handler ()->handle_close (); + transport->close_conn (); TAO_THROW_RETURN (CORBA::COMM_FAILURE (CORBA::COMPLETED_MAYBE), TAO_GIOP_SYSTEM_EXCEPTION); } @@ -607,7 +553,7 @@ TAO_GIOP_Twoway_Invocation::invoke (CORBA::ExceptionList &exceptions, this->inp_stream_ >> reply_ctx; if (!this->inp_stream_.good_bit ()) { - this->data_->handler ()->handle_close (); + transport->close_conn (); TAO_THROW_RETURN (CORBA::MARSHAL (CORBA::COMPLETED_NO), TAO_GIOP_SYSTEM_EXCEPTION); } @@ -616,7 +562,7 @@ TAO_GIOP_Twoway_Invocation::invoke (CORBA::ExceptionList &exceptions, || !this->inp_stream_.read_ulong (reply_status) || reply_status > TAO_GIOP_LOCATION_FORWARD) { - this->data_->handler ()->handle_close (); + transport->close_conn (); ACE_DEBUG ((LM_DEBUG, "(%P|%t) bad Response header\n")); TAO_THROW_RETURN (CORBA::COMM_FAILURE (CORBA::COMPLETED_MAYBE), TAO_GIOP_SYSTEM_EXCEPTION); } @@ -659,7 +605,7 @@ TAO_GIOP_Twoway_Invocation::invoke (CORBA::ExceptionList &exceptions, { if (this->inp_stream_.read_string (buf) == 0) { - this->data_->handler ()->handle_close (); + transport->close_conn (); TAO_THROW_RETURN (CORBA::MARSHAL (CORBA::COMPLETED_YES), TAO_GIOP_SYSTEM_EXCEPTION); } } @@ -722,7 +668,7 @@ TAO_GIOP_Twoway_Invocation::invoke (CORBA::ExceptionList &exceptions, } TAO_CATCH (CORBA_SystemException, ex) { - this->data_->handler ()->handle_close (); + transport->close_conn (); TAO_RETHROW_SAME_ENV_RETURN (TAO_GIOP_SYSTEM_EXCEPTION); } TAO_ENDTRY; @@ -773,6 +719,9 @@ TAO_GIOP_Twoway_Invocation::invoke (TAO_Exception_Data *excepts, TAO_CHECK_RETURN (retval); ACE_UNUSED_ARG (retval); + TAO_Profile *profile = this->data_->profile_in_use (); + TAO_Transport *transport = profile->transport (); + // This blocks until the response is read. In the current version, // there is only one client thread that ever uses this connection, // so most response messages are illegal. @@ -809,15 +758,12 @@ TAO_GIOP_Twoway_Invocation::invoke (TAO_Exception_Data *excepts, // (explicitly coded) handlers called. We assume a POSIX.1c/C/C++ // environment. - TAO_SVC_HANDLER *handler = this->data_->handler (); - TAO_GIOP::Message_Type m = TAO_GIOP::recv_request (handler, + TAO_GIOP::Message_Type m = TAO_GIOP::recv_request (transport, this->inp_stream_, this->orb_core_); // suspend was called in TAO_Client_Connection_Handler::handle_input - int result = this->orb_core_->reactor ()->resume_handler (handler); - ACE_UNUSED_ARG (result); - ACE_ASSERT (result == 0); + transport->resume_conn (this->orb_core_->reactor ()); switch (m) { @@ -852,7 +798,7 @@ TAO_GIOP_Twoway_Invocation::invoke (TAO_Exception_Data *excepts, case TAO_GIOP::EndOfFile: // @@ This should only refer to "getting GIOP MessageError" message only. - this->data_->handler ()->handle_close (); + transport->close_conn (); TAO_THROW_RETURN (CORBA::COMM_FAILURE (CORBA::COMPLETED_MAYBE), TAO_GIOP_SYSTEM_EXCEPTION); } @@ -887,7 +833,7 @@ TAO_GIOP_Twoway_Invocation::invoke (TAO_Exception_Data *excepts, this->inp_stream_ >> reply_ctx; if (!this->inp_stream_.good_bit ()) { - this->data_->handler ()->handle_close (); + transport->close_conn (); TAO_THROW_RETURN (CORBA::MARSHAL (CORBA::COMPLETED_NO), TAO_GIOP_SYSTEM_EXCEPTION); } @@ -896,7 +842,7 @@ TAO_GIOP_Twoway_Invocation::invoke (TAO_Exception_Data *excepts, || !this->inp_stream_.read_ulong (reply_status) || reply_status > TAO_GIOP_LOCATION_FORWARD) { - this->data_->handler ()->handle_close (); + transport->close_conn (); ACE_DEBUG ((LM_DEBUG, "(%P|%t) bad Response header\n")); TAO_THROW_RETURN (CORBA::COMM_FAILURE (CORBA::COMPLETED_MAYBE), TAO_GIOP_SYSTEM_EXCEPTION); } @@ -939,7 +885,7 @@ TAO_GIOP_Twoway_Invocation::invoke (TAO_Exception_Data *excepts, { if (this->inp_stream_.read_string (buf) == 0) { - this->data_->handler ()->handle_close (); + this->data_->profile_in_use ()->transport ()->close_conn (); TAO_THROW_RETURN (CORBA::MARSHAL (CORBA::COMPLETED_YES), TAO_GIOP_SYSTEM_EXCEPTION); } } @@ -1003,7 +949,7 @@ TAO_GIOP_Twoway_Invocation::invoke (TAO_Exception_Data *excepts, } TAO_CATCH (CORBA_SystemException, ex) { - this->data_->handler ()->handle_close (); + this->data_->profile_in_use ()->transport ()->close_conn (); TAO_RETHROW_SAME_ENV_RETURN (TAO_GIOP_SYSTEM_EXCEPTION); } TAO_ENDTRY; @@ -1046,26 +992,28 @@ TAO_GIOP_Locate_Request_Invocation::invoke (CORBA::Environment &TAO_IN_ENV) { // Send Request, return on error or if we're done - if (this->data_->handler ()->send_request (this->orb_core_, - this->out_stream_, - 1) == -1) + TAO_Profile *profile = this->data_->profile_in_use (); + TAO_Transport *transport = profile->transport (); + + // @@ This appears broken, the send_request returns -1 + if (transport->send_request (this->orb_core_, + this->out_stream_, + 1) == -1) { // send_request () closed the connection; we just set the // handler to 0 here. - this->data_->reset_handler (); + profile->reset_hint (); TAO_IN_ENV.exception (new CORBA::TRANSIENT (CORBA::COMPLETED_MAYBE)); return TAO_GIOP_SYSTEM_EXCEPTION; } - TAO_SVC_HANDLER *handler = this->data_->handler (); - TAO_GIOP::Message_Type m = TAO_GIOP::recv_request (handler, + TAO_GIOP::Message_Type m = TAO_GIOP::recv_request (transport, this->inp_stream_, this->orb_core_); + transport->resume_conn (this->orb_core_->reactor ()); + // suspend was called in TAO_Client_Connection_Handler::handle_input - int result = this->orb_core_->reactor ()->resume_handler (handler); - ACE_UNUSED_ARG (result); - ACE_ASSERT (result == 0); switch (m) { @@ -1083,7 +1031,7 @@ TAO_GIOP_Locate_Request_Invocation::invoke (CORBA::Environment &TAO_IN_ENV) || request_id != this->my_request_id_ || !this->inp_stream_.read_ulong (locate_status)) { - this->data_->handler ()->handle_close (); + transport->close_conn (); ACE_DEBUG ((LM_DEBUG, "(%P|%t) bad Response header\n")); TAO_THROW_RETURN (CORBA::COMM_FAILURE (CORBA::COMPLETED_MAYBE), TAO_GIOP_SYSTEM_EXCEPTION); @@ -1124,7 +1072,7 @@ TAO_GIOP_Locate_Request_Invocation::invoke (CORBA::Environment &TAO_IN_ENV) case TAO_GIOP::EndOfFile: // @@ This should only refer to "getting GIOP MessageError" message only. - this->data_->handler ()->handle_close (); + transport->close_conn (); TAO_THROW_RETURN (CORBA::COMM_FAILURE (CORBA::COMPLETED_MAYBE), TAO_GIOP_SYSTEM_EXCEPTION); } diff --git a/TAO/tao/Invocation.h b/TAO/tao/Invocation.h index 1fc0aef9fea..6dc928ee8ed 100644 --- a/TAO/tao/Invocation.h +++ b/TAO/tao/Invocation.h @@ -107,7 +107,7 @@ private: // weight version. protected: - IIOP_Object *data_; + STUB_Object *data_; // The object on which this invocation is going. const char *opname_; diff --git a/TAO/tao/Makefile b/TAO/tao/Makefile index 08d9b1822b2..07ca091ffa0 100644 --- a/TAO/tao/Makefile +++ b/TAO/tao/Makefile @@ -11,7 +11,9 @@ SHLIB = $(LIBNAME).$(SOEXT) # These are headers for things which are exported and must be # installed. (Currently not used). -PUB_HDRS = Align CDR GIOP Invocation IIOP_Object IIOP_ORB Connect Params \ +PUB_HDRS = Align CDR \ + Pluggable IIOP_Profile IIOP_Transport IIOP_Connector IIOP_Acceptor \ + GIOP Invocation IIOP_Object IIOP_ORB Connect Params \ Marshal Debug \ Default_Client Default_Server \ Server_Strategy_Factory Client_Strategy_Factory ORB_Core @@ -45,6 +47,11 @@ ORBCORE_SRCS = \ Request \ Sequence \ Server_Request \ + Pluggable \ + IIOP_Profile \ + IIOP_Transport \ + IIOP_Connector \ + IIOP_Acceptor \ Stub \ Typecode \ Union \ diff --git a/TAO/tao/ORB.cpp b/TAO/tao/ORB.cpp index 20d1bdc2568..c4813ba74b4 100644 --- a/TAO/tao/ORB.cpp +++ b/TAO/tao/ORB.cpp @@ -230,14 +230,19 @@ CORBA_ORB::open (void) TAO_ORB_Core *ocp = TAO_ORB_Core_instance (); TAO_Server_Strategy_Factory *f = ocp->server_factory (); + // @@ For now we simple assume an IIOP handler, in the future + // @@ this has to be more general + TAO_IIOP_BASE_ACCEPTOR *iiop_acceptor = + ACE_dynamic_cast(TAO_IIOP_BASE_ACCEPTOR *, ocp->acceptor ()->acceptor ()); + // Initialize the endpoint ... or try! - if (ocp->acceptor ()->open (ocp->orb_params ()->addr (), - ocp->reactor(), - f->creation_strategy (), - f->accept_strategy (), - f->concurrency_strategy (), - f->scheduling_strategy ()) == -1) + if (iiop_acceptor->open (ocp->orb_params ()->addr (), + ocp->reactor(), + f->creation_strategy (), + f->accept_strategy (), + f->concurrency_strategy (), + f->scheduling_strategy ()) == -1) // Need to return an error somehow!! Maybe set do_exit? return -1; @@ -245,13 +250,13 @@ CORBA_ORB::open (void) // a 0 for a port number. Once we open the acceptor, we can recheck // the address and get the accurate port number. ACE_INET_Addr new_address; - if (ocp->acceptor ()->acceptor ().get_local_addr (new_address) == -1) + if (iiop_acceptor->acceptor ().get_local_addr (new_address) == -1) return -1; // Reset the address ocp->orb_params ()->addr (new_address); - ocp->acceptor ()->acceptor ().enable (ACE_CLOEXEC); + iiop_acceptor->acceptor ().enable (ACE_CLOEXEC); ocp->add_to_collocation_table (); return 0; @@ -576,6 +581,10 @@ CORBA_ORB::resolve_trading_service (ACE_Time_Value *timeout) } +// @@ This will have to be sanitized of transport specific calls +// in order to support pluggable protocols! But, it does use +// UDP and multicast. Not all transport protocols may support +// this, connectionless and multicast. fredk CORBA_Object_ptr CORBA_ORB::multicast_to_service (TAO_Service_ID service_id, u_short port, @@ -710,11 +719,12 @@ CORBA_ORB::resolve_initial_references (CORBA::String name, TAO_THROW_RETURN (CORBA_ORB::InvalidName (), CORBA_Object::_nil ()); } -int -CORBA_ORB::preconnect (CORBA::String connections) -{ - return TAO_ORB_Core_instance ()->preconnect (connections); -} +// Now defined in IIOP_Connector and Connector_Registry +// int +// CORBA_ORB::preconnect (CORBA::String connections) +// { +// return TAO_ORB_Core_instance ()->preconnect (connections); +// } STUB_Object * @@ -736,12 +746,14 @@ CORBA_ORB::create_stub_object (const TAO_ObjectKey &key, id = 0; TAO_ORB_Core *orb_core = TAO_ORB_Core_instance (); + + // @@ Ugly, should not assume we are an IIOP Object!! + // Will deal with this on the next iteration of pluggable protocols! fredk IIOP_Object *data = 0; + // @@ replace IIOP::Profile with something more appropriate!! data = new IIOP_Object (id, - orb_core->orb_params ()->host (), - orb_core->orb_params ()->addr ().get_port_number (), - key, - orb_core->orb_params ()->addr ()); + TAO_ORB_Core_instance ()->orb_params ()->addr (), + key); if (data == 0) env.exception (new CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); @@ -939,6 +951,7 @@ CORBA_ORB::init_orb_globals (CORBA::Environment &env) // ORB initialisation, per OMG document 94-9-46. // // XXX in addition to the "built in" Internet ORB, there will be ORBs +// @@ ^^^^^^^^ XXX // which are added separately, e.g. through a DLL listed in the // registry. Registry will be used to assign orb names and to // establish which is the default. diff --git a/TAO/tao/ORB.h b/TAO/tao/ORB.h index 5e16736a0d1..5319b78e081 100644 --- a/TAO/tao/ORB.h +++ b/TAO/tao/ORB.h @@ -946,7 +946,6 @@ public: // ORB will not normally return OBJECT_NOT_EXIST unless the POA // reports that fault. - int preconnect (CORBA::String connections); // Establish connectsion to each of the comma-separated // <{host}>:<{port}> combinations specified in . diff --git a/TAO/tao/ORB_Core.cpp b/TAO/tao/ORB_Core.cpp index 4c1b3dcaeb2..488336f9dc3 100644 --- a/TAO/tao/ORB_Core.cpp +++ b/TAO/tao/ORB_Core.cpp @@ -31,49 +31,10 @@ TAO_Collocation_Table_Lock::~TAO_Collocation_Table_Lock (void) this->lock_ = 0; } -TAO_Cached_Connector_Lock::TAO_Cached_Connector_Lock (void) -{ - this->lock_ = TAO_ORB_Core_instance ()->server_factory ()->create_cached_connector_lock (); -} - -TAO_Cached_Connector_Lock::~TAO_Cached_Connector_Lock (void) -{ - delete this->lock_; - this->lock_ = 0; -} - -TAO_ST_Connect_Creation_Strategy::TAO_ST_Connect_Creation_Strategy (ACE_Thread_Manager *t) - : ACE_Creation_Strategy (t) -{ -} - -TAO_MT_Connect_Creation_Strategy::TAO_MT_Connect_Creation_Strategy (ACE_Thread_Manager *t) - : ACE_Creation_Strategy (t) -{ -} - -int -TAO_ST_Connect_Creation_Strategy::make_svc_handler (TAO_Client_Connection_Handler *&sh) -{ - if (sh == 0) - ACE_NEW_RETURN (sh, TAO_ST_Client_Connection_Handler (this->thr_mgr_), -1); - - return 0; -} - -int -TAO_MT_Connect_Creation_Strategy::make_svc_handler (TAO_Client_Connection_Handler *&sh) -{ - if (sh == 0) - ACE_NEW_RETURN (sh, TAO_MT_Client_Connection_Handler (this->thr_mgr_), -1); - - return 0; -} - TAO_ORB_Core::TAO_ORB_Core (void) : reactor_ (0), thr_mgr_ (0), - connector_ (0), + connector_registry_ (0), orb_ (0), root_poa_ (0), oa_params_ (0), @@ -503,7 +464,15 @@ TAO_ORB_Core::init (int &argc, char *argv[]) this->reactor (trf->get_reactor ()); this->thr_mgr (trf->get_thr_mgr ()); - this->connector (trf->get_connector ()); + + // Init the connector registry ... this initializes the registry + // pointer in the ORB core. The actual registry is either in TSS or global + // memory. + this->connector_registry (trf->get_connector_registry ()); + // @@ Make sure the IIOP_Connector is registered with the connector registry. + this->connector_registry ()->add_connector (trf->get_connector ()); + + // @@ Init acceptor ... This needs altering for Pluggable Protocols! fredk this->acceptor (trf->get_acceptor ()); this->input_cdr_dblock_allocator_ = @@ -553,7 +522,6 @@ TAO_ORB_Core::init (int &argc, char *argv[]) this->orb_params ()->name_service_port (ns_port); this->orb_params ()->trading_service_ior (ts_ior); this->orb_params ()->trading_service_port (ts_port); - this->orb_params ()->use_IIOP_lite_protocol (iiop_lite); this->orb_params ()->use_dotted_decimal_addresses (dotted_decimal_addresses); if (rcv_sock_size != 0) this->orb_params ()->sock_rcvbuf_size (rcv_sock_size); @@ -562,19 +530,22 @@ TAO_ORB_Core::init (int &argc, char *argv[]) if (cdr_tradeoff >= 0) this->orb_params ()->cdr_memcpy_tradeoff (cdr_tradeoff); + this->orb_params ()->use_lite_protocol (iiop_lite); + + this->orb_params ()->use_dotted_decimal_addresses (dotted_decimal_addresses); - if (this->connector ()->open (this->reactor (), - trf->get_null_creation_strategy (), - trf->get_cached_connect_strategy (), - trf->get_null_activation_strategy ()) != 0) + // tell the registry to open all registered interfaces! fredk + if (this->connector_registry ()->open (trf, this->reactor ()) != 0) return -1; + // Have registry parse the preconnects if (preconnections) - this->preconnect (preconnections); + this->connector_registry ()->preconnect (preconnections); return 0; } + int TAO_ORB_Core::set_endpoint (int dotted_decimal_addresses, CORBA::UShort port, @@ -641,140 +612,11 @@ TAO_ORB_Core::set_endpoint (int dotted_decimal_addresses, return 0; } -int -TAO_ORB_Core::preconnect (const char* the_preconnections) -{ - // It would be good to use auto_ptr<> to guard against premature - // termination and, thus, leaks. - char *preconnections = ACE_OS::strdup (the_preconnections); - -#if 0 - if (preconnections) - { - ACE_INET_Addr dest; - TAO_Client_Connection_Handler *handler; - ACE_Unbounded_Stack handlers; - - char *nextptr = 0; - char *where = 0; - for (where = ACE::strsplit_r (preconnections, ",", nextptr); - where != 0; - where = ACE::strsplit_r (0, ",", nextptr)) - { - char *tport = 0; - char *thost = where; - char *sep = ACE_OS::strchr (where, ':'); - - if (sep) - { - *sep = '\0'; - tport = sep + 1; - - dest.set (ACE_OS::atoi (tport), thost); - - // Try to establish the connection - handler = 0; - if (this->connector ()->connect (handler, dest) == 0) - { - // Save it for later so we can mark it as idle - handlers.push (handler); - } - else - ACE_ERROR ((LM_ERROR, - "(%P|%t) Unable to preconnect to host '%s', port %d.\n", - dest.get_host_name (), - dest.get_port_number ())); - } - else - ACE_ERROR ((LM_ERROR, - "(%P|%t) Yow! Couldn't find a ':' separator in '%s' spec.\n", - where)); - } - - // Walk the stack of handlers and mark each one as idle now. - handler = 0; - while (handlers.pop (handler) == 0) - handler->idle (); - - } -#else - int successes = 0; - if (preconnections) - { - ACE_INET_Addr dest; - ACE_Unbounded_Stack dests; - - char *nextptr = 0; - char *where = 0; - for (where = ACE::strsplit_r (preconnections, ",", nextptr); - where != 0; - where = ACE::strsplit_r (0, ",", nextptr)) - { - char *tport = 0; - char *thost = where; - char *sep = ACE_OS::strchr (where, ':'); - - if (sep) - { - *sep = '\0'; - tport = sep + 1; - - dest.set (atoi(tport), thost); - dests.push (dest); - } - else - ACE_ERROR ((LM_ERROR, - "(%P|%t) Yow! Couldn't find a ':' separator in '%s' spec.\n", where)); - } - - // Create an array of addresses from the stack, as well as an - // array of eventual handlers. - size_t num_connections = dests.size (); - ACE_INET_Addr *remote_addrs = 0; - TAO_Client_Connection_Handler **handlers = 0; - char *failures = 0; - - ACE_NEW_RETURN (remote_addrs, - ACE_INET_Addr[num_connections], - -1); - ACE_NEW_RETURN (handlers, - TAO_Client_Connection_Handler*[num_connections], - -1); - ACE_NEW_RETURN (failures, - char[num_connections], - -1); - - // Fill in the remote address array - size_t index = 0; - while (dests.pop (remote_addrs[index]) == 0) - handlers[index++] = 0; - - // Finally, try to connect. - this->connector ()->connect_n (num_connections, - handlers, - remote_addrs, - failures); - // Loop over all the failures and set the handlers that - // succeeded to idle state. - for (index = 0; index < num_connections; index++) - { - if (! failures[index]) - { - handlers[index]->idle (); - successes++; - } - } - } -#endif /* 0 */ - ACE_OS::free (preconnections); - - return successes; -} - int TAO_ORB_Core::fini (void) { - this->connector ()->close (); + // Ask the registry to close all registered connectors! + this->connector_registry ()->close_all (); TAO_Internal::close_services (); @@ -941,7 +783,7 @@ TAO_ORB_Core::inherit_from_parent_thread (TAO_ORB_Core *p) this->thr_mgr (p->thr_mgr ()); // We should use the same thread_manager. - this->connector (p->connector ()); + this->connector_registry (p->connector_registry ()); // We'll use the spawning thread's connector. this->orb (p->orb ()); @@ -1345,8 +1187,11 @@ rtype TAO_Resource_Factory::methodname(void)\ IMPLEMENT_PRE_GET_METHOD(get_reactor, ACE_Reactor *, r_) IMPLEMENT_PRE_GET_METHOD(get_thr_mgr, ACE_Thread_Manager *, tm_) -IMPLEMENT_PRE_GET_METHOD(get_acceptor, TAO_ACCEPTOR *, a_) -IMPLEMENT_PRE_GET_METHOD(get_connector, TAO_CONNECTOR *, c_) +IMPLEMENT_PRE_GET_METHOD(get_acceptor, TAO_Acceptor *, a_) +// Added the default IIOP connector to the resource factor to take advantage +// of these macros for storing this reference in TSS or global mem. +IMPLEMENT_PRE_GET_METHOD(get_connector_registry, TAO_Connector_Registry *, cr_) +IMPLEMENT_PRE_GET_METHOD(get_connector, TAO_Connector *, c_) IMPLEMENT_PRE_GET_METHOD(get_cached_connect_strategy, TAO_CACHED_CONNECT_STRATEGY *, cached_connect_strategy_) IMPLEMENT_PRE_GET_METHOD(get_null_creation_strategy, TAO_NULL_CREATION_STRATEGY *, null_creation_strategy_) IMPLEMENT_PRE_GET_METHOD(get_null_activation_strategy, TAO_NULL_ACTIVATION_STRATEGY *, null_activation_strategy_) @@ -1606,6 +1451,47 @@ TAO_ORB_Core_instance (void) return TAO_ORB_CORE::instance (); } + +TAO_Cached_Connector_Lock::TAO_Cached_Connector_Lock (void) +{ + this->lock_ = TAO_ORB_Core_instance ()->server_factory ()->create_cached_connector_lock (); +} + +TAO_Cached_Connector_Lock::~TAO_Cached_Connector_Lock (void) +{ + delete this->lock_; + this->lock_ = 0; +} + +TAO_ST_Connect_Creation_Strategy::TAO_ST_Connect_Creation_Strategy (ACE_Thread_Manager *t) + : ACE_Creation_Strategy (t) +{ +} + +TAO_MT_Connect_Creation_Strategy::TAO_MT_Connect_Creation_Strategy (ACE_Thread_Manager *t) + : ACE_Creation_Strategy (t) +{ +} + +int +TAO_ST_Connect_Creation_Strategy::make_svc_handler (TAO_Client_Connection_Handler *&sh) +{ + if (sh == 0) + ACE_NEW_RETURN (sh, TAO_ST_Client_Connection_Handler (this->thr_mgr_), -1); + + return 0; +} + +int +TAO_MT_Connect_Creation_Strategy::make_svc_handler (TAO_Client_Connection_Handler *&sh) +{ + if (sh == 0) + ACE_NEW_RETURN (sh, TAO_MT_Client_Connection_Handler (this->thr_mgr_), -1); + + return 0; +} + + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_Malloc; template class ACE_Allocator_Adapter >; diff --git a/TAO/tao/ORB_Core.h b/TAO/tao/ORB_Core.h index e27e9de12d1..ec720b3ee46 100644 --- a/TAO/tao/ORB_Core.h +++ b/TAO/tao/ORB_Core.h @@ -42,9 +42,6 @@ public: ~TAO_Cached_Connector_Lock (void); }; -typedef ACE_Strategy_Connector - TAO_CONNECTOR; - typedef ACE_Cached_Connect_Strategy @@ -56,7 +53,6 @@ typedef ACE_NOOP_Creation_Strategy typedef ACE_NOOP_Concurrency_Strategy TAO_NULL_ACTIVATION_STRATEGY; - // Forward decl. class TAO_Resource_Factory; @@ -118,13 +114,13 @@ public: // Sets the thread-specific pointer to the new POA Current state, // returning a pointer to the existing POA Current state. - // = Set/get the connector. - TAO_CONNECTOR *connector (TAO_CONNECTOR *c); - TAO_CONNECTOR *connector (void); + // = Set/get the connector registry - used to just be the connector. + TAO_Connector_Registry *connector_registry (TAO_Connector_Registry *c); + TAO_Connector_Registry *connector_registry (void); // = Set/get the acceptor. - TAO_ACCEPTOR *acceptor (TAO_ACCEPTOR *a); - TAO_ACCEPTOR *acceptor (void); + TAO_Acceptor *acceptor (TAO_Acceptor *a); + TAO_Acceptor *acceptor (void); // Accessor which returns the acceptor. // = Set/get pointer to the ORB. @@ -287,7 +283,8 @@ protected: int fini (void); // Final termination hook, typically called by CORBA::ORB's DTOR. - int preconnect (const char *preconnections); + // int preconnect (const char *preconnections); + // @@ Now defined in IIOP_Connector // Attempt to establish connections specified in . // Returns -1 in case of error, or the number of connections // actually established. @@ -304,8 +301,9 @@ protected: ACE_Thread_Manager *thr_mgr_; // Used to manage threads within the ORB - TAO_CONNECTOR *connector_; - // The connector actively initiating connection requests. + TAO_Connector_Registry *connector_registry_; + // The connector registry which all active connecters must register themselves + // with. CORBA::ORB_ptr orb_; // Pointer to the ORB. @@ -324,7 +322,12 @@ protected: TAO_ORB_Parameters *orb_params_; // Parameters used by the ORB. - TAO_ACCEPTOR *acceptor_; + // @@ Depricated! + ACE_INET_Addr *addr_; + // The address of the endpoint on which we're listening for + // connections and requests. + + TAO_Acceptor *acceptor_; // The acceptor passively listening for connection requests. TAO_POA_Current *poa_current_; @@ -472,7 +475,10 @@ public: virtual ACE_Thread_Manager *get_thr_mgr (void); // Return an to be utilized. - virtual TAO_CONNECTOR *get_connector (void); + virtual TAO_Connector *get_connector (void); + // Return an Connector to be utilized. + + virtual TAO_Connector_Registry *get_connector_registry (void); // Return an Connector to be utilized. virtual TAO_CACHED_CONNECT_STRATEGY *get_cached_connect_strategy (void); @@ -486,7 +492,7 @@ public: // This no-op activation strategy prevents the cached connector from // calling the service handler's method multiple times. - virtual TAO_ACCEPTOR *get_acceptor (void); + virtual TAO_Acceptor *get_acceptor (void); // Return an Acceptor to be utilized. virtual TAO_ORB_Parameters *get_orb_params (void); @@ -563,8 +569,12 @@ public: ACE_Thread_Manager tm_; // The Thread Manager - TAO_CONNECTOR c_; - // The Connector + TAO_Connector_Registry cr_; + // The Connector Registry! + + TAO_IIOP_Connector c_; + // The Connector, HACK to create the first connector which happens to be + // IIOP. TAO_CACHED_CONNECT_STRATEGY cached_connect_strategy_; // The Cached Connect Strategy @@ -577,7 +587,7 @@ public: // This no-op activation strategy prevents the cached connector from // calling the service handler's method multiple times. - TAO_ACCEPTOR a_; + TAO_IIOP_Acceptor a_; // The Acceptor TAO_ORB_Parameters orbparams_; diff --git a/TAO/tao/ORB_Core.i b/TAO/tao/ORB_Core.i index 6b7494bd881..3bda3cf324b 100644 --- a/TAO/tao/ORB_Core.i +++ b/TAO/tao/ORB_Core.i @@ -85,29 +85,29 @@ TAO_ORB_Core::orb_params(void) return TAO_OC_RETRIEVE (orb_params); } -ACE_INLINE TAO_CONNECTOR * -TAO_ORB_Core::connector (TAO_CONNECTOR *c) +ACE_INLINE TAO_Connector_Registry * +TAO_ORB_Core::connector_registry (TAO_Connector_Registry *cr) { - TAO_CONNECTOR *old_connector = this->connector_; - this->connector_ = c; - return old_connector; + TAO_Connector_Registry *old_cr = this->connector_registry_; + this->connector_registry_ = cr; + return old_cr; } -ACE_INLINE TAO_CONNECTOR * -TAO_ORB_Core::connector (void) +ACE_INLINE TAO_Connector_Registry * +TAO_ORB_Core::connector_registry (void) { - return TAO_OC_RETRIEVE (connector); + return TAO_OC_RETRIEVE (connector_registry); } -ACE_INLINE TAO_ACCEPTOR * -TAO_ORB_Core::acceptor (TAO_ACCEPTOR *a) +ACE_INLINE TAO_Acceptor * +TAO_ORB_Core::acceptor (TAO_Acceptor *a) { - TAO_ACCEPTOR *old_acceptor = this->acceptor_; + TAO_Acceptor *old_acceptor = this->acceptor_; this->acceptor_ = a; return old_acceptor; } -ACE_INLINE TAO_ACCEPTOR * +ACE_INLINE TAO_Acceptor * TAO_ORB_Core::acceptor (void) { return TAO_OC_RETRIEVE (acceptor); diff --git a/TAO/tao/Object.cpp b/TAO/tao/Object.cpp index da975f7635b..50ef400057a 100644 --- a/TAO/tao/Object.cpp +++ b/TAO/tao/Object.cpp @@ -242,7 +242,7 @@ CORBA_Object::_is_equivalent (CORBA_Object_ptr other_obj, TAO_ObjectKey * CORBA::Object::_key (CORBA::Environment &env) { - return this->_stubobj ()->key (env); + return this->_stubobj ()->profile_in_use ()->_key (env); } diff --git a/TAO/tao/Pluggable.cpp b/TAO/tao/Pluggable.cpp new file mode 100644 index 00000000000..13ada26a322 --- /dev/null +++ b/TAO/tao/Pluggable.cpp @@ -0,0 +1,193 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// +// = FILENAME +// +// = DESCRIPTION +// +// = AUTHOR +// +// ============================================================================ + +#include "tao/corba.h" + +TAO_Connector_Registry::TAO_Connector_Registry() + : iiop_connector_(0) +{ +} + +TAO_Connector_Registry::~TAO_Connector_Registry() +{ +} + +TAO_Connector * +TAO_Connector_Registry::get_connector (CORBA::ULong tag) +{ + // For now, only IIOP connectors. + if (tag != TAO_IOP_TAG_INTERNET_IOP) + { + ACE_DEBUG ((LM_DEBUG, "Invalid connector tag %d\n", tag)); + return 0; + } + + return iiop_connector_; +} + +CORBA::Boolean +TAO_Connector_Registry::add_connector (TAO_Connector *connector) +{ + + if (connector->tag() == TAO_IOP_TAG_INTERNET_IOP) + { + // do not copy, but save the reference (i.e. pointer) + this->iiop_connector_ = connector; + return 1; + } + ACE_DEBUG ((LM_DEBUG, "Invalid connector tag %d\n", connector->tag())); + return 0; +} + +int +TAO_Connector_Registry::open(TAO_Resource_Factory *trf, ACE_Reactor *reactor) +{ + // @@ Once again since we only accept 1 iiop connector, this is easy + if (iiop_connector_) + return this->iiop_connector_->open (trf, reactor); + return 0; +} + +int +TAO_Connector_Registry::close_all() +{ + // @@ Loop through all registered connectors ... not too hard + // since there is only one! + if (iiop_connector_) + return this->iiop_connector_->close (); + return 0; +} + +int +TAO_Connector_Registry::preconnect (const char* the_preconnections) +{ + // It would be good to use auto_ptr<> to guard against premature + // termination and, thus, leaks. + int result=0; + char *preconnections = ACE_OS::strdup (the_preconnections); + + // @@ OK, what we should do is parse the string so that we can gather + // @@ together addresses of the same protocol together and pass to the + // @@ appropriate connector. But, for now we ASSUME they are all + // @@ INET IP:Port!! HACK. fredk + + if (this->iiop_connector_) + result = this->iiop_connector_->preconnect(preconnections); + + ACE_OS::free (preconnections); + + return result; + +} + +TAO_Profile * +TAO_Connector_Registry::connect (STUB_Object *&obj, + CORBA::Environment &env) +{ + TAO_Profile *profile; + CORBA::ULong req_tag = TAO_IOP_TAG_INTERNET_IOP; + + { + ACE_MT (ACE_GUARD_RETURN (ACE_Lock, guard, obj->get_fwd_profile_lock (), 0)); + if (obj->get_fwd_profile_i () != 0) + { + profile = obj->get_fwd_profile_i (); + } + else + { + profile = obj->profile_in_use (); + } + } + + // And the profile selection policy is .... ONLY IIOP, and the + // first one found! + if (profile->tag () != req_tag) + { + TAO_THROW_ENV_RETURN (CORBA::INTERNAL (CORBA::COMPLETED_NO), env, 0); + } + + obj->set_profile_in_use(profile); + + // here is where we get the appropriate connector object + // but we are the Connector Registry so call get_connector(tag) + + TAO_Connector *connector = this->get_connector(req_tag); + + TAO_Transport *transport = connector->connect(profile, env); + + if (transport == 0) + return 0; + + return profile; +} + +Version::~Version (void) +{ +} + +Version::Version (const Version &src) + : major (src.major), + minor (src.minor) +{ +} + +Version::Version (CORBA::Octet maj, CORBA::Octet min) + : major (maj), + minor (min) +{ +} + +void +Version::set_version (CORBA::Octet maj, CORBA::Octet min) +{ + this->major = maj; + this->minor = min; +} + +int +Version::operator== (const Version *&src) +{ + return (this->major == src->major && this->minor == src->minor); +} + +int +Version::operator== (const Version &src) +{ + return (this->major == src.major && this->minor == src.minor); +} + +Version & +Version::operator= (const Version &src) +{ + this->major = src.major; + this->minor = src.minor; + return *this; +} + +TAO_Profile::~TAO_Profile (void) +{ +} + +TAO_Transport::~TAO_Transport (void) +{ +} + +TAO_Connector::~TAO_Connector (void) +{ +} + +TAO_Acceptor::~TAO_Acceptor (void) +{ +} diff --git a/TAO/tao/Pluggable.h b/TAO/tao/Pluggable.h new file mode 100644 index 00000000000..b3a7409dd69 --- /dev/null +++ b/TAO/tao/Pluggable.h @@ -0,0 +1,189 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// +// = FILENAME +// +// = DESCRIPTION +// +// = AUTHOR +// +// ============================================================================ + +#ifndef TAO_PLUGGABLE_H +# define TAO_PLUGGABLE_H + +class TAO_Resource_Factory; +class ACE_Reactor; + +// Generic definitions for the new Transport class. +// NOTE, the transport object is created in the Service handler constructor +// and delted in the service handlers destructor!! + +class TAO_Export TAO_Transport +{ +public: + virtual CORBA::ULong tag (void) = 0; + // The tag, each concrete class will have a specific tag value. + + virtual int idle (void) = 0; + virtual void close_conn() = 0; + virtual void resume_conn (ACE_Reactor *reactor) = 0; + + virtual ssize_t send (const ACE_Message_Block *mblk) = 0; + virtual ssize_t send (const u_char *buf, size_t len) = 0; + virtual ssize_t send (const iovec *iov, int iovcnt) = 0; + + virtual ssize_t receive (char *buf, size_t len) = 0; + virtual ssize_t receive (iovec *iov, int iovcnt) = 0; + + virtual TAO_Transport *_nil (void) = 0; + virtual int is_nil (TAO_Transport *obj) = 0; + + virtual int send_request (TAO_ORB_Core *orb_core, + TAO_OutputCDR &stream, + int twoway) = 0; + +// virtual int send_response (TAO_OutputCDR &response) = 0; + + virtual ACE_HANDLE handle(void) = 0; + // this is primarily used for error and debugging messages! + + virtual ~TAO_Transport(void); +}; + +// Generic Profile definitions +class TAO_Export TAO_Profile +{ +public: + virtual CORBA::ULong tag (void) = 0; + // The tag, each concrete class will have a specific tag value. + + virtual ASYS_TCHAR *addr_to_string(void) = 0; + virtual int parse (TAO_InputCDR& cdr, + CORBA::Boolean& continue_decoding, + CORBA::Environment &env) = 0; + virtual int parse_string (const char *string, CORBA::Environment &env) = 0; + // Parse the CDR encapsulation in ... + + virtual const TAO_opaque& body (void) const = 0; + // The body, an octet sequence that represent the marshaled + // profile... + + virtual TAO_ObjectKey *_key (CORBA::Environment &env) = 0; + virtual const TAO_ObjectKey &object_key (void) const = 0; + // Obtain the object key, return 0 if the profile cannot be parsed. + // The memory is owned by this object (not given to the caller). + + virtual TAO_Transport *transport(void) = 0; + virtual TAO_Profile *_nil (void) = 0; + + virtual CORBA::ULong hash (CORBA::ULong max, + CORBA::Environment &env) = 0; + + virtual CORBA::Boolean is_equivalent (TAO_Profile* other_profile, + CORBA::Environment &env) = 0; + + virtual void reset_hint (void) = 0; + // this methoid is used with a connection has been reset requiring the + // hint to be cleaned up and reset to NULL. + + virtual ~TAO_Profile (void); + // If you have a virtual method you need a virtual dtor. + +}; + +struct Version { + CORBA::Octet major; + CORBA::Octet minor; + + Version (const Version &src); + Version (CORBA::Octet maj = 0, CORBA::Octet min = 0); + ~Version (void); + + void set_version (CORBA::Octet maj, CORBA::Octet min); + Version &operator= (const Version &src); + int operator== (const Version &src); + int operator== (const Version *&src); + +}; + +// End Profile + +class TAO_Export TAO_Acceptor +{ + // TAOs Abstract Acceptor class used for pluggable protocols. +public: + + virtual TAO_Profile *create_profile (TAO_ObjectKey& object_key) = 0; + + virtual ACE_Event_Handler* acceptor (void) = 0; + // Return the ACE acceptor... + + virtual CORBA::ULong tag (void) = 0; + // The tag, each concrete class will have a specific tag value. + + virtual ~TAO_Acceptor (void); + +}; + +// Connector Registry and Generic Connector interface definitions + +class TAO_Export TAO_Connector +{ +public: + + virtual int preconnect(char* preconnections) = 0; + virtual int open(TAO_Resource_Factory *trf, ACE_Reactor *reactor) = 0; + virtual int close(void) = 0; + + virtual CORBA::ULong tag (void) = 0; + // The tag identifying the specific ORB transport layer + // protocol. For example TAO_IOP_TAG_INTERNET_IOP = 0. + // The tag is used in the IOR to identify the type of profile + // included. IOR -> {{tag0, profile0} {tag1, profole1} ...} + // GIOP.h defines typedef CORBA::ULong TAO_IOP_Profile_ID; + + virtual TAO_Transport* connect(TAO_Profile* profile, + CORBA::Environment &env) = 0; + // In order to support pluggable we need to abstract away the + // connect() method so it can be called from the GIOP code + // independant of the actual transport protocol in use. + + virtual ~TAO_Connector (void); + // the destructor + +}; + +class TAO_Export TAO_Connector_Registry +{ +public: + + TAO_Connector_Registry (); + ~TAO_Connector_Registry (); + + TAO_Connector *get_connector (CORBA::ULong tag); + CORBA::Boolean add_connector (TAO_Connector *connector); + // All TAO_Connectors will have a tag() member which will be + // used for registering object, as well as type checking. + + int open(TAO_Resource_Factory *trf, ACE_Reactor *reactor); + int close_all(void); + + int preconnect (const char* the_preconnections); + + TAO_Profile *connect (STUB_Object *&obj, CORBA::Environment &env); + // This is where the transport protocol is selected based on + // some policy. This member will call the connect member of the + // TAO_Connector class which in turn will call the concrete connector. +private: + TAO_Connector *iiop_connector_; + // @@ for now this is all we support! This next iteration will be + // a bit more generic. Something like a key, value pair with key + // equil to the IOP_TYPE and value a pointer to the Connector. +}; + +#endif /* TAO_PLUGGABLE_H */ diff --git a/TAO/tao/Server_Request.cpp b/TAO/tao/Server_Request.cpp index c630ba05fe8..7338e83ffc0 100644 --- a/TAO/tao/Server_Request.cpp +++ b/TAO/tao/Server_Request.cpp @@ -155,7 +155,7 @@ IIOP_ServerRequest::parse_header_lite (CORBA::Environment &env) void IIOP_ServerRequest::parse_header (CORBA::Environment &env) { - if (this->orb_core_->orb_params ()->use_IIOP_lite_protocol ()) + if (this->orb_core_->orb_params ()->use_lite_protocol ()) this->parse_header_lite (env); else this->parse_header_std (env); diff --git a/TAO/tao/Stub.h b/TAO/tao/Stub.h index d928e92b9d1..4680253f06a 100644 --- a/TAO/tao/Stub.h +++ b/TAO/tao/Stub.h @@ -45,6 +45,8 @@ enum TAO_Param_Type PARAM_RETURN // = PARAM_OUT }; +class TAO_Profile; + struct TAO_Param_Data { // = TITLE @@ -269,7 +271,9 @@ public: // only supports one protocol -- the problem won't show up. // "Multiprotocol ORBs" will need to solve that problem though. ] - virtual TAO_ObjectKey *key (CORBA_Environment &TAO_IN_ENV = CORBA_Environment::default_environment ()) = 0; + // This is profile specific and so should be called throug the profile_in_use + // member function. + // virtual TAO_ObjectKey *key (CORBA_Environment &TAO_IN_ENV = CORBA_Environment::default_environment ()) = 0; // Return the object key as an out parameter. Caller should release // return value when finished with it. @@ -277,6 +281,36 @@ public: virtual CORBA::ULong _incr_refcnt (void) = 0; virtual CORBA::ULong _decr_refcnt (void) = 0; + virtual TAO_Profile *set_profile_in_use (TAO_Profile *pfile) = 0; + // Makes a copy of the profile and frees the existing profile_in_use. + + virtual TAO_Profile *profile_in_use (void) {return 0;}; + // @@ In order to support pluggable protocols add a method to return + // a reference to a TAO_Profile (hence TAO_Transport) object. This + // object will keep a reference to the service handler hint. fredk + // returns a pointer to the profile_in_use object. This object + // retains ownership of this object. + + virtual TAO_Profile *get_profile(void) {return 0;}; + // returns null if profile_in_use == null + // otherwise return a pointer to a new profile object. + // The caller is responsible for freeing this memory! + + virtual TAO_Profile *get_fwd_profile (void) {return 0;}; + // Returns the current forwarding profile. + + virtual TAO_Profile *get_fwd_profile_i (void) {return 0;}; + // Returns the current forwarding profile. + + virtual TAO_Profile *set_fwd_profile (const TAO_Profile *new_profile) = 0; + // Sets forwarding profile and returns the current value. + + virtual ACE_Lock &get_fwd_profile_lock (void) = 0; + // Gives reference to the lock guarding the forwarding profile. + + virtual void reset_first_locate_request (void) = 0; + // reset the flag telling that the locate request should be used + protected: virtual ~STUB_Object (void); // XXX virtual inlines are evil. diff --git a/TAO/tao/corba.h b/TAO/tao/corba.h index dd40a32b452..c78ec4143e9 100644 --- a/TAO/tao/corba.h +++ b/TAO/tao/corba.h @@ -218,9 +218,18 @@ operator>> (TAO_InputCDR&, TAO_opaque&); #include "tao/POA.h" // TAO specific includes + + #include "tao/params.h" #include "tao/Connect.h" +// Pluggable Protocol Related Includes first +#include "tao/Pluggable.h" +#include "tao/IIOP_Profile.h" +#include "tao/IIOP_Transport.h" +#include "tao/IIOP_Connector.h" +#include "tao/IIOP_Acceptor.h" +// end pluggable protocols #include "tao/ORB_Core.h" #include "tao/Active_Object_Map.h" #include "tao/Operation_Table.h" diff --git a/TAO/tao/decode.cpp b/TAO/tao/decode.cpp index 73dba8e4111..96512768ce2 100644 --- a/TAO/tao/decode.cpp +++ b/TAO/tao/decode.cpp @@ -563,7 +563,7 @@ TAO_Marshal_Principal::decode (CORBA::TypeCode_ptr, } } -// Decode obj ref. +// Decode obj ref. An IOR CORBA::TypeCode::traverse_status TAO_Marshal_ObjRef::decode (CORBA::TypeCode_ptr, const void *data, // where the result will go @@ -658,69 +658,40 @@ TAO_Marshal_ObjRef::decode (CORBA::TypeCode_ptr, // Ownership of type_hint is given to IIOP_Object ACE_NEW_RETURN (objdata, - IIOP_Object (type_hint), - CORBA::TypeCode::TRAVERSE_STOP); - - IIOP::Profile *profile = &objdata->profile; - - // Read and verify major, minor versions, ignoring IIOP - // profiles whose versions we don't understand. - // - // XXX this doesn't actually go back and skip the whole - // encapsulation... - if (!(str.read_octet (profile->iiop_version.major) - && profile->iiop_version.major == IIOP::MY_MAJOR - && str.read_octet (profile->iiop_version.minor) - && profile->iiop_version.minor <= IIOP::MY_MINOR)) - { - ACE_DEBUG ((LM_DEBUG, "detected new v%d.%d IIOP profile", - profile->iiop_version.major, - profile->iiop_version.minor)); + IIOP_Object (type_hint), + CORBA::TypeCode::TRAVERSE_STOP); + + + // return code will be -1 if an error occurs + // otherwise 0 for stop (can't read this profile type or version) + // and 1 for continue. + // @@ check with carlos about how TRAVERSE_CONTINUE is used! + switch (objdata->profile_in_use ()->parse (str, continue_decoding, env)) + { + case -1: + objdata->_decr_refcnt (); + return CORBA::TypeCode::TRAVERSE_STOP; + break; + case 0: objdata->type_id = (const char *) 0; objdata->_decr_refcnt (); objdata = 0; continue; - } - - // Get host and port - if (str.decode (CORBA::_tc_string, - &profile->host, - 0, - env) != CORBA::TypeCode::TRAVERSE_CONTINUE - || !str.read_ushort (profile->port)) - { - env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); - ACE_DEBUG ((LM_DEBUG, "error decoding IIOP host/port")); - objdata->_decr_refcnt (); - return CORBA::TypeCode::TRAVERSE_STOP; - } - - profile->reset_object_addr (); - - // ... and object key. - - continue_decoding = str.decode (TC_opaque, - &profile->object_key, - 0, - env) == CORBA::TypeCode::TRAVERSE_CONTINUE; - - if (str.length () != 0) - { - env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); - ACE_DEBUG ((LM_DEBUG, - "%d bytes out of %d left after IIOP profile data\n", - str.length (), encap_len)); - objdata->_decr_refcnt (); - return CORBA::TypeCode::TRAVERSE_STOP; - } - } + break; + case 1: + default: + // all other return values indicate success + break; + } + } + if (objdata == 0) { env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); ACE_DEBUG ((LM_DEBUG, "objdata is 0, maybe because " "no IIOP v%d.%d (or earlier) profile in IOR!\n", - IIOP::MY_MAJOR, IIOP::MY_MINOR )); + TAO_IIOP_Profile::DEF_IIOP_MAJOR, TAO_IIOP_Profile::DEF_IIOP_MINOR)); return CORBA::TypeCode::TRAVERSE_STOP; } else @@ -1023,7 +994,8 @@ TAO_Marshal_Union::decode (CORBA::TypeCode_ptr tc, { CORBA::Long l; TAO_InputCDR stream ((ACE_Message_Block *) - member_label->_tao_get_cdr ()); + member_label->value + ()); (void)stream.decode (discrim_tc, &l, 0, env); if (l == *(CORBA::Long *) discrim_val) discrim_matched = 1; diff --git a/TAO/tao/encode.cpp b/TAO/tao/encode.cpp index c721ffefc10..21f01287755 100644 --- a/TAO/tao/encode.cpp +++ b/TAO/tao/encode.cpp @@ -286,7 +286,8 @@ TAO_Marshal_ObjRef::encode (CORBA::TypeCode_ptr, IIOP_Object *iiopobj = ACE_dynamic_cast (IIOP_Object *, obj->_stubobj ()); - IIOP::Profile *profile = &iiopobj->profile; + TAO_IIOP_Profile *profile = + ACE_dynamic_cast (TAO_IIOP_Profile *, iiopobj->profile_in_use()); // STRING, a type ID hint stream->encode (CORBA::_tc_string, &iiopobj->type_id, 0, env); @@ -304,7 +305,7 @@ TAO_Marshal_ObjRef::encode (CORBA::TypeCode_ptr, // this longword; it guarantees the rest is aligned for us. u_int hostlen; - hostlen = ACE_OS::strlen ((char *) profile->host); + hostlen = ACE_OS::strlen ((char *) profile->host ()); CORBA::ULong encap_len = 1 // byte order + 1 // version major @@ -316,7 +317,7 @@ TAO_Marshal_ObjRef::encode (CORBA::TypeCode_ptr, + 2 // port + ( hostlen & 02) // optional pad short + 4 // sizeof (key length) - + profile->object_key.length (); // key length. + + profile->object_key ().length (); // key length. stream->write_ulong (encap_len); #if 0 @@ -328,17 +329,17 @@ TAO_Marshal_ObjRef::encode (CORBA::TypeCode_ptr, stream->write_octet (TAO_ENCAP_BYTE_ORDER); // IIOP::Version, two characters (version 1.0) padding - stream->write_char (profile->iiop_version.major); - stream->write_char (profile->iiop_version.minor); + stream->write_char (profile->version()->major); + stream->write_char (profile->version()->minor); // STRING hostname from profile - stream->encode (CORBA::_tc_string, &profile->host, 0, env); + stream->encode (CORBA::_tc_string, &profile->host_, 0, env); // UNSIGNED SHORT port number - stream->write_ushort (profile->port); + stream->write_ushort (profile->port_); // OCTET SEQUENCE for object key - stream->encode (TC_opaque, &profile->object_key, 0, env); + stream->encode (TC_opaque, &profile->object_key (), 0, env); #if 0 // This is good for debugging the computation of the key diff --git a/TAO/tao/params.cpp b/TAO/tao/params.cpp index e8d13cd443f..f2419bf0488 100644 --- a/TAO/tao/params.cpp +++ b/TAO/tao/params.cpp @@ -18,7 +18,7 @@ TAO_ORB_Parameters::TAO_ORB_Parameters (void) sock_rcvbuf_size_ (ACE_DEFAULT_MAX_SOCKET_BUFSIZ), sock_sndbuf_size_ (ACE_DEFAULT_MAX_SOCKET_BUFSIZ), cdr_memcpy_tradeoff_ (TAO_DEFAULT_CDR_MEMCPY_TRADEOFF), - use_IIOP_lite_protocol_ (0) + use_lite_protocol_ (0) { } diff --git a/TAO/tao/params.h b/TAO/tao/params.h index 403455d63ac..3d1cc0fca01 100644 --- a/TAO/tao/params.h +++ b/TAO/tao/params.h @@ -102,8 +102,8 @@ public: // octet sequence is small enough and there is room in the current // message block it is more efficient just to copy the buffer. - int use_IIOP_lite_protocol (void) const; - void use_IIOP_lite_protocol (int); + int use_lite_protocol (void) const; + void use_lite_protocol (int); // The ORB will use a modified version of IIOP that minimizes the // header size. By default we use the standard IIOP protocol. @@ -150,8 +150,8 @@ private: // Control the strategy for copying vs. appeding octet sequences in // CDR streams. - int use_IIOP_lite_protocol_; - // For selecting a liteweight IIOP protocol. + int use_lite_protocol_; + // For selecting a liteweight version of the GIOP protocol. int use_dotted_decimal_addresses_; // For selecting a address notation diff --git a/TAO/tao/params.i b/TAO/tao/params.i index 77637ce766e..4fcf03f459a 100644 --- a/TAO/tao/params.i +++ b/TAO/tao/params.i @@ -91,15 +91,15 @@ TAO_ORB_Parameters::cdr_memcpy_tradeoff (int x) } ACE_INLINE int -TAO_ORB_Parameters::use_IIOP_lite_protocol (void) const +TAO_ORB_Parameters::use_lite_protocol (void) const { - return this->use_IIOP_lite_protocol_; + return this->use_lite_protocol_; } ACE_INLINE void -TAO_ORB_Parameters::use_IIOP_lite_protocol (int x) +TAO_ORB_Parameters::use_lite_protocol (int x) { - this->use_IIOP_lite_protocol_ = x; + this->use_lite_protocol_ = x; } ACE_INLINE int -- cgit v1.2.1