From 660b38150b3c7d51abf92873a0070992fe9c6772 Mon Sep 17 00:00:00 2001 From: coryan Date: Thu, 3 Jun 1999 18:25:00 +0000 Subject: ChangeLogTag:Thu Jun 3 13:20:09 1999 Carlos O'Ryan --- TAO/ChangeLog-99c | 43 ++ TAO/tao/GIOP.cpp | 1048 +++++++++++++++++++++++++++----------- TAO/tao/GIOP.h | 96 +++- TAO/tao/GIOP_Server_Request.cpp | 88 ++-- TAO/tao/GIOP_Server_Request.h | 53 +- TAO/tao/GIOP_Server_Request.i | 24 +- TAO/tao/IIOP_Connect.cpp | 545 ++------------------ TAO/tao/IIOP_Connect.h | 40 +- TAO/tao/IIOP_Profile.cpp | 8 +- TAO/tao/IIOP_Transport.cpp | 209 +++----- TAO/tao/IIOP_Transport.h | 11 +- TAO/tao/Invocation.cpp | 114 +---- TAO/tao/Invocation.h | 3 + TAO/tao/Invocation.i | 6 +- TAO/tao/Pluggable.cpp | 65 --- TAO/tao/Pluggable.h | 39 -- TAO/tao/Reply_Dispatcher.cpp | 66 +-- TAO/tao/Reply_Dispatcher.h | 73 +-- TAO/tao/Reply_Dispatcher.i | 19 + TAO/tao/Request_Mux_Strategy.cpp | 45 +- TAO/tao/Request_Mux_Strategy.h | 19 +- TAO/tao/UIOP_Connect.cpp | 547 ++------------------ TAO/tao/UIOP_Connect.h | 32 +- TAO/tao/UIOP_Transport.cpp | 212 +++----- TAO/tao/UIOP_Transport.h | 11 +- TAO/tao/Wait_Strategy.cpp | 25 +- TAO/tao/Wait_Strategy.h | 25 +- TAO/tests/MT_Client/test_i.cpp | 2 +- 28 files changed, 1387 insertions(+), 2081 deletions(-) create mode 100644 TAO/tao/Reply_Dispatcher.i diff --git a/TAO/ChangeLog-99c b/TAO/ChangeLog-99c index 581206f3741..70db3e5db9a 100644 --- a/TAO/ChangeLog-99c +++ b/TAO/ChangeLog-99c @@ -1,3 +1,46 @@ +Thu Jun 3 13:20:09 1999 Carlos O'Ryan + + * tao/GIOP.h: + * tao/GIOP.cpp: + * tao/GIOP_Server_Request.h: + * tao/GIOP_Server_Request.i: + * tao/GIOP_Server_Request.cpp: + * tao/IIOP_Connect.h: + * tao/IIOP_Connect.cpp: + * tao/IIOP_Profile.cpp: + * tao/IIOP_Transport.cpp: + * tao/IIOP_Transport.h: + * tao/Invocation.h: + * tao/Invocation.i: + * tao/Invocation.cpp: + * tao/Pluggable.h: + * tao/Pluggable.cpp: + * tao/Wait_Strategy.h: + * tao/Wait_Strategy.cpp: + * tao/Reply_Dispatcher.h: + * tao/Reply_Dispatcher.cpp: + * tao/Request_Mux_Strategy.h: + * tao/Request_Mux_Strategy.cpp: + * tao/UIOP_Connect.h: + * tao/UIOP_Connect.cpp: + * tao/UIOP_Transport.h: + * tao/UIOP_Transport.cpp: + Moved all the GIOP code into GIOP.cpp, i.e. the Invocation, + Transport and Connect classes do not parse headers or read any + data, it is all controlled by the GIOP module. + This also saved some code because the UIOP and IIOP protocols + can share the implementation in GIOP.cpp + Improve the interface between the Reply_Dispatcher, the + Request_Muxers and the transport objects. + Removed a bunch of methods that were not used anymore, like + suspend_* and resume_* + In short: we continue the process of integrating pluggable + protocols and the first phase of messaging. + + * tests/MT_Client/test_i.cpp: + Call shutdown() with the default parameter, otherwise it dies a + horrible death. + Thu Jun 3 13:17:50 1999 Carlos O'Ryan * tao/varout.h: diff --git a/TAO/tao/GIOP.cpp b/TAO/tao/GIOP.cpp index 0c6a215ab3d..df4a652ea13 100644 --- a/TAO/tao/GIOP.cpp +++ b/TAO/tao/GIOP.cpp @@ -50,10 +50,12 @@ #include "tao/GIOP.h" #include "tao/Timeprobe.h" +#include "tao/GIOP_Server_Request.h" #include "tao/CDR.h" #include "tao/Pluggable.h" #include "tao/debug.h" #include "tao/ORB_Core.h" +#include "tao/POA.h" #if !defined (__ACE_INLINE__) # include "tao/GIOP.i" @@ -68,9 +70,6 @@ static const char *TAO_GIOP_Timeprobe_Description[] = "GIOP::send_request - start", "GIOP::send_request - end", - "GIOP::recv_message - start", - "GIOP::recv_message - end", - "GIOP::read_buffer - start", "GIOP::read_buffer - end", @@ -123,8 +122,14 @@ TAO_GIOP::dump_msg (const char *label, const u_char *ptr, size_t len) { - if (TAO_debug_level >= 2) + if (TAO_debug_level >= 5) { + const char* message_name = "UNKNOWN MESSAGE"; + unsigned long index = ptr[7] + TAO_GIOP::tao_specific_message_types; + if (index >= 0 && index < sizeof (names)/sizeof(names[0])) + { + message_name = names [index]; + } ACE_DEBUG ((LM_DEBUG, "%s GIOP v%c.%c msg, %d data bytes, %s endian, %s", label, @@ -132,8 +137,7 @@ TAO_GIOP::dump_msg (const char *label, digits[ptr[5]], len - TAO_GIOP_HEADER_LEN, (ptr[6] == TAO_ENCAP_BYTE_ORDER) ? "my" : "other", - (ptr[7] <= TAO_GIOP::Fragment) ? names [ptr[7] + - TAO_GIOP::tao_specific_message_types] : "UNKNOWN TYPE")); + message_name)); if (ptr[7] == TAO_GIOP::Request) { @@ -153,7 +157,7 @@ TAO_GIOP::dump_msg (const char *label, else ACE_DEBUG ((LM_DEBUG, "\n")); - if (TAO_debug_level >= 4) + if (TAO_debug_level >= 10) ACE_HEX_DUMP ((LM_DEBUG, (const char*)ptr, len, @@ -220,7 +224,7 @@ operator>>(TAO_InputCDR &cdr, } CORBA::Boolean -TAO_GIOP::send_request (TAO_Transport *transport, +TAO_GIOP::send_message (TAO_Transport *transport, TAO_OutputCDR &stream, TAO_ORB_Core *orb_core) { @@ -430,8 +434,21 @@ TAO_GIOP::read_buffer (TAO_Transport *transport, ssize_t bytes_read = transport->recv (buf, len); + if (bytes_read <= 0 && TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p,\n" + " transport = %d, " + "bytes = %d, len = %d\n", + "TAO_GIOP::read_buffer", + transport->handle (), + bytes_read, len)); + } + if (bytes_read == -1 && errno == ECONNRESET) { + // @@ Is this OK?? + // We got a connection reset (TCP RSET) from the other side, // i.e., they didn't initiate a proper shutdown. // @@ -443,310 +460,93 @@ TAO_GIOP::read_buffer (TAO_Transport *transport, return bytes_read; } -// Read the message header, plus any data part of the message, setting -// stuff up so that CDR byteswaps data as appropriate. Errors are -// reported to be MessageError messages. -// -// NOTE: this code is structured to issue two read () calls for each -// incoming message. Alternative structures (e.g. with a user-space -// buffer per connection, or networking code handing off entire GIOP -// messages) can reduce the overhead of these calls to the networking -// code; correctness and simplicity drove this implementation more -// than efficiency. -// -// NOTE: as always, counting system calls associated with I/O gives -// you a good basic understanding of the tuning issues. On the server -// side, there is normally select/read/read/write per invocation. The -// call to select () can be omitted by allocating a thread to each -// connection; in some cases, that alone has almost doubled -// performance. The two read () calls can be made into one by fancy -// buffering. How fast could it be with both optimizations applied? - -// I am now making this call non-blocking. For reading the header it -// is not non-blocking. But for reading the rest of the message, it is -// non-blocking. Total size and the current offset of the incoming -// message is kept at the Transport class. Flag is to force -// blocking for the full reply. Useful strategies. -TAO_GIOP::Message_Type -TAO_GIOP::recv_message (TAO_Transport *transport, - TAO_InputCDR &msg, - TAO_ORB_Core* orb_core, - TAO_GIOP_Version & /* version */, - int block) -{ - TAO_FUNCTION_PP_TIMEPROBE (TAO_GIOP_RECV_MESSAGE_START); - - // Read the message header off the wire. - // - // THREADING NOTE: the connection manager handed us this connection - // for exclusive use, so we need not worry about having two threads - // interleave reads of partial messages. This model is excellent - // for "lightly threaded" systems (as will be the majority in the - // near future) but makes less effective use of connection resources - // as the "duty factor" goes down because of either long calls or - // bursty contention during numerous short calls to the same server. - - // Default header length. - ssize_t header_len = TAO_GIOP_HEADER_LEN; - - // @@ Alex&Carlos: we need to figure out what is the right value to - // initialize this thing... - TAO_GIOP::Message_Type retval = TAO_GIOP::ShortRead; - CORBA::ULong message_size; - ssize_t len; - char *header = 0; - - if (!transport->message_size ()) - { - // This is the first read for this message. - ACE_CDR::mb_align (&msg.start_); - - if (orb_core->orb_params ()->use_lite_protocol ()) - header_len = TAO_GIOP_LITE_HEADER_LEN; - - if (ACE_CDR::grow (&msg.start_, - header_len) == -1) - // This should probably be an exception. - return TAO_GIOP::CommunicationError; - - header = msg.start_.rd_ptr (); - len = TAO_GIOP::read_buffer (transport, - header, - header_len); - // Read the header into the buffer. - - if (len != header_len) - { - switch (len) - { - case 0: - if (TAO_orbdebug) - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) GIOP::recv_message " - "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. - // Is it _never_ an error? Not sure ... - /* NOTREACHED */ - - case -1: // error - if (TAO_orbdebug) - ACE_DEBUG ((LM_ERROR, - "TAO (%P|%t) GIOP::recv_message header %p\n", - "read_buffer")); - break; - /* NOTREACHED */ - - default: - if (TAO_orbdebug) - ACE_DEBUG ((LM_ERROR, - "TAO (%P|%t) GIOP::recv_message header read failed, " - "only %d of %d bytes\n", - len, - header_len)); - break; - /* NOTREACHED */ - } - - return TAO_GIOP::CommunicationError; - } - - // NOTE: if message headers, or whole messages, get encrypted in - // application software (rather than by the network infrastructure) - // they should be decrypted here ... - - // First make sure it's a GIOP message of any version. - - if (TAO_GIOP::parse_header (msg, - msg.do_byte_swap_, - retval, - message_size, - orb_core) == -1) - { - TAO_GIOP::send_error (transport); - // We didn't really receive anything useful here. - return TAO_GIOP::CommunicationError; - } - - // Make sure we have the full length in memory, growing the - // buffer if needed. - // - // NOTE: We could overwrite these few bytes of header... they're - // left around for now as a debugging aid. - - assert (message_size <= UINT_MAX); - - if (ACE_CDR::grow (&msg.start_, - header_len + message_size) == -1) - return TAO_GIOP::CommunicationError; - - // Growing the buffer may have reset the rd_ptr(), but we want to - // leave it just after the GIOP header (that was parsed already); - ACE_CDR::mb_align (&msg.start_); - msg.start_.wr_ptr (header_len); - msg.start_.wr_ptr (message_size); - msg.start_.rd_ptr (header_len); - - // Keep the message_size with the Transport object. - transport->message_size (message_size); - } - - // Header is read already. Read the rest of this message into the - // buffer. - - char* payload = msg.start_.rd_ptr (); - - // @@ Handle the non-blocking case !!!. (Alex). - len = TAO_GIOP::read_buffer (transport, - payload, - (size_t) transport->message_size () - - transport->message_offset ()); - - if (len != (ssize_t) message_size) - { - switch (len) - { - case 0: - if (TAO_orbdebug) - ACE_DEBUG ((LM_DEBUG, - "(%t) End of connection, transport handle %d\n", - transport->handle ())); - - return TAO_GIOP::EndOfFile; - /* NOTREACHED */ - - case -1: - if (TAO_orbdebug) - ACE_DEBUG ((LM_ERROR, - "(%P|%t) TAO_GIOP::recv_message - body %p\n", - "read_buffer")); - break; - /* NOTREACHED */ - - default: - // @@ This is ok in the non-blocking read. (Alex). - if (TAO_orbdebug) - ACE_DEBUG ((LM_ERROR, - "TAO: (%P|%t) GIOP::recv_message body read failed, " - "only %d of %d bytes\n", - len, - message_size)); - break; - /* NOTREACHED */ - } - return TAO_GIOP::CommunicationError; - } - - - TAO_GIOP::dump_msg ("recv", - ACE_reinterpret_cast (u_char *, header), - message_size + header_len); - - transport->incr_message_offset (len); - - // If we have read the whole message, reset the states for the input - // message. - if (transport->message_size () == transport->message_offset ()) - { - // Reset. - transport->message_size (0); - - // Current message is received fully. - transport->message_received (1); - } - - return retval; -} - int -TAO_GIOP::parse_header_std (TAO_InputCDR &cdr, - int &do_byte_swap, - TAO_GIOP::Message_Type &message_type, - CORBA::ULong &message_size) +TAO_GIOP::parse_header_std (ACE_Message_Block *payload, + TAO_GIOP_MessageHeader &header) { - char *header = cdr.start_.rd_ptr (); + char *buf = payload->rd_ptr (); // The values are hard-coded to support non-ASCII platforms - if (!(header [0] == 0x47 // 'G' - && header [1] == 0x49 // 'I' - && header [2] == 0x4f // 'O' - && header [3] == 0x50 // 'P' + if (!(buf [0] == 0x47 // 'G' + && buf [1] == 0x49 // 'I' + && buf [2] == 0x4f // 'O' + && buf [3] == 0x50 // 'P' )) { - ACE_DEBUG ((LM_DEBUG, - "TAO: (%P|%t) bad header, magic word [%c%c%c%c]\n", - header[0], header[1], header[2], header[3])); + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) bad header, magic word [%c%c%c%c]\n", + buf[0], buf[1], buf[2], buf[3])); return -1; } - // Then make sure the major version is ours, and the minor version - // is one that we understand. - - if (!(header [4] == TAO_GIOP_MessageHeader::MY_MAJOR - && header [5] <= TAO_GIOP_MessageHeader::MY_MINOR)) +#if 0 + // @@ Nobody uses this magic number, no sense in wasting time here. + header.magic[0] = 0x47; + header.magic[1] = 0x49; + header.magic[2] = 0x4f; + header.magic[3] = 0x50; +#endif /* 0 */ + header.giop_version.major = buf[4]; + header.giop_version.minor = buf[5]; + header.byte_order = buf[6]; + header.message_type = buf[7]; + + TAO_InputCDR cdr (payload, + ACE_static_cast(int,header.byte_order)); + + cdr.skip_bytes (TAO_GIOP_MESSAGE_SIZE_OFFSET); + cdr.read_ulong (header.message_size); + + if (TAO_debug_level > 2) { ACE_DEBUG ((LM_DEBUG, - "TAO: (%P|%t) bad header, version [%c%c]\n", - header[4], header[5])); - return -1; + "TAO (%P|%t) Parsed header = <%d,%d,%d,%d,%d>\n", + header.giop_version.major, + header.giop_version.minor, + header.byte_order, + header.message_type, + header.message_size)); } - - // Get the message type out and adjust the buffer's records to - // record that we've read everything except the length. - - message_type = (TAO_GIOP::Message_Type) header[7]; - - do_byte_swap = (header [6] != TAO_ENCAP_BYTE_ORDER); - - // Make sure byteswapping is done if needed, and then read the - // message size (appropriately byteswapped). - - cdr.start_.rd_ptr (8); - cdr.read_ulong (message_size); - return 0; } int -TAO_GIOP::parse_header_lite (TAO_InputCDR &cdr, - int &do_byte_swap, - TAO_GIOP::Message_Type &message_type, - CORBA::ULong &message_size) +TAO_GIOP::parse_header_lite (ACE_Message_Block *payload, + TAO_GIOP_MessageHeader& header) { - do_byte_swap = 0; - - char *header = cdr.start_.rd_ptr (); - - // Get the message type out and adjust the buffer's records to - // record that we've read everything except the length. - message_type = (TAO_GIOP::Message_Type) header[4]; - - cdr.read_ulong (message_size); - - cdr.start_.rd_ptr (1); - + char *buf = payload->rd_ptr (); + +#if 0 + // @@ Nobody uses this magic number, no sense in wasting time here. + header.magic[0] = 0x47; + header.magic[1] = 0x49; + header.magic[2] = 0x4f; + header.magic[3] = 0x50; +#endif /* 0 */ + header.giop_version.major = 1; + header.giop_version.minor = 0; + header.byte_order = TAO_ENCAP_BYTE_ORDER; + header.message_type = buf[4]; + + TAO_InputCDR cdr (payload, + ACE_static_cast(int,header.byte_order)); + + cdr.read_ulong (header.message_size); return 0; } int -TAO_GIOP::parse_header (TAO_InputCDR &cdr, - int &do_byte_swap, - TAO_GIOP::Message_Type &message_type, - CORBA::ULong &message_size, - TAO_ORB_Core *orb_core) +TAO_GIOP::parse_header (TAO_ORB_Core *orb_core, + ACE_Message_Block *payload, + TAO_GIOP_MessageHeader& header) { if (orb_core->orb_params ()->use_lite_protocol ()) - return TAO_GIOP::parse_header_lite (cdr, - do_byte_swap, - message_type, - message_size); + return TAO_GIOP::parse_header_lite (payload, + header); else - return TAO_GIOP::parse_header_std (cdr, - do_byte_swap, - message_type, - message_size); + return TAO_GIOP::parse_header_std (payload, + header); } CORBA::Boolean @@ -862,6 +662,678 @@ TAO_GIOP::convert_CORBA_to_GIOP_exception (CORBA::exception_type corba_type) } } +// **************************************************************** + +int +TAO_GIOP::read_header (TAO_Transport *transport, + TAO_ORB_Core *orb_core, + TAO_GIOP_MessageHeader &header, + CORBA::ULong &header_size, + ACE_Message_Block *payload) +{ + // Default header length. + header_size = TAO_GIOP_HEADER_LEN; + if (orb_core->orb_params ()->use_lite_protocol ()) + header_size = TAO_GIOP_LITE_HEADER_LEN; + + if (ACE_CDR::grow (payload, header_size) == -1) + return -1; + + ACE_CDR::mb_align (payload); + + // Read until all the header is received. There should be no + // problems with locking, the header is only a few bytes so they + // should all be available on the socket, otherwise there is a + // problem with the underlying transport, in which case we have more + // problems than just this small loop. + + char* buf = payload->rd_ptr (); + int t = header_size; + while (t != 0) + { + int n = transport->recv (buf, t); + if (n == -1) + return -1; + else if (n == 0 && errno != EWOULDBLOCK) + return -1; + buf += n; + t -= n; + } + + // Adjust the length of the payload + payload->wr_ptr (header_size); + + if (TAO_GIOP::parse_header (orb_core, payload, header) == -1) + return -1; + return header_size; +} + +int +TAO_GIOP::handle_input (TAO_Transport *transport, + TAO_ORB_Core *orb_core, + TAO_GIOP_MessageHeader &header, + CORBA::ULong ¤t_offset, + ACE_Message_Block *payload) +{ + if (header.message_size == 0) + { + current_offset = 0; + CORBA::ULong header_size; + if (TAO_GIOP::read_header (transport, + orb_core, + header, + header_size, + payload) == -1) + { + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "TAO_GIOP::handle_input, read_header")); + } + return -1; + } + + if (ACE_CDR::grow (payload, + header_size + + header.message_size) == -1) + { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "TAO_GIOP::handle_input, ACE_CDR::grow")); + return -1; + } + + // Growing the buffer may have reset the rd_ptr(), but we want to + // leave it just after the GIOP header (that was parsed already); + ACE_CDR::mb_align (payload); + payload->wr_ptr (header_size); + payload->wr_ptr (header.message_size); + payload->rd_ptr (header_size); + } + + size_t missing_data = + header.message_size - current_offset; + ssize_t n = + TAO_GIOP::read_buffer (transport, + payload->rd_ptr () + current_offset, + missing_data); + if (n == -1) + { + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "TAO_GIOP::handle_input, read_buffer[1]")); + } + return -1; + } + else if (n == 0) + { + if (errno == EWOULDBLOCK) + return 0; + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "TAO_GIOP::handle_input, read_buffer[2]")); + } + return -1; + } + + current_offset += n; + + if (current_offset == header.message_size) + { + if (TAO_debug_level >= 5) + { + size_t header_len = TAO_GIOP_HEADER_LEN; + if (orb_core->orb_params ()->use_lite_protocol ()) + header_len = TAO_GIOP_LITE_HEADER_LEN; + + char* buf = payload->rd_ptr (); + buf -= header_len; + size_t msg_len = payload->length () + header_len; + TAO_GIOP::dump_msg ("recv", + ACE_reinterpret_cast (u_char *, buf), + msg_len); + } + return 1; + } + return 0; +} + +int +TAO_GIOP::parse_reply (TAO_Transport *transport, + TAO_ORB_Core *orb_core, + TAO_InputCDR& input, + const TAO_GIOP_MessageHeader& header, + TAO_GIOP_ServiceContextList& reply_ctx, + CORBA::ULong& request_id, + CORBA::ULong& reply_status) +{ + switch (header.message_type) + { + case TAO_GIOP::Request: + // In GIOP 1.0 and GIOP 1.1 this is an error, but it is + // *possible* to receive requests in GIOP 1.2. Don't handle this + // on the firt iteration, leave it for the nearby future... + // ERROR too. + // @@ this->reply_handler_->error (); + ACE_ERROR_RETURN ((LM_ERROR, + "TAO (%P|%t) %N:%l handle_client_input: " + "request.\n"), + -1); + + case TAO_GIOP::CancelRequest: + case TAO_GIOP::LocateRequest: + case TAO_GIOP::CloseConnection: + default: + // @@ Errors for the time being. + // @@ this->reply_handler_->error (); + ACE_ERROR_RETURN ((LM_ERROR, + "TAO (%P|%t) %N:%l handle_client_input: " + "wrong message.\n"), + -1); + + case TAO_GIOP::LocateReply: + case TAO_GIOP::Reply: + // Handle after the switch. + break; + } + + // For GIOP 1.0 and 1.1 the reply_ctx comes first: + // @@ Use to make this work with GIOP 1.2 + if ((input >> reply_ctx) == 0) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) TAO_GIOP::parse_reply, " + "extracting context\n")); + return -1; + } + + // Read the request id + if (!input.read_ulong (request_id)) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) : TAO_GIOP::parse_reply, " + "extracting request id")); + return -1; + } + + // and the reply status type. + // status can be NO_EXCEPTION, SYSTEM_EXCEPTION, USER_EXCEPTION, + // LOCATION_FORWARD or (on GIOP 1.2) LOCATION_FORWARD_PERM + if (!input.read_ulong (reply_status)) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) : TAO_GIOP::parse_reply, " + "extracting reply status\n")); + return -1; + } + return 0; +} + +// **************************************************************** + +int +TAO_GIOP::process_server_message (TAO_Transport *transport, + TAO_ORB_Core *orb_core, + TAO_InputCDR &input, + const TAO_GIOP_MessageHeader& header) +{ + char repbuf[ACE_CDR::DEFAULT_BUFSIZE]; +#if defined(ACE_HAS_PURIFY) + (void) ACE_OS::memset (repbuf, '\0', sizeof (repbuf)); +#endif /* ACE_HAS_PURIFY */ + TAO_OutputCDR output (repbuf, sizeof(repbuf), + TAO_ENCAP_BYTE_ORDER, + orb_core->output_cdr_buffer_allocator (), + orb_core->output_cdr_dblock_allocator (), + orb_core->orb_params ()->cdr_memcpy_tradeoff ()); + + int result = 0; + int error_encountered = 0; + CORBA::Boolean response_required = 0; + CORBA::ULong request_id = 0; + + CORBA::Environment &ACE_TRY_ENV = CORBA::default_environment (); + ACE_TRY + { + TAO_MINIMAL_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_RECEIVE_REQUEST_END); + + // Check to see if we've been cancelled cooperatively. + if (orb_core->orb ()->should_shutdown () != 0) + error_encountered = 1; + else + { + switch (header.message_type) + { + case TAO_GIOP::Request: + // Message was successfully read, so handle it. If we + // encounter any errors, will be set + // appropriately by the called code, and -1 will be + // returned. + if (TAO_GIOP::process_server_request (transport, + orb_core, + input, + output, + response_required, + request_id, + ACE_TRY_ENV) == -1) + error_encountered = 1; + ACE_TRY_CHECK; + break; + + case TAO_GIOP::LocateRequest: + if (TAO_GIOP::process_server_locate (transport, + orb_core, + input, + output, + response_required, + request_id, + ACE_TRY_ENV) == -1) + error_encountered = 1; + ACE_TRY_CHECK; + break; + + // These messages should never be sent to the server; + // it's an error if the peer tries. Set the environment + // accordingly, as it's not yet been reported as an + // error. + case TAO_GIOP::Reply: + case TAO_GIOP::LocateReply: + case TAO_GIOP::CloseConnection: + default: // Unknown message + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Illegal message received by server\n")); + ACE_TRY_THROW (CORBA::COMM_FAILURE ()); + // NOTREACHED + + case TAO_GIOP::CommunicationError: + case TAO_GIOP::MessageError: + // Here, MessageError can either mean condition for + // GIOP::MessageError happened or a GIOP message was + // not successfully received. Sending back of + // GIOP::MessageError is handled in TAO_GIOP::parse_header. + error_encountered = 1; + break; + } + } + } + ACE_CATCHANY // Only CORBA exceptions are caught here. + { + if (response_required) + return TAO_GIOP::send_reply_exception (transport, + orb_core, + request_id, + &ACE_ANY_EXCEPTION); + else + { + if (TAO_debug_level > 0) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) exception thrown " + "but client is not waiting a response\n")); + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "TAO: "); + } + + // It is unfotunate that an exception (probably a system + // exception) was thrown by the upcall code (even by the + // user) when the client was not expecting a response. + // However, in this case, we cannot close the connection + // down, since it really isn't the client's fault. + result = 0; + } + return result; + } +#if defined (TAO_HAS_EXCEPTIONS) + ACE_CATCHALL + { + // @@ TODO some c++ exception or another, but what do we do with + // it? + // We are supposed to map it into a CORBA::UNKNOWN exception. + // BTW, this cannot be detected if using the mapping. + // If we have native exceptions but no support for them + // in the ORB we should still be able to catch it. + // If we don't have native exceptions it couldn't have been + // raised in the first place! + + ACE_ERROR ((LM_ERROR, + "(%P|%t) closing conn %d after C++ exception %p\n", + trasnport.get_handle (), + "TAO_GIOP::process_server_message")); + return -1; + } +#endif /* TAO_HAS_EXCEPTIONS */ + ACE_ENDTRY; + + if (response_required) + { + if (!error_encountered) + TAO_GIOP::send_message (transport, + output, + orb_core); + else + { + // No exception but some kind of error, yet a response is + // required. + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "TAO: (%P|%t) %s: closing conn, no exception, " + "but expecting response\n", + "TAO_GIOP::process_server_message")); + return -1; + } + } + else if (error_encountered) + { + // No exception, no response expected, but an error ocurred, + // close the socket. + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "TAO: (%P|%t) %s: closing conn, no exception, " + "but expecting response\n", + "TAO_GIOP::process_server_message")); + return -1; + } + + TAO_MINIMAL_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_HANDLE_INPUT_END); + + return result; +} + + +int +TAO_GIOP::process_server_request (TAO_Transport *transport, + TAO_ORB_Core* orb_core, + TAO_InputCDR &input, + TAO_OutputCDR &output, + CORBA::Boolean &response_required, + CORBA::ULong &request_id, + CORBA::Environment &ACE_TRY_ENV) +{ + // This will extract the request header, set as + // appropriate. + TAO_GIOP_ServerRequest request (input, + output, + orb_core, + ACE_TRY_ENV); + ACE_CHECK_RETURN (-1); + + // The request_id_ field in request will be 0 if something went + // wrong before it got a chance to read it out. + request_id = request.request_id (); + + response_required = request.response_expected (); + +#if !defined (TAO_NO_IOR_TABLE) + + const CORBA::Octet *object_key = request.object_key ().get_buffer (); + + if (ACE_OS::memcmp (object_key, + &TAO_POA::objectkey_prefix[0], + TAO_POA::TAO_OBJECTKEY_PREFIX_SIZE) != 0) + { + ACE_CString object_id (ACE_reinterpret_cast (const char *, object_key), + request.object_key ().length (), + 0, + 0); + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "Simple Object key %s. Doing the Table Lookup ...\n", + object_id.c_str ())); + + CORBA::Object_ptr object_reference; + + // Do the Table Lookup. + int status = + orb_core->orb ()->_tao_find_in_IOR_table (object_id, + object_reference); + + // If ObjectID not in table or reference is nil raise OBJECT_NOT_EXIST. + + if (CORBA::is_nil (object_reference) || status == -1) + ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (), -1); + + // ObjectID present in the table with an associated NON-NULL reference. + // Throw a forward request exception. + + CORBA::Object_ptr dup = CORBA::Object::_duplicate (object_reference); + + // @@ We could simply write the response at this point... + ACE_THROW_RETURN (PortableServer::ForwardRequest (dup), -1); + } + +#endif /* TAO_NO_IOR_TABLE */ + + orb_core->object_adapter ()->dispatch_servant (request.object_key (), + request, + 0, + ACE_TRY_ENV); + ACE_CHECK_RETURN (-1); + + return 0; +} + +int +TAO_GIOP::process_server_locate (TAO_Transport *transport, + TAO_ORB_Core* orb_core, + TAO_InputCDR &input, + TAO_OutputCDR &output, + CORBA::Boolean &response_required, + CORBA::ULong &request_id, + CORBA::Environment &ACE_TRY_ENV) +{ + // TAO_FUNCTION_PP_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_HANDLE_LOCATE_START); + + // This will extract the request header, set as + // appropriate. + TAO_GIOP_LocateRequestHeader locateRequestHeader; + + request_id = locateRequestHeader.request_id; + response_required = 0; + if (locateRequestHeader.init (input, ACE_TRY_ENV) == 0) + return -1; + ACE_CHECK_RETURN (-1); + + // Copy the request ID to be able to respond in case of an + // exception. + request_id = locateRequestHeader.request_id; + response_required = 1; + + char repbuf[ACE_CDR::DEFAULT_BUFSIZE]; + TAO_OutputCDR dummy_output (repbuf, sizeof(repbuf)); + // This output CDR is not used! + + TAO_ObjectKey tmp_key (locateRequestHeader.object_key.length (), + locateRequestHeader.object_key.length (), + locateRequestHeader.object_key.get_buffer (), + 0); + + CORBA::Object_var forward_location_var; + TAO_GIOP_LocateStatusType status; + + TAO_GIOP_ServerRequest serverRequest (locateRequestHeader.request_id, + response_required, + tmp_key, + "_non_existent", + dummy_output, + orb_core, + ACE_TRY_ENV); + + ACE_TRY + { + orb_core->object_adapter ()->dispatch_servant (serverRequest.object_key (), + serverRequest, + 0, + ACE_TRY_ENV); + ACE_TRY_CHECK; + + if (serverRequest.exception_type () == TAO_GIOP_NO_EXCEPTION) + { + // we got no exception, so the object is here + status = TAO_GIOP_OBJECT_HERE; + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO: (%P|%t) handle_locate() : found\n")); + } + else if (serverRequest.exception_type () != TAO_GIOP_NO_EXCEPTION) + { + forward_location_var = serverRequest.forward_location (); + if (!CORBA::is_nil (forward_location_var.in ())) + { + status = TAO_GIOP_OBJECT_FORWARD; + ACE_DEBUG ((LM_DEBUG, + "handle_locate has been called: forwarding\n")); + } + else + { + // Normal exception, so the object is not here + status = TAO_GIOP_UNKNOWN_OBJECT; + ACE_DEBUG ((LM_DEBUG, + "handle_locate has been called: not here\n")); + } + } + + } +#if !defined (TAO_HAS_MINIMUM_CORBA) + ACE_CATCH (PortableServer::ForwardRequest, forward_request) + { + status = TAO_GIOP_OBJECT_FORWARD; + forward_location_var = forward_request.forward_reference; + ACE_DEBUG ((LM_DEBUG, + "handle_locate has been called: forwarding\n")); + } +#endif /* TAO_HAS_MINIMUM_CORBA */ + ACE_CATCHANY + { + // Normal exception, so the object is not here + status = TAO_GIOP_UNKNOWN_OBJECT; + ACE_DEBUG ((LM_DEBUG, + "handle_locate has been called: not here\n")); + } + ACE_ENDTRY; + + // Create the response. + TAO_GIOP::start_message (TAO_GIOP::LocateReply, + output, + orb_core); + output.write_ulong (locateRequestHeader.request_id); + output.write_ulong (status); + + if (status == TAO_GIOP_OBJECT_FORWARD) + { + CORBA::Object_ptr object_ptr = forward_location_var.in (); + if ((output << object_ptr) == 0) + { + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + "Server_Connection_Handler::handle_locate - " + "error marshaling forwarded reference\n")); + } + response_required = 0; + return -1; + } + } + + return 0; +} + +int +TAO_GIOP::send_reply_exception (TAO_Transport *transport, + TAO_ORB_Core* orb_core, + CORBA::ULong request_id, + CORBA::Exception *x) +{ + // Create a new output CDR stream + TAO_OutputCDR output; + + // Construct a REPLY header. + TAO_GIOP::start_message (TAO_GIOP::Reply, output, orb_core); + + // A new try/catch block, but if something goes wrong now we + // have no hope, just abort. + ACE_TRY_NEW_ENV + { + // create and write a dummy context + TAO_GIOP_ServiceContextList resp_ctx; + resp_ctx.length (0); + output << resp_ctx; + + // Write the request ID + output.write_ulong (request_id); + +#if !defined (TAO_HAS_MINIMUM_CORBA) + + // @@ TODO This is the place to conditionally compile + // forwarding. It certainly seems easy to strategize too, + // just invoke an strategy to finish marshalling the + // response. + + // Now we check for Forwarding *************************** + + // Try to narrow to ForwardRequest + PortableServer::ForwardRequest_ptr forward_request_ptr = + PortableServer::ForwardRequest::_narrow (x); + + // If narrowing of exception succeeded + if (forward_request_ptr != 0 + && !CORBA::is_nil (forward_request_ptr->forward_reference.in ())) + { + // write the reply_status + output.write_ulong (TAO_GIOP_LOCATION_FORWARD); + + // write the object reference into the stream + CORBA::Object_ptr object_ptr = + forward_request_ptr->forward_reference.in(); + + output << object_ptr; + } + // end of the forwarding code **************************** + else + +#endif /* TAO_HAS_MINIMUM_CORBA */ + + { + // Write the exception + CORBA::TypeCode_ptr except_tc = x->_type (); + + CORBA::exception_type extype = CORBA::USER_EXCEPTION; + if (CORBA::SystemException::_narrow (x) != 0) + extype = CORBA::SYSTEM_EXCEPTION; + + // write the reply_status + output.write_ulong (TAO_GIOP::convert_CORBA_to_GIOP_exception (extype)); + + // @@ Any way to implement this without interpretive + // marshaling??? + output.encode (except_tc, x, 0, ACE_TRY_ENV); + ACE_TRY_CHECK; + } + } + ACE_CATCH (CORBA_Exception, ex) + { + // now we know, that while handling the error an other error + // happened -> no hope, close connection. + + // close the handle + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) cannot marshal exception %p\n", + transport->handle (), + "TAO_GIOP::send_reply_exception")); + return -1; + } + ACE_ENDTRY; + + return TAO_GIOP::send_message (transport, output, orb_core); +} + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class TAO_Unbounded_Sequence; template class TAO_Unbounded_Sequence; diff --git a/TAO/tao/GIOP.h b/TAO/tao/GIOP.h index 2420d3dbb27..0ef9cb98ec8 100644 --- a/TAO/tao/GIOP.h +++ b/TAO/tao/GIOP.h @@ -152,7 +152,7 @@ public: MY_MINOR = 0 }; - CORBA::Char magic [4]; // "GIOP" + CORBA::Octet magic [4]; // "GIOP" TAO_GIOP_Version giop_version; CORBA::Octet byte_order; // 0 = big, 1 = little CORBA::Octet message_type; // MsgType above @@ -334,22 +334,11 @@ public: TAO_ORB_Core* orb_core); // Build the header for a message of type into stream . - static CORBA::Boolean send_request (TAO_Transport *transport, + static CORBA::Boolean send_message (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_message (TAO_Transport *transport, - TAO_InputCDR &msg, - TAO_ORB_Core *orb_core, - TAO_GIOP_Version &version, - int block); - // Reads message and returns message type from header. - // For reading the header, this call is *not* non-blocking. But for - // reading the rest of the message, it is non-blocking. Flag - // is to force blocking for the full reply. This is useful when we - // want to do nothing other than wait for the reply. - static void dump_msg (const char *label, const u_char *ptr, size_t len); @@ -370,6 +359,67 @@ public: static TAO_GIOP_ReplyStatusType convert_CORBA_to_GIOP_exception (CORBA::exception_type corba_type); // Convert the exception type from CORBA to GIOP + static int read_header (TAO_Transport *transport, + TAO_ORB_Core *orb_core, + TAO_GIOP_MessageHeader &header, + CORBA::ULong &header_size, + ACE_Message_Block *payload); + static int handle_input (TAO_Transport *transport, + TAO_ORB_Core *orb_core, + TAO_GIOP_MessageHeader &header, + CORBA::ULong ¤t_offset, + ACE_Message_Block *payload); + + static int parse_reply (TAO_Transport *transport, + TAO_ORB_Core *orb_core, + TAO_InputCDR& input, + const TAO_GIOP_MessageHeader& header, + TAO_GIOP_ServiceContextList& reply_ctx, + CORBA::ULong& request_id, + CORBA::ULong& reply_status); + static int process_server_message (TAO_Transport *transport, + TAO_ORB_Core *orb_core, + TAO_InputCDR &cdr, + const TAO_GIOP_MessageHeader& header); + + static int process_server_request (TAO_Transport *transport, + TAO_ORB_Core* orb_core, + TAO_InputCDR &input, + TAO_OutputCDR &output, + CORBA::Boolean &response_required, + CORBA::ULong &request_id, + CORBA::Environment &ACE_TRY_ENV); + // A request was received on the server side. + // is the source of the message (and thus where the + // replies should be sent). + // is the ORB that received the message + // contains the message + // can be used to store any responses + // and are set as part of the + // message processing. + + static int process_server_locate (TAO_Transport *transport, + TAO_ORB_Core* orb_core, + TAO_InputCDR &input, + TAO_OutputCDR &output, + CORBA::Boolean &response_required, + CORBA::ULong &request_id, + CORBA::Environment &ACE_TRY_ENV); + // A LocateRequest was received on the server side. + // is the source of the message (and thus where the + // replies should be sent). + // is the ORB that received the message + // contains the message + // can be used to store any responses + // and are set as part of the + // message processing. + + static int send_reply_exception (TAO_Transport *transport, + TAO_ORB_Core* orb_core, + CORBA::ULong request_id, + CORBA::Exception *x); + // We must send a LocateReply through , this request + // resulted in some kind of exception. private: static CORBA::Boolean start_message_lite (TAO_GIOP::Message_Type t, @@ -382,19 +432,13 @@ private: // Build the standard header for a message of type into // stream . - static int parse_header_std (TAO_InputCDR &cdr, - int& do_byte_swap, - TAO_GIOP::Message_Type& message_type, - CORBA::ULong& message_size); - static int parse_header_lite (TAO_InputCDR &cdr, - int& do_byte_swap, - TAO_GIOP::Message_Type& message_type, - CORBA::ULong& message_size); - static int parse_header (TAO_InputCDR &cdr, - int& do_byte_swap, - TAO_GIOP::Message_Type& message_type, - CORBA::ULong& message_size, - TAO_ORB_Core *orb_core); + static int parse_header_std (ACE_Message_Block *payload, + TAO_GIOP_MessageHeader& header); + static int parse_header_lite (ACE_Message_Block *payload, + TAO_GIOP_MessageHeader& header); + static int parse_header (TAO_ORB_Core *orb_core, + ACE_Message_Block *payload, + TAO_GIOP_MessageHeader& header); // Parse the header, extracting all the relevant info. }; diff --git a/TAO/tao/GIOP_Server_Request.cpp b/TAO/tao/GIOP_Server_Request.cpp index 18bb3b19026..c0f71ad6278 100644 --- a/TAO/tao/GIOP_Server_Request.cpp +++ b/TAO/tao/GIOP_Server_Request.cpp @@ -40,10 +40,10 @@ ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Server_Request_Timeprobe_Description, #endif /* ACE_ENABLE_TIMEPROBES */ -GIOP_ServerRequest::GIOP_ServerRequest (TAO_InputCDR &input, - TAO_OutputCDR &output, - TAO_ORB_Core *orb_core, - CORBA::Environment &env) +TAO_GIOP_ServerRequest::TAO_GIOP_ServerRequest (TAO_InputCDR &input, + TAO_OutputCDR &output, + TAO_ORB_Core *orb_core, + CORBA::Environment &env) : incoming_ (&input), outgoing_ (&output), response_expected_ (0), @@ -69,7 +69,7 @@ GIOP_ServerRequest::GIOP_ServerRequest (TAO_InputCDR &input, } void -GIOP_ServerRequest::parse_header_std (CORBA::Environment &ACE_TRY_ENV) +TAO_GIOP_ServerRequest::parse_header_std (CORBA::Environment &ACE_TRY_ENV) { // Tear out the service context ... we currently ignore it, but it // should probably be passed to each ORB service as appropriate @@ -127,7 +127,7 @@ GIOP_ServerRequest::parse_header_std (CORBA::Environment &ACE_TRY_ENV) } void -GIOP_ServerRequest::parse_header_lite (CORBA::Environment &ACE_TRY_ENV) +TAO_GIOP_ServerRequest::parse_header_lite (CORBA::Environment &ACE_TRY_ENV) { TAO_InputCDR& input = *this->incoming_; @@ -170,7 +170,7 @@ GIOP_ServerRequest::parse_header_lite (CORBA::Environment &ACE_TRY_ENV) void -GIOP_ServerRequest::parse_header (CORBA::Environment &env) +TAO_GIOP_ServerRequest::parse_header (CORBA::Environment &env) { if (this->orb_core_->orb_params ()->use_lite_protocol ()) this->parse_header_lite (env); @@ -180,13 +180,13 @@ GIOP_ServerRequest::parse_header (CORBA::Environment &env) // This constructor is used, by the locate request code -GIOP_ServerRequest::GIOP_ServerRequest (CORBA::ULong &request_id, - CORBA::Boolean &response_expected, - TAO_ObjectKey &object_key, - const ACE_CString &operation, - TAO_OutputCDR &output, - TAO_ORB_Core *orb_core, - CORBA::Environment &) +TAO_GIOP_ServerRequest::TAO_GIOP_ServerRequest (CORBA::ULong &request_id, + CORBA::Boolean &response_expected, + TAO_ObjectKey &object_key, + const ACE_CString &operation, + TAO_OutputCDR &output, + TAO_ORB_Core *orb_core, + CORBA::Environment &) : operation_ (operation), incoming_ (0), outgoing_ (&output), @@ -209,7 +209,7 @@ GIOP_ServerRequest::GIOP_ServerRequest (CORBA::ULong &request_id, { } -GIOP_ServerRequest::~GIOP_ServerRequest (void) +TAO_GIOP_ServerRequest::~TAO_GIOP_ServerRequest (void) { #if !defined (TAO_HAS_MINIMUM_CORBA) @@ -224,13 +224,13 @@ GIOP_ServerRequest::~GIOP_ServerRequest (void) } CORBA::ORB_ptr -GIOP_ServerRequest::orb (void) +TAO_GIOP_ServerRequest::orb (void) { return this->orb_core_->orb (); } TAO_POA * -GIOP_ServerRequest::oa (void) +TAO_GIOP_ServerRequest::oa (void) { return this->orb_core_->root_poa (); } @@ -241,8 +241,8 @@ GIOP_ServerRequest::oa (void) // inout/out/return values later on. void -GIOP_ServerRequest::arguments (CORBA::NVList_ptr &list, - CORBA::Environment &env) +TAO_GIOP_ServerRequest::arguments (CORBA::NVList_ptr &list, + CORBA::Environment &env) { env.clear (); @@ -280,7 +280,7 @@ GIOP_ServerRequest::arguments (CORBA::NVList_ptr &list, param_name = "(no name given)"; ACE_ERROR ((LM_ERROR, - "GIOP_ServerRequest::arguments - problem while" + "TAO_GIOP_ServerRequest::arguments - problem while" " decoding parameter %d <%s>\n", i, param_name)); return; } @@ -314,7 +314,7 @@ GIOP_ServerRequest::arguments (CORBA::NVList_ptr &list, if (incoming_->length () != 0) { ACE_ERROR ((LM_ERROR, - "GIOP_ServerRequest::arguments - " + "TAO_GIOP_ServerRequest::arguments - " "%d bytes left in buffer\n", incoming_->length ())); env.exception (new CORBA::BAD_PARAM ()); } @@ -325,7 +325,7 @@ GIOP_ServerRequest::arguments (CORBA::NVList_ptr &list, // only after the parameter list has been provided (maybe empty). void -GIOP_ServerRequest::set_result (const CORBA::Any &value, +TAO_GIOP_ServerRequest::set_result (const CORBA::Any &value, CORBA::Environment &env) { env.clear (); @@ -343,8 +343,8 @@ GIOP_ServerRequest::set_result (const CORBA::Any &value, // Store the exception value. void -GIOP_ServerRequest::set_exception (const CORBA::Any &value, - CORBA::Environment &env) +TAO_GIOP_ServerRequest::set_exception (const CORBA::Any &value, + CORBA::Environment &env) { if (this->retval_ || this->exception_) env.exception (new CORBA::BAD_INV_ORDER ()); @@ -355,7 +355,7 @@ GIOP_ServerRequest::set_exception (const CORBA::Any &value, // Try to narrow to ForwardRequest PortableServer::ForwardRequest_ptr forward_request = - PortableServer::ForwardRequest::_narrow ((CORBA::Exception *) value.value ()); + PortableServer::ForwardRequest::_narrow ((CORBA::Exception *) value.value ()); // If narrowing of exception succeeded if (forward_request != 0) @@ -386,7 +386,7 @@ GIOP_ServerRequest::set_exception (const CORBA::Any &value, // parameters void -GIOP_ServerRequest::dsi_marshal (CORBA::Environment &env) +TAO_GIOP_ServerRequest::dsi_marshal (CORBA::Environment &env) { // NOTE: if "env" is set, it takes precedence over exceptions // reported using the mechanism of the ServerRequest. Only system @@ -449,11 +449,11 @@ GIOP_ServerRequest::dsi_marshal (CORBA::Environment &env) // Extension void -GIOP_ServerRequest::demarshal (CORBA::Environment &orb_env, - // ORB related exception reporting - const TAO_Call_Data_Skel *info, - // call description - ...) +TAO_GIOP_ServerRequest::demarshal (CORBA::Environment &orb_env, + // ORB related exception reporting + const TAO_Call_Data_Skel *info, + // call description + ...) { CORBA::ULong i; const TAO_Param_Data_Skel *pdp; @@ -475,7 +475,7 @@ GIOP_ServerRequest::demarshal (CORBA::Environment &orb_env, if (orb_env.exception ()) { - orb_env.print_exception ("GIOP_ServerRequest::demarshal - parameter decode failed"); + orb_env.print_exception ("TAO_GIOP_ServerRequest::demarshal - parameter decode failed"); return; } } @@ -485,13 +485,13 @@ GIOP_ServerRequest::demarshal (CORBA::Environment &orb_env, // Extension void -GIOP_ServerRequest::marshal (CORBA::Environment &orb_env, - // ORB related exception reporting - // CORBA::Environment &skel_env, - // skeleton related exception reporting - const TAO_Call_Data_Skel *info, - // call description - ...) +TAO_GIOP_ServerRequest::marshal (CORBA::Environment &orb_env, + // ORB related exception reporting + // CORBA::Environment &skel_env, + // skeleton related exception reporting + const TAO_Call_Data_Skel *info, + // call description + ...) { // what is "orb_env" and "skel_env"? // "skel_env" holds the exception that got raised inside the operation @@ -559,7 +559,7 @@ GIOP_ServerRequest::marshal (CORBA::Environment &orb_env, if (orb_env.exception ()) { - orb_env.print_exception ("GIOP_ServerRequest::marshal - parameter encode failed"); + orb_env.print_exception ("TAO_GIOP_ServerRequest::marshal - parameter encode failed"); return; } } @@ -568,7 +568,7 @@ GIOP_ServerRequest::marshal (CORBA::Environment &orb_env, } void -GIOP_ServerRequest::init_reply (CORBA::Environment &env) +TAO_GIOP_ServerRequest::init_reply (CORBA::Environment &env) { // Construct a REPLY header. TAO_GIOP::start_message (TAO_GIOP::Reply, @@ -591,7 +591,7 @@ GIOP_ServerRequest::init_reply (CORBA::Environment &env) if ((*this->outgoing_ << object_ptr) == 0) { ACE_DEBUG ((LM_DEBUG, - "GIOP_ServerRequest::marshal - " + "TAO_GIOP_ServerRequest::marshal - " "encoding forwarded objref failed\n")); return; } @@ -619,14 +619,14 @@ GIOP_ServerRequest::init_reply (CORBA::Environment &env) } CORBA::Object_ptr -GIOP_ServerRequest::forward_location (void) +TAO_GIOP_ServerRequest::forward_location (void) // get the forward_location { return CORBA::Object::_duplicate (this->forward_location_.in ()); } CORBA::ULong -GIOP_ServerRequest::exception_type (void) +TAO_GIOP_ServerRequest::exception_type (void) // get the exception type { return this->exception_type_; diff --git a/TAO/tao/GIOP_Server_Request.h b/TAO/tao/GIOP_Server_Request.h index f6fe0e2d9b9..292b271b91d 100644 --- a/TAO/tao/GIOP_Server_Request.h +++ b/TAO/tao/GIOP_Server_Request.h @@ -24,43 +24,49 @@ #include "tao/Server_Request.h" #include "tao/Principal.h" -class TAO_Export GIOP_ServerRequest : public CORBA_ServerRequest +class TAO_Export TAO_GIOP_ServerRequest : public CORBA_ServerRequest { // = TITLE // Class representing an GIOP ServerRequest object. public: // = Initialization and termination methods. - GIOP_ServerRequest (TAO_InputCDR &input, - TAO_OutputCDR &output, - TAO_ORB_Core *orb_core, - CORBA_Environment &TAO_IN_ENV = CORBA::default_environment ()); + TAO_GIOP_ServerRequest (TAO_InputCDR &input, + TAO_OutputCDR &output, + TAO_ORB_Core *orb_core, + CORBA_Environment &TAO_IN_ENV = + CORBA::default_environment ()); // Constructor - GIOP_ServerRequest (CORBA::ULong &request_id, - CORBA::Boolean &response_expected, - TAO_ObjectKey &object_key, - const ACE_CString &operation, - TAO_OutputCDR &output, - TAO_ORB_Core *orb_core, - CORBA_Environment &TAO_IN_ENV = CORBA::default_environment ()); - - virtual ~GIOP_ServerRequest (void); + TAO_GIOP_ServerRequest (CORBA::ULong &request_id, + CORBA::Boolean &response_expected, + TAO_ObjectKey &object_key, + const ACE_CString &operation, + TAO_OutputCDR &output, + TAO_ORB_Core *orb_core, + CORBA_Environment &TAO_IN_ENV = + CORBA::default_environment ()); + + virtual ~TAO_GIOP_ServerRequest (void); // Destructor. #if !defined (TAO_HAS_MINIMUM_CORBA) // = General ServerRequest operations void arguments (CORBA::NVList_ptr &list, - CORBA_Environment &TAO_IN_ENV = CORBA::default_environment ()); + CORBA_Environment &TAO_IN_ENV = + CORBA::default_environment ()); void set_result (const CORBA::Any &value, - CORBA_Environment &TAO_IN_ENV = CORBA::default_environment ()); + CORBA_Environment &TAO_IN_ENV = + CORBA::default_environment ()); void set_exception (const CORBA::Any &value, - CORBA_Environment &TAO_IN_ENV = CORBA::default_environment ()); + CORBA_Environment &TAO_IN_ENV = + CORBA::default_environment ()); - virtual void dsi_marshal (CORBA_Environment &TAO_IN_ENV = CORBA::default_environment ()); - // does the marshaling of outgoing parameters and is used by the DSI based - // scheme + virtual void dsi_marshal (CORBA_Environment &TAO_IN_ENV = + CORBA::default_environment ()); + // does the marshaling of outgoing parameters and is used by the DSI + // based scheme #endif /* TAO_HAS_MINIMUM_CORBA */ @@ -101,7 +107,8 @@ public: // marshal outgoing parameters and return value. This is used by the SSI // i.e., by the IDL compiler generated skeletons. - virtual void init_reply (CORBA_Environment &TAO_IN_ENV = CORBA::default_environment ()); + virtual void init_reply (CORBA_Environment &TAO_IN_ENV = + CORBA::default_environment ()); // start a Reply message virtual TAO_InputCDR &incoming (void); @@ -121,8 +128,8 @@ public: // The pseudo object methods, not really needed because the class is // not in the spec, but we add them for the sake of completeness. - static GIOP_ServerRequest* _duplicate (GIOP_ServerRequest*); - static GIOP_ServerRequest* _nil (void); + static TAO_GIOP_ServerRequest* _duplicate (TAO_GIOP_ServerRequest*); + static TAO_GIOP_ServerRequest* _nil (void); // To handle System Exceptions at the lowest level, // a method returning the request_id_ is needed. diff --git a/TAO/tao/GIOP_Server_Request.i b/TAO/tao/GIOP_Server_Request.i index c21bec56381..5f2ab14107e 100644 --- a/TAO/tao/GIOP_Server_Request.i +++ b/TAO/tao/GIOP_Server_Request.i @@ -5,20 +5,20 @@ // using reference counting wouldn't help much. Using a _clone() // method would make the following methods really easy to implement, // but that's hard to implement for the extremely optimized -// GIOP_ServerRequest. +// TAO_GIOP_ServerRequest. // Another solution would be to modify the class hierarchy, make // ServerRequest the "slow" version (with copies for each field) and -// GIOP_ServerRequest the "fast" version (with no copies at all). The +// TAO_GIOP_ServerRequest the "fast" version (with no copies at all). The // first would be use for DII and the later for SII. ACE_INLINE TAO_InputCDR & -GIOP_ServerRequest::incoming (void) +TAO_GIOP_ServerRequest::incoming (void) { return *this->incoming_; } ACE_INLINE TAO_OutputCDR & -GIOP_ServerRequest::outgoing (void) +TAO_GIOP_ServerRequest::outgoing (void) { return *this->outgoing_; } @@ -26,14 +26,14 @@ GIOP_ServerRequest::outgoing (void) // Invocation attributes. ACE_INLINE const char * -GIOP_ServerRequest::operation (void) const +TAO_GIOP_ServerRequest::operation (void) const { return this->operation_.c_str (); } // get the length of the operation name. ACE_INLINE unsigned int -GIOP_ServerRequest::operation_length (void) const +TAO_GIOP_ServerRequest::operation_length (void) const { return this->operation_.length (); } @@ -41,38 +41,38 @@ GIOP_ServerRequest::operation_length (void) const #if 0 //@@ (TAO) to do after Context is implemented ACE_INLINE CORBA::Context_ptr -GIOP_ServerRequest::ctx (void) +TAO_GIOP_ServerRequest::ctx (void) { return 0; } #endif ACE_INLINE CORBA::Boolean -GIOP_ServerRequest::response_expected (void) const +TAO_GIOP_ServerRequest::response_expected (void) const { return this->response_expected_; } ACE_INLINE CORBA::Principal_ptr -GIOP_ServerRequest::principal (void) const +TAO_GIOP_ServerRequest::principal (void) const { return this->requesting_principal_.ptr (); } ACE_INLINE const TAO_ObjectKey & -GIOP_ServerRequest::object_key (void) const +TAO_GIOP_ServerRequest::object_key (void) const { return this->object_key_; } ACE_INLINE const TAO_GIOP_ServiceContextList & -GIOP_ServerRequest::service_info (void) const +TAO_GIOP_ServerRequest::service_info (void) const { return this->service_info_; } ACE_INLINE CORBA::ULong -GIOP_ServerRequest::request_id (void) +TAO_GIOP_ServerRequest::request_id (void) { return this->request_id_; } diff --git a/TAO/tao/IIOP_Connect.cpp b/TAO/tao/IIOP_Connect.cpp index 7d163075119..4bfc16a2de0 100644 --- a/TAO/tao/IIOP_Connect.cpp +++ b/TAO/tao/IIOP_Connect.cpp @@ -4,11 +4,8 @@ #include "tao/Timeprobe.h" #include "tao/IIOP_Transport.h" #include "tao/debug.h" -#include "tao/GIOP.h" -#include "tao/GIOP_Server_Request.h" #include "tao/ORB_Core.h" #include "tao/ORB.h" -#include "tao/POA.h" #include "tao/CDR.h" #include "tao/Wait_Strategy.h" @@ -76,12 +73,16 @@ TAO_IIOP_Handler_Base::TAO_IIOP_Handler_Base (ACE_Thread_Manager *t) } TAO_IIOP_Server_Connection_Handler::TAO_IIOP_Server_Connection_Handler (ACE_Thread_Manager *t) - : TAO_IIOP_Handler_Base (t ? t : TAO_ORB_Core_instance()->thr_mgr ()), - orb_core_ (TAO_ORB_Core_instance ()), - tss_resources_ (TAO_ORB_CORE_TSS_RESOURCES::instance ()) + : TAO_IIOP_Handler_Base (t), + orb_core_ (0), + tss_resources_ (0) { - iiop_transport_ = new TAO_IIOP_Server_Transport(this, - this->orb_core_); + // This constructor should *never* get called, it is just here to + // make the compiler happy: the default implementation of the + // Creation_Strategy requires a constructor with that signature, we + // don't use that implementation, but some (most?) compilers + // instantiate it anyway. + ACE_ASSERT (this->orb_core_ != 0); } TAO_IIOP_Server_Connection_Handler::TAO_IIOP_Server_Connection_Handler (TAO_ORB_Core *orb_core) @@ -89,6 +90,7 @@ TAO_IIOP_Server_Connection_Handler::TAO_IIOP_Server_Connection_Handler (TAO_ORB_ orb_core_ (orb_core), tss_resources_ (TAO_ORB_CORE_TSS_RESOURCES::instance ()) { + message_header_.message_size = 0; iiop_transport_ = new TAO_IIOP_Server_Transport(this, this->orb_core_); } @@ -251,81 +253,13 @@ TAO_IIOP_Server_Connection_Handler::handle_message (TAO_InputCDR &input, CORBA::ULong &request_id, CORBA::Environment &ACE_TRY_ENV) { - // This will extract the request header, set as - // appropriate. - GIOP_ServerRequest request (input, - output, - this->orb_core_, - ACE_TRY_ENV); - ACE_CHECK_RETURN (-1); - - // The request_id_ field in request will be 0 if something went - // wrong before it got a chance to read it out. - request_id = request.request_id (); - - response_required = request.response_expected (); - -#if !defined (TAO_NO_IOR_TABLE) - - const CORBA::Octet *object_key = request.object_key ().get_buffer (); - - if (ACE_OS::memcmp (object_key, - &TAO_POA::objectkey_prefix[0], - TAO_POA::TAO_OBJECTKEY_PREFIX_SIZE) != 0) - { - ACE_CString object_id (ACE_reinterpret_cast (const char *, object_key), - request.object_key ().length (), - 0, - 0); - - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, - "Simple Object key %s. Doing the Table Lookup ...\n", - object_id.c_str ())); - - CORBA::Object_ptr object_reference; - - // Do the Table Lookup. - int status = - this->orb_core_->orb ()->_tao_find_in_IOR_table (object_id, - object_reference); - - // If ObjectID not in table or reference is nil raise OBJECT_NOT_EXIST. - - if (CORBA::is_nil (object_reference) || status == -1) - ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (), -1); - - // ObjectID present in the table with an associated NON-NULL reference. - // Throw a forward request exception. - - CORBA::Object_ptr dup = CORBA::Object::_duplicate (object_reference); - - ACE_THROW_RETURN (PortableServer::ForwardRequest (dup), -1); - } - -#endif /* TAO_NO_IOR_TABLE */ - - // So, we read a request, now handle it using something more - // primitive than a CORBA2 ServerRequest pseudo-object. - - // @@ (CJC) We need to create a TAO-specific request which will hold - // context for a request such as the connection handler ("this") over - // which the request was received so that the servicer of the request - // has sufficient context to send a response on its own. - // - // One thing which me must be careful of is that responses are sent - // with a single write so that they're not accidentally interleaved - // over the transport (as could happen using TCP). - - this->orb_core_->object_adapter ()->dispatch_servant (request.object_key (), - request, - 0, - ACE_TRY_ENV); - // NEED TO CHECK FOR any errors present in and set the return - // code appropriately. - ACE_CHECK_RETURN (-1); - - return 0; + return TAO_GIOP::process_server_request (this->transport (), + this->orb_core_, + input, + output, + response_required, + request_id, + ACE_TRY_ENV); } int @@ -333,144 +267,15 @@ TAO_IIOP_Server_Connection_Handler::handle_locate (TAO_InputCDR &input, TAO_OutputCDR &output, CORBA::Boolean &response_required, CORBA::ULong &request_id, - CORBA::Environment &env) + CORBA::Environment &ACE_TRY_ENV) { - TAO_FUNCTION_PP_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_HANDLE_LOCATE_START); - - // This will extract the request header, set as - // appropriate. - TAO_GIOP_LocateRequestHeader locateRequestHeader; - - env.clear (); - if (locateRequestHeader.init (input, env) == 0) - { - request_id = locateRequestHeader.request_id; - response_required = 0; - return -1; - } - - // Copy the request ID to be able to respond in case of an - // exception. - request_id = locateRequestHeader.request_id; - response_required = 1; - - char repbuf[ACE_CDR::DEFAULT_BUFSIZE]; - TAO_OutputCDR dummy_output (repbuf, sizeof(repbuf)); - // This output CDR is not used! - - TAO_ObjectKey tmp_key (locateRequestHeader.object_key.length (), - locateRequestHeader.object_key.length (), - locateRequestHeader.object_key.get_buffer (), - 0); - - CORBA::Object_var forward_location_var; - TAO_GIOP_LocateStatusType status; - - GIOP_ServerRequest serverRequest (locateRequestHeader.request_id, - response_required, - tmp_key, - "_non_existent", - dummy_output, - this->orb_core_, - env); - - this->orb_core_->object_adapter ()->dispatch_servant (serverRequest.object_key (), - serverRequest, - 0, - env); - - if (serverRequest.exception_type () == TAO_GIOP_NO_EXCEPTION - && env.exception () == 0) - { - // we got no exception, so the object is here - status = TAO_GIOP_OBJECT_HERE; - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, - "TAO: (%P|%t) handle_locate() : found\n")); - } - else if (serverRequest.exception_type () != TAO_GIOP_NO_EXCEPTION) - { - forward_location_var = serverRequest.forward_location (); - if (!CORBA::is_nil (forward_location_var.in ())) - { - status = TAO_GIOP_OBJECT_FORWARD; - ACE_DEBUG ((LM_DEBUG, - "handle_locate has been called: forwarding\n")); - } - else - { - // Normal exception, so the object is not here - status = TAO_GIOP_UNKNOWN_OBJECT; - ACE_DEBUG ((LM_DEBUG, - "handle_locate has been called: not here\n")); - } - - // The locate_servant call might have thrown an exception but we - // don't want to marshal it because it is no failure. The - // proper Locacte_Reply will tell the client what is going on. - - // Remove the exception - env.clear (); - } - else - { - -#if !defined (TAO_HAS_MINIMUM_CORBA) - - // Try to narrow to ForwardRequest - PortableServer::ForwardRequest_ptr forward_request_ptr = - PortableServer::ForwardRequest::_narrow (env.exception ()); - - // If narrowing of exception succeeded - if (forward_request_ptr != 0) - { - status = TAO_GIOP_OBJECT_FORWARD; - forward_location_var = forward_request_ptr->forward_reference; - ACE_DEBUG ((LM_DEBUG, - "handle_locate has been called: forwarding\n")); - } - else - -#endif /* TAO_HAS_MINIMUM_CORBA */ - - { - // Normal exception, so the object is not here - status = TAO_GIOP_UNKNOWN_OBJECT; - ACE_DEBUG ((LM_DEBUG, - "handle_locate has been called: not here\n")); - } - - // the locate_servant call might have thrown an exception but we - // don't want to marshal it because it is no failure. The - // proper Locacte_Reply will tell the client what is going on. - - // Remove the exception - env.clear (); - } - - // Create the response. - TAO_GIOP::start_message (TAO_GIOP::LocateReply, output, - this->orb_core_); - output.write_ulong (locateRequestHeader.request_id); - output.write_ulong (status); - - if (status == TAO_GIOP_OBJECT_FORWARD) - { - CORBA::Object_ptr object_ptr = forward_location_var.in (); - if ((output << object_ptr) == 0) - { - if (TAO_debug_level > 0) - { - ACE_DEBUG ((LM_DEBUG, - "Server_Connection_Handler::handle_locate - " - "error marshaling forwarded reference\n")); - } - response_required = 0; - return -1; - } - } - - return 0; + return TAO_GIOP::process_server_locate (this->transport (), + this->orb_core_, + input, + output, + response_required, + request_id, + ACE_TRY_ENV); } void @@ -478,303 +283,53 @@ TAO_IIOP_Server_Connection_Handler::send_response (TAO_OutputCDR &output) { TAO_FUNCTION_PP_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_SEND_RESPONSE_START); - TAO_GIOP::send_request (this->iiop_transport_, + TAO_GIOP::send_message (this->iiop_transport_, output, this->orb_core_); } -// This method is designed to return system exceptions to the caller. - -void -TAO_IIOP_Server_Connection_Handler::send_error (CORBA::ULong request_id, - CORBA::Exception *x) -{ - TAO_FUNCTION_PP_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_SEND_RESPONSE_START); - - // Create a new output CDR stream - TAO_OutputCDR output; - - // Construct a REPLY header. - TAO_GIOP::start_message (TAO_GIOP::Reply, output, - this->orb_core_); - - // A new try/catch block, but if something goes wrong now we - // have no hope, just abort. - ACE_TRY_NEW_ENV - { - // create and write a dummy context - TAO_GIOP_ServiceContextList resp_ctx; - resp_ctx.length (0); - output << resp_ctx; - - // Write the request ID - output.write_ulong (request_id); - -#if !defined (TAO_HAS_MINIMUM_CORBA) - - // @@ TODO This is the place to conditionally compile - // forwarding. It certainly seems easy to strategize too, - // just invoke an strategy to finish marshalling the - // response. - - // Now we check for Forwarding *************************** - - // Try to narrow to ForwardRequest - PortableServer::ForwardRequest_ptr forward_request_ptr = - PortableServer::ForwardRequest::_narrow (x); - - // If narrowing of exception succeeded - if (forward_request_ptr != 0 - && !CORBA::is_nil (forward_request_ptr->forward_reference.in ())) - { - // write the reply_status - output.write_ulong (TAO_GIOP_LOCATION_FORWARD); - - // write the object reference into the stream - CORBA::Object_ptr object_ptr = - forward_request_ptr->forward_reference.in(); - - output << object_ptr; - } - // end of the forwarding code **************************** - else - -#endif /* TAO_HAS_MINIMUM_CORBA */ - - { - // Write the exception - CORBA::TypeCode_ptr except_tc = x->_type (); - - CORBA::exception_type extype = CORBA::USER_EXCEPTION; - if (CORBA::SystemException::_narrow (x) != 0) - extype = CORBA::SYSTEM_EXCEPTION; - - // write the reply_status - output.write_ulong (TAO_GIOP::convert_CORBA_to_GIOP_exception (extype)); - - // write the actual exception - output.encode (except_tc, x, 0, ACE_TRY_ENV); - ACE_TRY_CHECK; - } - } - ACE_CATCH (CORBA_Exception, ex) - { - // now we know, that while handling the error an other error - // happened -> no hope, close connection. - - // close the handle - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) closing conn %d after fault %p\n", - this->peer().get_handle (), - "TAO_IIOP_Server_Connection_Handler::send_error")); - this->handle_close (); - return; - } - ACE_ENDTRY; - - // hand it to the next lower layer - TAO_GIOP::send_request (this->iiop_transport_, output, this->orb_core_); -} - int TAO_IIOP_Server_Connection_Handler::handle_input (ACE_HANDLE) { - // CJCXXX The tasks of this method should change to something like - // the following: - // 1. call into GIOP to pull off the header - // 2. construct a complete request - // 3. dispatch that request and return any required reply and errors - - TAO_FUNCTION_PP_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_HANDLE_INPUT_START); - - // @@ TODO This should take its memory from a specialized - // allocator. It is better to use a message block than a on stack - // buffer because we cannot minimize memory copies in that case. - TAO_InputCDR input (this->orb_core_->create_input_cdr_data_block (ACE_CDR::DEFAULT_BUFSIZE), - TAO_ENCAP_BYTE_ORDER, - this->orb_core_); - - char repbuf[ACE_CDR::DEFAULT_BUFSIZE]; -#if defined(ACE_HAS_PURIFY) - (void) ACE_OS::memset (repbuf, '\0', sizeof (repbuf)); -#endif /* ACE_HAS_PURIFY */ - TAO_OutputCDR output (repbuf, sizeof(repbuf), - TAO_ENCAP_BYTE_ORDER, - this->orb_core_->output_cdr_buffer_allocator (), - this->orb_core_->output_cdr_dblock_allocator (), - this->orb_core_->orb_params ()->cdr_memcpy_tradeoff ()); + int result = TAO_GIOP::handle_input (this->transport (), + this->orb_core_, + this->message_header_, + this->current_offset_, + &this->payload_); - int result = 0; - int error_encountered = 0; - CORBA::Boolean response_required = 0; - CORBA::ULong request_id = 0; - TAO_GIOP_Version version; - - CORBA::Environment &ACE_TRY_ENV = CORBA::default_environment (); - ACE_TRY + if (result == -1 && TAO_debug_level > 0) { - // Try to recv a new request. - - // Init the input message states in Transport. - this->iiop_transport_->message_size (0); - - // Recv message. Block for it. - TAO_GIOP::Message_Type type = - TAO_GIOP::recv_message (this->iiop_transport_, - input, - this->orb_core_, - version, - 1); - - TAO_MINIMAL_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_RECEIVE_REQUEST_END); - - // Check to see if we've been cancelled cooperatively. - if (this->orb_core_->orb ()->should_shutdown () != 0) - error_encountered = 1; - else - { - switch (type) - { - case TAO_GIOP::Request: - // Message was successfully read, so handle it. If we - // encounter any errors, will be set - // appropriately by the called code, and -1 will be - // returned. - if (this->handle_message (input, - output, - response_required, - request_id, - ACE_TRY_ENV) == -1) - error_encountered = 1; - ACE_TRY_CHECK; - break; - - case TAO_GIOP::LocateRequest: - if (this->handle_locate (input, - output, - response_required, - request_id, - ACE_TRY_ENV) == -1) - error_encountered = 1; - ACE_TRY_CHECK; - break; - - case TAO_GIOP::EndOfFile: - // Got a EOF - result = -1; - break; - - // These messages should never be sent to the server; - // it's an error if the peer tries. Set the environment - // accordingly, as it's not yet been reported as an - // error. - case TAO_GIOP::Reply: - case TAO_GIOP::LocateReply: - case TAO_GIOP::CloseConnection: - default: // Unknown message - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Illegal message received by server\n")); - ACE_TRY_THROW (CORBA::COMM_FAILURE ()); - // NOTREACHED - - case TAO_GIOP::CommunicationError: - case TAO_GIOP::MessageError: - // Here, MessageError can either mean condition for - // GIOP::MessageError happened or a GIOP message was - // not successfully received. Sending back of - // GIOP::MessageError is handled in TAO_GIOP::parse_header. - error_encountered = 1; - break; - } - } - } - ACE_CATCHANY // Only CORBA exceptions are caught here. - { - if (response_required) - this->send_error (request_id, &ex); - else - { - if (TAO_debug_level > 0) - { - ACE_ERROR ((LM_ERROR, - "(%P|%t) exception thrown " - "but client is not waiting a response\n")); - ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "TAO: "); - } - - // It is unfotunate that an exception (probably a system - // exception) was thrown by the upcall code (even by the - // user) when the client was not expecting a response. - // However, in this case, we cannot close the connection - // down, since it really isn't the client's fault. - result = 0; - } - return result; - } -#if defined (TAO_HAS_EXCEPTIONS) - ACE_CATCHALL - { - // @@ TODO some c++ exception or another, but what do we do with - // it? - // We are supposed to map it into a CORBA::UNKNOWN exception. - // BTW, this cannot be detected if using the mapping. - // If we have native exceptions but no support for them - // in the ORB we should still be able to catch it. - // If we don't have native exceptions it couldn't have been - // raised in the first place! - - ACE_ERROR ((LM_ERROR, - "(%P|%t) closing conn %d after fault %p\n", - this->peer().get_handle (), - "TAO_IIOP_Server_Connection_Handler::handle_input")); - // this->handle_close (); - return -1; + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "IIOP_Server_CH::handle_input, handle_input")); } -#endif /* TAO_HAS_EXCEPTIONS */ - ACE_ENDTRY; - - if (response_required) + if (result == 1) { - if (!error_encountered) - this->send_response (output); - else + TAO_GIOP_MessageHeader header_copy = this->message_header_; + this->message_header_.message_size = 0; + TAO_InputCDR input (&this->payload_, + header_copy.byte_order, + this->orb_core_); + result = TAO_GIOP::process_server_message (this->transport (), + this->orb_core_, + input, + header_copy); + if (result == -1 && TAO_debug_level > 0) { - // No exception but some kind of error, yet a response is - // required. - if (TAO_debug_level > 0) - ACE_ERROR ((LM_ERROR, - "TAO: (%P|%t) %s: closing conn, no exception, " - "but expecting response\n", - "TAO_IIOP_Server_Connection_Handler::handle_input")); - // this->handle_close (); - return -1; + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "IIOP_Server_CH::handle_input, upcall")); } } - else if (error_encountered) - { - // No exception, no response expected, but an error ocurred, - // close the socket. - if (TAO_debug_level > 0) - ACE_ERROR ((LM_ERROR, - "TAO: (%P|%t) %s: closing conn, no exception, " - "but expecting response\n", - "TAO_IIOP_Server_Connection_Handler::handle_input")); - // this->handle_close (); - return -1; - } - - TAO_MINIMAL_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_HANDLE_INPUT_END); - return result; } // **************************************************************** -// @@ For pluggable protocols, added a reference to the corresponding // transport obj. TAO_IIOP_Client_Connection_Handler:: TAO_IIOP_Client_Connection_Handler (ACE_Thread_Manager *t, - TAO_ORB_Core* orb_core) + TAO_ORB_Core* orb_core) : TAO_IIOP_Handler_Base (t) { iiop_transport_ = new TAO_IIOP_Client_Transport (this, diff --git a/TAO/tao/IIOP_Connect.h b/TAO/tao/IIOP_Connect.h index 02748ac6c7a..b5436016002 100644 --- a/TAO/tao/IIOP_Connect.h +++ b/TAO/tao/IIOP_Connect.h @@ -17,18 +17,19 @@ #ifndef TAO_IIOP_CONNECT_H #define TAO_IIOP_CONNECT_H -# include "ace/Reactor.h" +#include "ace/Reactor.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once +#pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -# include "ace/Acceptor.h" -# include "ace/SOCK_Acceptor.h" -# include "ace/Synch.h" -# include "ace/Svc_Handler.h" +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Synch.h" +#include "ace/Svc_Handler.h" -# include "tao/corbafwd.h" +#include "tao/corbafwd.h" +#include "tao/GIOP.h" // Forward Decls class TAO_Transport; @@ -128,7 +129,8 @@ public: TAO_OutputCDR &response, CORBA::Boolean &response_required, CORBA::ULong &request_id, - CORBA_Environment &TAO_IN_ENV = CORBA::default_environment ()); + CORBA_Environment &TAO_IN_ENV = + CORBA::default_environment ()); // Handle processing of the request residing in , setting // to zero if the request is for a oneway or // non-zero if for a two-way and to any necessary @@ -138,14 +140,13 @@ public: 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, CORBA::ULong &request_id, - CORBA_Environment &TAO_IN_ENV = CORBA::default_environment ()); + CORBA_Environment &TAO_IN_ENV = + CORBA::default_environment ()); // Handle processing of the location request residing in , // setting to one if no errors are encountered. // The LocateRequestReply is placed into . In case of @@ -155,11 +156,6 @@ protected: virtual void send_response (TAO_OutputCDR &response); // Send to the client on the other end. - void send_error (CORBA::ULong request_id, - CORBA::Exception *ex); - // Send to the client on the other end, which - // means basically sending the exception. - // = Event Handler overloads virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); @@ -170,15 +166,25 @@ protected: ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK); // Perform appropriate closing. +protected: + TAO_IIOP_Server_Transport *iiop_transport_; + // @@ New transport object reference. + TAO_ORB_Core *orb_core_; // Cached ORB Core. TAO_ORB_Core_TSS_Resources *tss_resources_; // Cached tss resources of the ORB that activated this object. + + TAO_GIOP_MessageHeader message_header_; + CORBA::ULong current_offset_; + ACE_Message_Block payload_; + // This keep the state of the current message, to enable + // non-blocking reads. }; #if defined (__ACE_INLINE__) -# include "tao/IIOP_Connect.i" +#include "tao/IIOP_Connect.i" #endif /* __ACE_INLINE__ */ #endif /* TAO_IIOP_CONNECT_H */ diff --git a/TAO/tao/IIOP_Profile.cpp b/TAO/tao/IIOP_Profile.cpp index e7680056d00..aa709b7e86e 100644 --- a/TAO/tao/IIOP_Profile.cpp +++ b/TAO/tao/IIOP_Profile.cpp @@ -32,7 +32,7 @@ TAO_IIOP_Profile::TAO_IIOP_Profile (const ACE_INET_Addr& addr, object_addr_ (addr), hint_ (0) { - this->set(addr); + this->set (addr); int l = ACE_OS::strlen (object_key); this->object_key_.length (l); @@ -53,7 +53,7 @@ TAO_IIOP_Profile::TAO_IIOP_Profile (const ACE_INET_Addr& addr, object_addr_ (addr), hint_ (0) { - this->set(addr); + this->set (addr); this->create_body (); } @@ -69,7 +69,7 @@ TAO_IIOP_Profile::TAO_IIOP_Profile (const ACE_INET_Addr& addr, object_addr_ (addr), hint_ (0) { - this->set(addr); + this->set (addr); int l = ACE_OS::strlen (object_key); this->object_key_.length (l); @@ -91,7 +91,7 @@ TAO_IIOP_Profile::TAO_IIOP_Profile (const ACE_INET_Addr& addr, object_addr_ (addr), hint_ (0) { - this->set(addr); + this->set (addr); this->create_body (); } diff --git a/TAO/tao/IIOP_Transport.cpp b/TAO/tao/IIOP_Transport.cpp index ec1365692e4..cb481fba26c 100644 --- a/TAO/tao/IIOP_Transport.cpp +++ b/TAO/tao/IIOP_Transport.cpp @@ -1,6 +1,8 @@ // This may look like C, but it's really -*- C++ -*- // $Id$ + + #include "tao/IIOP_Transport.h" #include "tao/IIOP_Connect.h" #include "tao/Timeprobe.h" @@ -44,12 +46,11 @@ ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Transport_Timeprobe_Description, #endif /* ACE_ENABLE_TIMEPROBES */ - TAO_IIOP_Transport::TAO_IIOP_Transport (TAO_IIOP_Handler_Base *handler, TAO_ORB_Core *orb_core) : TAO_Transport (TAO_IOP_TAG_INTERNET_IOP, orb_core), - handler_(handler) + handler_ (handler) { } @@ -65,13 +66,14 @@ TAO_IIOP_Server_Transport:: { } -TAO_IIOP_Client_Transport::TAO_IIOP_Client_Transport (TAO_IIOP_Client_Connection_Handler *handler, - TAO_ORB_Core *orb_core) +TAO_IIOP_Client_Transport:: + TAO_IIOP_Client_Transport (TAO_IIOP_Client_Connection_Handler *handler, + TAO_ORB_Core *orb_core) : TAO_IIOP_Transport (handler, orb_core), client_handler_ (handler) { - client_handler_ = handler; + message_header_.message_size = 0; } TAO_IIOP_Server_Transport::~TAO_IIOP_Server_Transport (void) @@ -106,18 +108,6 @@ 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::close_connection (void) { @@ -137,9 +127,13 @@ TAO_IIOP_Client_Transport::send_request (TAO_ORB_Core *orb_core, { ACE_FUNCTION_TIMEPROBE (TAO_IIOP_CLIENT_TRANSPORT_SEND_REQUEST_START); - return this->ws_->send_request (orb_core, - stream, - two_way); + if (this->ws_->sending_request (orb_core, + two_way) == -1) + return -1; + + return TAO_GIOP::send_message (this, + stream, + orb_core); } // Return 0, when the reply is not read fully, 1 if it is read fully. @@ -148,9 +142,6 @@ TAO_IIOP_Client_Transport::send_request (TAO_ORB_Core *orb_core, int TAO_IIOP_Client_Transport::handle_client_input (int block) { - // @@ Alex: it should be possible to make this code generic and move - // it to the GIOP class or something similar.... - // When we multiplex several invocations over a connection we need // to allocate the CDR stream *here*, but when there is a single // request over a connection the CDR stream can be pre-allocated on @@ -177,152 +168,68 @@ TAO_IIOP_Client_Transport::handle_client_input (int block) // removed. // Do I make any sense? - // Receive the message. Get also the GIOP version number. - // is non-blocking!!!! - // - // + In , Don't worry about blocking on the GIOP - // header, it's only 12 bytes, use read_n() for the header but - // non-blocking for the rest. - // - // + After reading the header you can allocate memory for the - // complete buffer [this is there already, look at how they - // do it!] - // + TAO_InputCDR* cdr = this->rms_->get_cdr_stream (); + ACE_Message_Block* payload = + ACE_const_cast(ACE_Message_Block*, cdr->start ()); - // if (!this->message_size_) - // { - // Reading the header. - - // @@ Where do I keep this CDR? (alex) - // } - - // Get the CDR stream for reading the input. - TAO_InputCDR* cdr = this->input_cdr_stream (); - - // @@ Exclsive RMS instead of giving the CDR given by the Invocation - // class, it should give the preallocated CDR so that it can give - // that CDR to the invocation back, if there is a valid reply or - // it can just forget it, for example, if there was a close - // connection message or something. (Alex) - - // If RMS not expecting any message, handle the unexpected data. - if (cdr == 0) - return this->check_unexpected_data (); - - TAO_GIOP_Version version; - - TAO_GIOP::Message_Type message_type = - TAO_GIOP::recv_message (this, - *cdr, - this->orb_core_, - version, - block); - switch (message_type) + int result = TAO_GIOP::handle_input (this, + this->orb_core_, + this->message_header_, + this->current_offset_, + payload); + if (result == -1) { - case TAO_GIOP::ShortRead: - // Return a value so that this we will get called again to - // handle the input. - return 0; - // NOT REACHED. - - case TAO_GIOP::EndOfFile: - case TAO_GIOP::CommunicationError: - case TAO_GIOP::MessageError: - // Handle errors like these. - // @@ this->reply_handler_->error (); - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) %N:%l handle_client_input: " - "error on stream.\n"), - -1); - - case TAO_GIOP::Fragment: - // Handle this. - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) %N:%l handle_client_input: " - "fragment.\n"), - -1); - - case TAO_GIOP::Request: - // In GIOP 1.0 and GIOP 1.1 this is an error, but it is - // *possible* to receive requests in GIOP 1.2. Don't handle this - // on the firt iteration, leave it for the nearby future... - // ERROR too. - // @@ this->reply_handler_->error (); - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) %N:%l handle_client_input: " - "request.\n"), - -1); - - case TAO_GIOP::CancelRequest: - case TAO_GIOP::LocateRequest: - case TAO_GIOP::CloseConnection: - default: - // @@ Errors for the time being. - // @@ this->reply_handler_->error (); - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) %N:%l handle_client_input: " - "wrong message.\n"), - -1); - - case TAO_GIOP::LocateReply: - case TAO_GIOP::Reply: - // Handle after the switch. - break; + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "IIOP_Transport::handle_client_input, handle_input")); + return -1; } + if (result == 0) + return result; - // For GIOP 1.0 and 1.1 the reply_ctx comes first: - // @@ Put this reply ctx into the reply dispatcher. so that - // invocation can read it. - // We should pass that reply_ctx to the invocation, interceptors - // will want to read it! + // OK, the complete message is here... - TAO_GIOP_ServiceContextList reply_ctx; - *cdr >> reply_ctx; - - // Read the request id and the reply status type. - // status can be NO_EXCEPTION, SYSTEM_EXCEPTION, USER_EXCEPTION, - // LOCATION_FORWARD or (on GIOP 1.2) LOCATION_FORWARD_PERM + TAO_GIOP_MessageHeader header_copy = this->message_header_; + this->message_header_.message_size = 0; + TAO_GIOP_ServiceContextList reply_ctx; CORBA::ULong request_id; CORBA::ULong reply_status; - if (!cdr->read_ulong (request_id)) - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) : IIOP_Client_Transport::" - "handle_client_input - error while " - "reading request_id\n"), - -1); - - if (!cdr->read_ulong (reply_status)) - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) : IIOP_Client_Transport::" - "handle_client_input - error while " - "reading reply status\n"), - -1); - - // @@ Alex: for some reason this was causing a crash with the - // leader-follower wait strategy. Somehow it seems like the rms - // still has a pointer to an object that was already destroyed - // (i.e. the stack was unrolled on the thread waiting for this - // event), since this is only needed for *true* asynchronous - // messaging. - //ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - dispatching reply <%x>\n", this)); + result = TAO_GIOP::parse_reply (this, + this->orb_core_, + *cdr, + header_copy, + reply_ctx, + request_id, + reply_status); + if (result == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "IIOP_Transport::handle_client_input, parse reply")); + return -1; + } + if (this->rms_->dispatch_reply (request_id, reply_status, - version, + header_copy.giop_version, reply_ctx, cdr) != 0) { - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) : IIOP_Client_Transport::" - "handle_client_input - " - "dispatch reply failed\n"), - -1); + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) : IIOP_Client_Transport::" + "handle_client_input - " + "dispatch reply failed\n")); + return -1; } // This is a NOOP for the Exclusive request case, but it actually // destroys the stream in the muxed case. - this->destroy_cdr_stream (cdr); + this->rms_->destroy_cdr_stream (cdr); // Return something to indicate the reply is received. return 1; diff --git a/TAO/tao/IIOP_Transport.h b/TAO/tao/IIOP_Transport.h index 06dd333ec08..0ea91fd1736 100644 --- a/TAO/tao/IIOP_Transport.h +++ b/TAO/tao/IIOP_Transport.h @@ -59,12 +59,6 @@ public: TAO_IIOP_Handler_Base *&handler (void); // Return a reference to the corresponding connection handler. - int is_nil (TAO_Transport *obj); - // Returns 0 if the obj is 0, else 1. - - TAO_Transport *_nil (void); - // Return a NULL pointer of type TAO_Transport *. - ACE_HANDLE handle (void); // Return the underlying connection handle. @@ -160,6 +154,11 @@ protected: private: TAO_IIOP_Client_Connection_Handler *client_handler_; // pointer to the corresponding client side connection handler. + + TAO_GIOP_MessageHeader message_header_; + CORBA::ULong current_offset_; + // This keep the state of the current message, to enable + // non-blocking reads. }; // **************************************************************** diff --git a/TAO/tao/Invocation.cpp b/TAO/tao/Invocation.cpp index e9a7f704e78..441de3df280 100644 --- a/TAO/tao/Invocation.cpp +++ b/TAO/tao/Invocation.cpp @@ -214,18 +214,6 @@ TAO_GIOP_Invocation::start (CORBA::Boolean is_roundtrip, CORBA::COMPLETED_NO)); } - // Init the input message states in the transport object. - // This is necessary for the round trip call only. But it is ok to - // do this in all cases. - // @@ Alex: I think we should keep the "reading" state (message_size - // and offset) separate from the writing state, i.e. those - // variables should only be set by the handle_input() method and - // its friends... - // @@ Carlos: I didnt quite understand this. What are the writing - // states do we have now? (Alex). - this->transport_->message_size (0); - this->transport_->message_received (0); - // Obtain unique request id from the RMS. this->request_id_ = this->transport_->request_id (); @@ -717,15 +705,9 @@ int TAO_GIOP_Twoway_Invocation::invoke_i (CORBA::Environment &ACE_TRY_ENV) ACE_THROW_SPEC ((CORBA::SystemException)) { - // Give the CDR stream for reading the input. - this->transport_->input_cdr_stream (&this->inp_stream_); - // Register a reply dispatcher for this invocation. Use the // preallocated reply dispatcher. - // Init reply dispatcher. - this->rd_.request_id (this->request_id_); - // Bind. int retval = this->transport_->bind_reply_dispatcher (this->request_id_, &this->rd_); @@ -850,7 +832,8 @@ TAO_GIOP_Twoway_Invocation::invoke_i (CORBA::Environment &ACE_TRY_ENV) return this->location_forward (this->inp_stream_, ACE_TRY_ENV); // NOT REACHED. } - return 0; + + return TAO_INVOKE_OK; } // **************************************************************** @@ -868,6 +851,21 @@ TAO_GIOP_Locate_Request_Invocation::invoke (CORBA::Environment &ACE_TRY_ENV) ACE_THROW_RETURN (CORBA::INTERNAL (), TAO_INVOKE_EXCEPTION); + // Register a reply dispatcher for this invocation. Use the + // preallocated reply dispatcher. + + // Bind. + int retval = this->transport_->bind_reply_dispatcher (this->request_id_, + &this->rd_); + if (retval == -1) + { + // @@ What is the right way to handle this error? + this->close_connection (); + ACE_THROW_RETURN (CORBA::INTERNAL (TAO_DEFAULT_MINOR_CODE, + CORBA::COMPLETED_NO), + TAO_INVOKE_EXCEPTION); + } + int result = this->transport_->send_request (this->orb_core_, this->out_stream_, @@ -897,86 +895,20 @@ TAO_GIOP_Locate_Request_Invocation::invoke (CORBA::Environment &ACE_TRY_ENV) // received? But what about oneways? this->stub_->set_valid_profile (); - TAO_GIOP_Version version; - - TAO_GIOP::Message_Type m = TAO_GIOP::recv_message (this->transport_, - this->inp_stream_, - this->orb_core_, - version, - 1); + // Wait for the reply. We should wait till we receive the reply + // fully. + // @@ Check for return value -1 here !!! (Alex). + int reply_error = this->transport_->wait_for_reply (); - switch (m) + if (reply_error == -1) { - case TAO_GIOP::Reply: - // Thereply is handled at the end of this switch() statement. - break; - - case TAO_GIOP::CloseConnection: - // Try the same profile again, but open a new connection. - // If that fails then we go to the next profile. - this->profile_->reset_hint (); - return TAO_INVOKE_RESTART; - - case TAO_GIOP::Request: - case TAO_GIOP::CancelRequest: - case TAO_GIOP::LocateRequest: - case TAO_GIOP::LocateReply: - default: - // These are all illegal messages to find. If found, they could - // be indicative of client bugs (lost track of input stream) or - // server bugs; maybe the request was acted on, maybe not, we - // can't tell. - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, - "TAO: (%P|%t) illegal GIOP message (%s) " - "in response to my LocateRequest!\n", - TAO_GIOP::message_name (m))); - // FALLTHROUGH ... - - case TAO_GIOP::MessageError: - // @@ Maybe the transport should be closed by recv_request? - // FALLTHROUGH - - case TAO_GIOP::CommunicationError: - // Couldn't read it for some reason ... exception's set already, - // so just tell the other end about the trouble (closing the - // connection) and return. - // FALLTHROUGH - - case TAO_GIOP::EndOfFile: - // In all those cases the message was (apparently) sent, but we - // couldn't read the reply. To satisfy the "at most once" - // semantics of CORBA we must raise an exception at this point - // and *not* try to transparently restart the request. - // FALLTHROUGH - this->close_connection (); - - ACE_THROW_RETURN (CORBA::COMM_FAILURE (TAO_DEFAULT_MINOR_CODE, - CORBA::COMPLETED_MAYBE), - TAO_INVOKE_EXCEPTION); - } - - // Note: we only get here if the status was TAO_GIOP::LocateReply - - CORBA::ULong request_id; - CORBA::ULong locate_status; // TAO_GIOP_LocateStatusType - - if (!this->inp_stream_.read_ulong (request_id) - || request_id != this->request_id_ - || !this->inp_stream_.read_ulong (locate_status)) - { - // @@ Fred: Do we really want to close the connection here? This - // is a problem, but we haven't lost synchronization with the - // server or anything. - this->transport_->close_connection (); - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, "TAO: (%P|%t) bad Response header\n")); ACE_THROW_RETURN (CORBA::COMM_FAILURE (TAO_DEFAULT_MINOR_CODE, CORBA::COMPLETED_MAYBE), TAO_INVOKE_EXCEPTION); } + CORBA::ULong locate_status = this->rd_.reply_status (); switch (locate_status) { case TAO_GIOP_OBJECT_HERE: diff --git a/TAO/tao/Invocation.h b/TAO/tao/Invocation.h index ca106f437c7..fcb5ec34e35 100644 --- a/TAO/tao/Invocation.h +++ b/TAO/tao/Invocation.h @@ -280,6 +280,9 @@ public: private: TAO_InputCDR inp_stream_; // Stream into which the request is placed. + + TAO_Synch_Reply_Dispatcher rd_; + // Reply dispatcher for the current synchronous invocation. }; #if defined (__ACE_INLINE__) diff --git a/TAO/tao/Invocation.i b/TAO/tao/Invocation.i index 5df0a6140f7..5379efc050e 100644 --- a/TAO/tao/Invocation.i +++ b/TAO/tao/Invocation.i @@ -27,7 +27,8 @@ TAO_GIOP_Twoway_Invocation (TAO_Stub *stub, : TAO_GIOP_Invocation (stub, operation, orb_core), inp_stream_ (orb_core->create_input_cdr_data_block (ACE_CDR::DEFAULT_BUFSIZE), TAO_ENCAP_BYTE_ORDER, - orb_core) + orb_core), + rd_ (&inp_stream_) { } @@ -86,7 +87,8 @@ TAO_GIOP_Locate_Request_Invocation (TAO_Stub *stub, : TAO_GIOP_Invocation (stub, 0, orb_core), inp_stream_ (orb_core->create_input_cdr_data_block(ACE_CDR::DEFAULT_BUFSIZE), TAO_ENCAP_BYTE_ORDER, - orb_core) + orb_core), + rd_ (&inp_stream_) { } diff --git a/TAO/tao/Pluggable.cpp b/TAO/tao/Pluggable.cpp index 474a38cab35..7a09ff634c6 100644 --- a/TAO/tao/Pluggable.cpp +++ b/TAO/tao/Pluggable.cpp @@ -204,9 +204,6 @@ TAO_Transport::TAO_Transport (CORBA::ULong tag, TAO_ORB_Core *orb_core) : tag_ (tag), orb_core_ (orb_core), - message_size_ (0), - message_offset_ (0), - message_received_ (0), rms_ (0), ws_ (0) { @@ -237,13 +234,6 @@ TAO_Transport::tag (void) const // reply_dispatcher, // input_cdr); -// Set the CDR stream for reading the input message. -void -TAO_Transport::input_cdr_stream (TAO_InputCDR *cdr) -{ - this->rms_->set_cdr_stream (cdr); -} - // @@ Do you need an accessor? Or is the CDR stream simply passed by // the RMS to the right target. We should go to the RMS and obtain // the CDR stream from it, that way we can implement an optimized @@ -263,61 +253,6 @@ TAO_Transport::destroy_cdr_stream (TAO_InputCDR *cdr) const this->rms_->destroy_cdr_stream (cdr); } -// Set the total size of the incoming message. (This does not -// include the header size). -void -TAO_Transport::message_size (CORBA::ULong message_size) -{ - this->message_size_ = message_size; - - // Reset the offset. - this->message_offset_ = 0; -} - -// Get the total size of the incoming message. -CORBA::ULong -TAO_Transport::message_size (void) const -{ - return this->message_size_; -} - -// Get the current offset of the incoming message. -CORBA::ULong -TAO_Transport::message_offset (void) const -{ - return this->message_offset_; -} - -// Update the offset of the incoming message. -int -TAO_Transport::incr_message_offset (CORBA::Long bytes_transferred) -{ - if ((this->message_offset_ + bytes_transferred) > this->message_size_) - ACE_ERROR_RETURN ((LM_ERROR, - "TAO: %N:%l: (%P | %t): TAO_Transport::incr_message_offset: " - "Failed to update the offset of incoming message\n"), - -1); - - this->message_offset_ += bytes_transferred; - - return 0; -} - -// Set the flag to indicate whether the input message was read fully -// or no. -void -TAO_Transport::message_received (int received) -{ - this->message_received_ = received; -} - -// Get the flag. -int -TAO_Transport::message_received (void) const -{ - return this->message_received_; -} - // Get it. TAO_ORB_Core * TAO_Transport::orb_core (void) const diff --git a/TAO/tao/Pluggable.h b/TAO/tao/Pluggable.h index cccd96deae0..1cf98c998c5 100644 --- a/TAO/tao/Pluggable.h +++ b/TAO/tao/Pluggable.h @@ -123,39 +123,12 @@ public: int twoway) = 0; // Default action to be taken for send request. - void input_cdr_stream (TAO_InputCDR *cdr); - // Set the CDR stream for reading the input message. - TAO_InputCDR *input_cdr_stream (void) const; // Get the CDR stream for reading the input message. void destroy_cdr_stream (TAO_InputCDR *) const; // Release a CDR stream, simply pass it to the RMS... - // = State of the incoming message. - - void message_size (CORBA::ULong message_size); - // Set the total size of the incoming message. (This does not - // include the header size). This inits the setting - // it to zero. - - CORBA::ULong message_size (void) const; - // Get the total size of the incoming message. - - CORBA::ULong message_offset (void) const; - // Get the current offset of the incoming message. - - int incr_message_offset (CORBA::Long bytes_transferred); - // Update the offset of the incoming message. Returns 0 on success - // -1 on failure. - - void message_received (int received); - // Set the flag to indicate whether the input message was read fully - // or no. - - int message_received (void) const; - // Get the flag. - // = Get and set methods for the ORB Core. // void orb_core (TAO_ORB_Core *orb_core); @@ -208,18 +181,6 @@ protected: TAO_ORB_Core *orb_core_; // Global orbcore resource. - // = States for the input message. - CORBA::ULong message_size_; - // Total length of the whole message. This does not include the - // header length. - - CORBA::ULong message_offset_; - // Current offset of the input message. - - int message_received_; - // Flag to indicate whether the input message has been received - // fully or not. - TAO_Request_Mux_Strategy *rms_; // Strategy to decide whether multiple requests can be sent over the // same connection or the connection is exclusive for a request. diff --git a/TAO/tao/Reply_Dispatcher.cpp b/TAO/tao/Reply_Dispatcher.cpp index a6249ef9c36..d28e4a8869b 100644 --- a/TAO/tao/Reply_Dispatcher.cpp +++ b/TAO/tao/Reply_Dispatcher.cpp @@ -2,10 +2,12 @@ #include "tao/Reply_Dispatcher.h" +#if defined(__ACE_INLINE__) +#include "tao/Reply_Dispatcher.i" +#endif /* __ACE_INLINE__ */ + // Constructor. TAO_Reply_Dispatcher::TAO_Reply_Dispatcher (void) - : request_id_ (0), - cdr_ (0) { } @@ -14,50 +16,18 @@ TAO_Reply_Dispatcher::~TAO_Reply_Dispatcher (void) { } -void -TAO_Reply_Dispatcher::request_id (CORBA::ULong request_id) -{ - this->request_id_ = request_id; -} - -CORBA::ULong -TAO_Reply_Dispatcher::request_id (void) const -{ - return this->request_id_; -} - -void -TAO_Reply_Dispatcher::reply_status (CORBA::ULong reply_status) -{ - this->reply_status_ = reply_status; -} - -// Get the reply status. -CORBA::ULong -TAO_Reply_Dispatcher::reply_status (void) const -{ - return this->reply_status_; -} - -// Set the CDR which the has the reply message. -void -TAO_Reply_Dispatcher::cdr (TAO_InputCDR *cdr) -{ - this->cdr_ = cdr; -} - -// Get the CDR stream. TAO_InputCDR * TAO_Reply_Dispatcher::cdr (void) const { - return this->cdr_; + return 0; } // ********************************************************************* // Constructor. -TAO_Synch_Reply_Dispatcher::TAO_Synch_Reply_Dispatcher (void) +TAO_Synch_Reply_Dispatcher::TAO_Synch_Reply_Dispatcher (TAO_InputCDR* cdr) { + this->cdr_ = cdr; } // Destructor. @@ -67,8 +37,26 @@ TAO_Synch_Reply_Dispatcher::~TAO_Synch_Reply_Dispatcher (void) // Dispatch the reply. int -TAO_Synch_Reply_Dispatcher::dispatch_reply (void) +TAO_Synch_Reply_Dispatcher::dispatch_reply (CORBA::ULong reply_status, + const TAO_GIOP_Version& version, + TAO_GIOP_ServiceContextList& reply_ctx, + TAO_InputCDR*) { - // @@ Handover the input CDR to the Invocation class. + this->reply_status_ = reply_status; + this->version_ = version; + + // Steal the buffer, that way we don't do any unnecesary copies of + // this data. + CORBA::ULong max = reply_ctx.maximum (); + CORBA::ULong len = reply_ctx.length (); + TAO_GIOP_ServiceContext* context_list = reply_ctx.get_buffer (1); + this->reply_ctx_.replace (max, len, context_list, 1); + return 0; } + +TAO_InputCDR * +TAO_Synch_Reply_Dispatcher::cdr (void) const +{ + return this->cdr_; +} diff --git a/TAO/tao/Reply_Dispatcher.h b/TAO/tao/Reply_Dispatcher.h index cb616e7a8ad..9fdba00034b 100644 --- a/TAO/tao/Reply_Dispatcher.h +++ b/TAO/tao/Reply_Dispatcher.h @@ -19,7 +19,7 @@ #ifndef TAO_REPLY_DISPATCHER_H #define TAO_REPLY_DISPATCHER_H -#include "tao/corbafwd.h" +#include "tao/GIOP.h" // Forward Declarations. @@ -40,38 +40,14 @@ public: virtual ~TAO_Reply_Dispatcher (void); // Destructor. - void request_id (CORBA::ULong request_id); - // Set the request id. - - CORBA::ULong request_id (void) const; - // Return the request id. - - void reply_status (CORBA::ULong reply_status); - // Set the reply status. Reply status is stored as read from the - // incoming message. Readers of this data should see it whether this - // number fits into the TAO_GIOP_ReplyStatusType type. - - CORBA::ULong reply_status (void) const; - // Get the reply status. - - void cdr (TAO_InputCDR *cdr); - // Set the CDR which the has the reply message. - - TAO_InputCDR *cdr (void) const; - // Get the CDR stream. - - virtual int dispatch_reply (void) = 0; + virtual int dispatch_reply (CORBA::ULong reply_status, + const TAO_GIOP_Version& version, + TAO_GIOP_ServiceContextList& reply_ctx, + TAO_InputCDR* cdr) = 0; // Dispatch the reply. -protected: - CORBA::ULong request_id_; - // Request ID for this request. - - TAO_InputCDR *cdr_; - // CDR stream for reading the input. - - CORBA::ULong reply_status_; - // Replt status. + virtual TAO_InputCDR *cdr (void) const; + // Get the CDR stream (if any) }; class TAO_Export TAO_Synch_Reply_Dispatcher : public TAO_Reply_Dispatcher @@ -84,14 +60,43 @@ class TAO_Export TAO_Synch_Reply_Dispatcher : public TAO_Reply_Dispatcher // public: - TAO_Synch_Reply_Dispatcher (void); + TAO_Synch_Reply_Dispatcher (TAO_InputCDR* cdr); // Constructor. virtual ~TAO_Synch_Reply_Dispatcher (void); // Destructor. - virtual int dispatch_reply (void); - // NO OP. + CORBA::ULong reply_status (void) const; + // Get the reply status. + + const TAO_GIOP_Version& version (void) const; + // Get the GIOP version + + TAO_GIOP_ServiceContextList& reply_ctx (void); + // Get the reply context + + virtual int dispatch_reply (CORBA::ULong reply_status, + const TAO_GIOP_Version& version, + TAO_GIOP_ServiceContextList& reply_ctx, + TAO_InputCDR* cdr); + virtual TAO_InputCDR *cdr (void) const; + +private: + CORBA::ULong reply_status_; + // Reply or LocateReply status. + + TAO_GIOP_Version version_; + // The version + + TAO_GIOP_ServiceContextList reply_ctx_; + // The service context list + + TAO_InputCDR *cdr_; + // CDR stream for reading the input. }; +#if !defined(__ACE_INLINE__) +#include "tao/Reply_Dispatcher.i" +#endif /* __ACE_INLINE__ */ + #endif /* TAO_REPLY_DISPATCHER_H */ diff --git a/TAO/tao/Reply_Dispatcher.i b/TAO/tao/Reply_Dispatcher.i new file mode 100644 index 00000000000..826563e3eb5 --- /dev/null +++ b/TAO/tao/Reply_Dispatcher.i @@ -0,0 +1,19 @@ +// $Id$ + +ACE_INLINE CORBA::ULong +TAO_Synch_Reply_Dispatcher::reply_status (void) const +{ + return this->reply_status_; +} + +ACE_INLINE const TAO_GIOP_Version& +TAO_Synch_Reply_Dispatcher::version (void) const +{ + return this->version_; +} + +ACE_INLINE TAO_GIOP_ServiceContextList& +TAO_Synch_Reply_Dispatcher::reply_ctx (void) +{ + return this->reply_ctx_; +} diff --git a/TAO/tao/Request_Mux_Strategy.cpp b/TAO/tao/Request_Mux_Strategy.cpp index 30803803623..b0e7dd99489 100644 --- a/TAO/tao/Request_Mux_Strategy.cpp +++ b/TAO/tao/Request_Mux_Strategy.cpp @@ -2,6 +2,7 @@ #include "tao/Request_Mux_Strategy.h" #include "tao/Reply_Dispatcher.h" +#include "tao/debug.h" // @@ Alex: there is another aspect that is controlled by this // strategy: the demuxed version must idle() the transport @@ -12,7 +13,6 @@ // We may need to add a couple of methods to implement that. TAO_Request_Mux_Strategy::TAO_Request_Mux_Strategy (void) - : cdr_ (0) { } @@ -20,12 +20,6 @@ TAO_Request_Mux_Strategy::~TAO_Request_Mux_Strategy (void) { } -TAO_InputCDR * -TAO_Request_Mux_Strategy::get_cdr_stream (void) -{ - return cdr_; -} - // ********************************************************************* TAO_Muxed_RMS::TAO_Muxed_RMS (void) @@ -66,13 +60,12 @@ TAO_Muxed_RMS::dispatch_reply (CORBA::ULong request_id, return -1; } -void -TAO_Muxed_RMS::set_cdr_stream (TAO_InputCDR *Cdr) +TAO_InputCDR * +TAO_Muxed_RMS::get_cdr_stream (void) { - // @@ + return 0; } - void TAO_Muxed_RMS::destroy_cdr_stream (TAO_InputCDR *) { @@ -124,30 +117,36 @@ TAO_Exclusive_RMS::dispatch_reply (CORBA::ULong request_id, { ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); if (this->request_id_ != request_id) - return -1; + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO_Exclusive_RMS::dispatch_reply - <%d != %d>\n", + this->request_id_, request_id)); + return -1; + } TAO_Reply_Dispatcher *rd = this->rd_; this->request_id_ = 0xdeadbeef; // @@ What is a good value??? this->rd_ = 0; - // @@ Use a single operation for all of this... - rd->reply_status (reply_status); - rd->cdr (cdr); - return rd->dispatch_reply (); + return rd->dispatch_reply (reply_status, + version, + reply_ctx, + cdr); } -// Set the CDR stream. -void -TAO_Exclusive_RMS::set_cdr_stream (TAO_InputCDR *cdr) +TAO_InputCDR * +TAO_Exclusive_RMS::get_cdr_stream (void) { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->lock_); - this->cdr_ = cdr; + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0); + if (this->rd_ == 0) + return 0; + + return this->rd_->cdr (); } // NOOP function. void TAO_Exclusive_RMS::destroy_cdr_stream (TAO_InputCDR *) { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->lock_); - this->cdr_ = 0; } diff --git a/TAO/tao/Request_Mux_Strategy.h b/TAO/tao/Request_Mux_Strategy.h index 13f1f1a2e47..6c35c496235 100644 --- a/TAO/tao/Request_Mux_Strategy.h +++ b/TAO/tao/Request_Mux_Strategy.h @@ -71,20 +71,11 @@ public: // the factory simply allocates a new one, in the Exclusive case // the factory returns a pointer to the pre-allocated CDR. - virtual void set_cdr_stream (TAO_InputCDR *cdr) = 0; - // Set the CDR stream. - - virtual TAO_InputCDR *get_cdr_stream (void); - // Get the CDR stream. + virtual TAO_InputCDR *get_cdr_stream (void) = 0; + // Get a CDR stream. virtual void destroy_cdr_stream (TAO_InputCDR *) = 0; - // Destroy the CDR stream. - -protected: - TAO_InputCDR *cdr_; - // Pointer to the CDR stream used to read the incoming message. This - // is obtained from the Invocation object. This is preallocated in - // the SMI and dynamically allocated in AMI. + // Destroy a CDR stream. }; class TAO_Export TAO_Muxed_RMS : public TAO_Request_Mux_Strategy @@ -112,7 +103,7 @@ public: const TAO_GIOP_Version& version, TAO_GIOP_ServiceContextList& reply_ctx, TAO_InputCDR* cdr); - virtual void set_cdr_stream (TAO_InputCDR *cdr); + virtual TAO_InputCDR *get_cdr_stream (void); virtual void destroy_cdr_stream (TAO_InputCDR *); protected: @@ -144,7 +135,7 @@ public: const TAO_GIOP_Version& version, TAO_GIOP_ServiceContextList& reply_ctx, TAO_InputCDR* cdr); - virtual void set_cdr_stream (TAO_InputCDR *cdr); + virtual TAO_InputCDR *get_cdr_stream (void); virtual void destroy_cdr_stream (TAO_InputCDR *); protected: diff --git a/TAO/tao/UIOP_Connect.cpp b/TAO/tao/UIOP_Connect.cpp index 1663203a9df..4fa95ff9f2a 100644 --- a/TAO/tao/UIOP_Connect.cpp +++ b/TAO/tao/UIOP_Connect.cpp @@ -6,11 +6,8 @@ #include "tao/Timeprobe.h" #include "tao/UIOP_Transport.h" #include "tao/debug.h" -#include "tao/GIOP.h" -#include "tao/GIOP_Server_Request.h" #include "tao/ORB_Core.h" #include "tao/ORB.h" -#include "tao/POA.h" #include "tao/CDR.h" #include "tao/Wait_Strategy.h" @@ -35,12 +32,16 @@ TAO_UIOP_Handler_Base::TAO_UIOP_Handler_Base (ACE_Thread_Manager *t) // @@ For pluggable protocols, added a reference to // the corresponding transport obj. TAO_UIOP_Server_Connection_Handler::TAO_UIOP_Server_Connection_Handler (ACE_Thread_Manager *t) - : TAO_UIOP_Handler_Base (t ? t : TAO_ORB_Core_instance()->thr_mgr ()), - orb_core_ (TAO_ORB_Core_instance ()), - tss_resources_ (TAO_ORB_CORE_TSS_RESOURCES::instance ()) + : TAO_UIOP_Handler_Base (t), + orb_core_ (0), + tss_resources_ (0) { - uiop_transport_ = new TAO_UIOP_Server_Transport (this, - this->orb_core_); + // This constructor should *never* get called, it is just here to + // make the compiler happy: the default implementation of the + // Creation_Strategy requires a constructor with that signature, we + // don't use that implementation, but some (most?) compilers + // instantiate it anyway. + ACE_ASSERT (this->orb_core_ != 0); } // @@ For pluggable protocols, added a reference to the @@ -50,6 +51,7 @@ TAO_UIOP_Server_Connection_Handler::TAO_UIOP_Server_Connection_Handler (TAO_ORB_ orb_core_ (orb_core), tss_resources_ (TAO_ORB_CORE_TSS_RESOURCES::instance ()) { + message_header_.message_size = 0; uiop_transport_ = new TAO_UIOP_Server_Transport (this, this->orb_core_); } @@ -202,81 +204,13 @@ TAO_UIOP_Server_Connection_Handler::handle_message (TAO_InputCDR &input, CORBA::ULong &request_id, CORBA::Environment &ACE_TRY_ENV) { - // This will extract the request header, set as - // appropriate. - GIOP_ServerRequest request (input, - output, - this->orb_core_, - ACE_TRY_ENV); - ACE_CHECK_RETURN (-1); - - // The request_id_ field in request will be 0 if something went - // wrong before it got a chance to read it out. - request_id = request.request_id (); - - response_required = request.response_expected (); - -#if !defined (TAO_NO_IOR_TABLE) - - const CORBA::Octet *object_key = request.object_key ().get_buffer (); - - if (ACE_OS::memcmp (object_key, - &TAO_POA::objectkey_prefix[0], - TAO_POA::TAO_OBJECTKEY_PREFIX_SIZE) != 0) - { - ACE_CString object_id (ACE_reinterpret_cast (const char *, object_key), - TAO_POA::TAO_OBJECTKEY_PREFIX_SIZE, - 0, - 0); - - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, - "Simple Object key %s. Doing the Table Lookup ...\n", - object_id.c_str ())); - - CORBA::Object_ptr object_reference; - - // Do the Table Lookup. - int status = - this->orb_core_->orb ()->_tao_find_in_IOR_table (object_id, - object_reference); - - // If ObjectID not in table or reference is nil raise OBJECT_NOT_EXIST. - - if (CORBA::is_nil (object_reference) || status == -1) - ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (), -1); - - // ObjectID present in the table with an associated NON-NULL reference. - // Throw a forward request exception. - - CORBA::Object_ptr dup = CORBA::Object::_duplicate (object_reference); - - ACE_THROW_RETURN (PortableServer::ForwardRequest (dup), -1); - } - -#endif /* TAO_NO_IOR_TABLE */ - - // So, we read a request, now handle it using something more - // primitive than a CORBA2 ServerRequest pseudo-object. - - // @@ (CJC) We need to create a TAO-specific request which will hold - // context for a request such as the connection handler ("this") over - // which the request was received so that the servicer of the request - // has sufficient context to send a response on its own. - // - // One thing which me must be careful of is that responses are sent - // with a single write so that they're not accidentally interleaved - // over the transport (as could happen using TCP). - - this->orb_core_->object_adapter ()->dispatch_servant (request.object_key (), - request, - 0, - ACE_TRY_ENV); - // NEED TO CHECK FOR any errors present in and set the return - // code appropriately. - ACE_CHECK_RETURN (-1); - - return 0; + return TAO_GIOP::process_server_request (this->transport (), + this->orb_core_, + input, + output, + response_required, + request_id, + ACE_TRY_ENV); } int @@ -284,444 +218,63 @@ TAO_UIOP_Server_Connection_Handler::handle_locate (TAO_InputCDR &input, TAO_OutputCDR &output, CORBA::Boolean &response_required, CORBA::ULong &request_id, - CORBA::Environment &env) + CORBA::Environment &ACE_TRY_ENV) { - // TAO_FUNCTION_PP_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_HANDLE_LOCATE_START); - - // This will extract the request header, set as - // appropriate. - TAO_GIOP_LocateRequestHeader locateRequestHeader; - - env.clear (); - if (locateRequestHeader.init (input, env) == 0) - { - request_id = locateRequestHeader.request_id; - response_required = 0; - return -1; - } - - // Copy the request ID to be able to respond in case of an - // exception. - request_id = locateRequestHeader.request_id; - response_required = 1; - - char repbuf[ACE_CDR::DEFAULT_BUFSIZE]; - TAO_OutputCDR dummy_output (repbuf, sizeof(repbuf)); - // This output CDR is not used! - - TAO_ObjectKey tmp_key (locateRequestHeader.object_key.length (), - locateRequestHeader.object_key.length (), - locateRequestHeader.object_key.get_buffer (), - 0); - - CORBA::Object_var forward_location_var; - TAO_GIOP_LocateStatusType status; - - GIOP_ServerRequest serverRequest (locateRequestHeader.request_id, - response_required, - tmp_key, - "_non_existent", - dummy_output, - this->orb_core_, - env); - - this->orb_core_->object_adapter ()->dispatch_servant (serverRequest.object_key (), - serverRequest, - 0, - env); - - if (serverRequest.exception_type () == TAO_GIOP_NO_EXCEPTION - && env.exception () == 0) - { - // we got no exception, so the object is here - status = TAO_GIOP_OBJECT_HERE; - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, - "TAO: (%P|%t) handle_locate() : found\n")); - } - else if (serverRequest.exception_type () != TAO_GIOP_NO_EXCEPTION) - { - forward_location_var = serverRequest.forward_location (); - if (!CORBA::is_nil (forward_location_var.in ())) - { - status = TAO_GIOP_OBJECT_FORWARD; - ACE_DEBUG ((LM_DEBUG, - "handle_locate has been called: forwarding\n")); - } - else - { - // Normal exception, so the object is not here - status = TAO_GIOP_UNKNOWN_OBJECT; - ACE_DEBUG ((LM_DEBUG, - "handle_locate has been called: not here\n")); - } - - // The locate_servant call might have thrown an exception but we - // don't want to marshal it because it is no failure. The - // proper Locacte_Reply will tell the client what is going on. - - // Remove the exception - env.clear (); - } - else - { - -#if !defined (TAO_HAS_MINIMUM_CORBA) - - // Try to narrow to ForwardRequest - PortableServer::ForwardRequest_ptr forward_request_ptr = - PortableServer::ForwardRequest::_narrow (env.exception ()); - - // If narrowing of exception succeeded - if (forward_request_ptr != 0) - { - status = TAO_GIOP_OBJECT_FORWARD; - forward_location_var = forward_request_ptr->forward_reference; - ACE_DEBUG ((LM_DEBUG, - "handle_locate has been called: forwarding\n")); - } - else - -#endif /* TAO_HAS_MINIMUM_CORBA */ - - { - // Normal exception, so the object is not here - status = TAO_GIOP_UNKNOWN_OBJECT; - ACE_DEBUG ((LM_DEBUG, - "handle_locate has been called: not here\n")); - } - - // the locate_servant call might have thrown an exception but we - // don't want to marshal it because it is no failure. The - // proper Locacte_Reply will tell the client what is going on. - - // Remove the exception - env.clear (); - } - - // Create the response. - TAO_GIOP::start_message (TAO_GIOP::LocateReply, output, - this->orb_core_); - output.write_ulong (locateRequestHeader.request_id); - output.write_ulong (status); - - if (status == TAO_GIOP_OBJECT_FORWARD) - { - CORBA::Object_ptr object_ptr = forward_location_var.in (); - if ((output << object_ptr) == 0) - { - if (TAO_debug_level > 0) - { - ACE_DEBUG ((LM_DEBUG, - "Server_Connection_Handler::handle_locate - " - "error marshaling forwarded reference\n")); - } - response_required = 0; - return -1; - } - } - - return 0; + return TAO_GIOP::process_server_locate (this->transport (), + this->orb_core_, + input, + output, + response_required, + request_id, + ACE_TRY_ENV); } void TAO_UIOP_Server_Connection_Handler::send_response (TAO_OutputCDR &output) { - // TAO_FUNCTION_PP_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_SEND_RESPONSE_START); - - TAO_GIOP::send_request (this->uiop_transport_, + TAO_GIOP::send_message (this->uiop_transport_, output, this->orb_core_); } -// This method is designed to return system exceptions to the caller. - -void -TAO_UIOP_Server_Connection_Handler::send_error (CORBA::ULong request_id, - CORBA::Exception *x) -{ - // TAO_FUNCTION_PP_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_SEND_RESPONSE_START); - - // Create a new output CDR stream - TAO_OutputCDR output; - - // Construct a REPLY header. - TAO_GIOP::start_message (TAO_GIOP::Reply, output, - this->orb_core_); - - // A new try/catch block, but if something goes wrong now we - // have no hope, just abort. - ACE_TRY_NEW_ENV - { - // create and write a dummy context - TAO_GIOP_ServiceContextList resp_ctx; - resp_ctx.length (0); - output << resp_ctx; - - // Write the request ID - output.write_ulong (request_id); - -#if !defined (TAO_HAS_MINIMUM_CORBA) - - // @@ TODO This is the place to conditionally compile - // forwarding. It certainly seems easy to strategize too, - // just invoke an strategy to finish marshalling the - // response. - - // Now we check for Forwarding *************************** - - // Try to narrow to ForwardRequest - PortableServer::ForwardRequest_ptr forward_request_ptr = - PortableServer::ForwardRequest::_narrow (x); - - // If narrowing of exception succeeded - if (forward_request_ptr != 0 - && !CORBA::is_nil (forward_request_ptr->forward_reference.in ())) - { - // write the reply_status - output.write_ulong (TAO_GIOP_LOCATION_FORWARD); - - // write the object reference into the stream - CORBA::Object_ptr object_ptr = - forward_request_ptr->forward_reference.in(); - - output << object_ptr; - } - // end of the forwarding code **************************** - else - -#endif /* TAO_HAS_MINIMUM_CORBA */ - - { - // Write the exception - CORBA::TypeCode_ptr except_tc = x->_type (); - - CORBA::exception_type extype = CORBA::USER_EXCEPTION; - if (CORBA::SystemException::_narrow (x) != 0) - extype = CORBA::SYSTEM_EXCEPTION; - - // write the reply_status - output.write_ulong (TAO_GIOP::convert_CORBA_to_GIOP_exception (extype)); - - // write the actual exception - output.encode (except_tc, x, 0, ACE_TRY_ENV); - ACE_TRY_CHECK; - } - } - ACE_CATCH (CORBA_Exception, ex) - { - // now we know, that while handling the error an other error - // happened -> no hope, close connection. - - // close the handle - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) closing conn %d after fault %p\n", - this->peer ().get_handle (), - "TAO_UIOP_Server_Connection_Handler::send_error")); - this->handle_close (); - return; - } - ACE_ENDTRY; - - // hand it to the next lower layer - TAO_GIOP::send_request (this->uiop_transport_, output, this->orb_core_); -} - int TAO_UIOP_Server_Connection_Handler::handle_input (ACE_HANDLE) { - // CJCXXX The tasks of this method should change to something like - // the following: - // 1. call into GIOP to pull off the header - // 2. construct a complete request - // 3. dispatch that request and return any required reply and errors - - // TAO_FUNCTION_PP_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_HANDLE_INPUT_START); - - // @@ TODO This should take its memory from a specialized - // allocator. It is better to use a message block than a on stack - // buffer because we cannot minimize memory copies in that case. - TAO_InputCDR input (this->orb_core_->create_input_cdr_data_block (ACE_CDR::DEFAULT_BUFSIZE), - TAO_ENCAP_BYTE_ORDER, - this->orb_core_); - - char repbuf[ACE_CDR::DEFAULT_BUFSIZE]; -#if defined(ACE_HAS_PURIFY) - (void) ACE_OS::memset (repbuf, '\0', sizeof (repbuf)); -#endif /* ACE_HAS_PURIFY */ - TAO_OutputCDR output (repbuf, sizeof(repbuf), - TAO_ENCAP_BYTE_ORDER, - this->orb_core_->output_cdr_buffer_allocator (), - this->orb_core_->output_cdr_buffer_allocator ()); - - int result = 0; - int error_encountered = 0; - CORBA::Boolean response_required = 0; - CORBA::ULong request_id = 0; - TAO_GIOP_Version version; + int result = TAO_GIOP::handle_input (this->transport (), + this->orb_core_, + this->message_header_, + this->current_offset_, + &this->payload_); - CORBA::Environment &ACE_TRY_ENV = CORBA::default_environment (); - ACE_TRY - { - // Try to recv a new request. - - // Init the input message states in Transport. - this->uiop_transport_->message_size (0); - - // Try to recv a new request. - TAO_GIOP::Message_Type type = - TAO_GIOP::recv_message (this->uiop_transport_, - input, - this->orb_core_, - version, - 1); - - // TAO_MINIMAL_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_RECEIVE_REQUEST_END); - - // Check to see if we've been cancelled cooperatively. - if (this->orb_core_->orb ()->should_shutdown () != 0) - error_encountered = 1; - else - { - switch (type) - { - case TAO_GIOP::Request: - // Message was successfully read, so handle it. If we - // encounter any errors, will be set - // appropriately by the called code, and -1 will be - // returned. - if (this->handle_message (input, - output, - response_required, - request_id, - ACE_TRY_ENV) == -1) - error_encountered = 1; - ACE_TRY_CHECK; - break; - - case TAO_GIOP::LocateRequest: - if (this->handle_locate (input, - output, - response_required, - request_id, - ACE_TRY_ENV) == -1) - error_encountered = 1; - ACE_TRY_CHECK; - break; - - case TAO_GIOP::EndOfFile: - // Got a EOF - result = -1; - break; - - // These messages should never be sent to the server; - // it's an error if the peer tries. Set the environment - // accordingly, as it's not yet been reported as an - // error. - case TAO_GIOP::Reply: - case TAO_GIOP::LocateReply: - case TAO_GIOP::CloseConnection: - default: // Unknown message - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Illegal message received by server\n")); - ACE_TRY_THROW (CORBA::COMM_FAILURE ()); - // NOTREACHED - - case TAO_GIOP::CommunicationError: - case TAO_GIOP::MessageError: - // Here, MessageError can either mean condition for - // GIOP::MessageError happened or a GIOP message was - // not successfully received. Sending back of - // GIOP::MessageError is handled in TAO_GIOP::parse_header. - error_encountered = 1; - break; - } - } - } - ACE_CATCHANY // Only CORBA exceptions are caught here. - { - if (response_required) - this->send_error (request_id, &ex); - else - { - if (TAO_debug_level > 0) - { - ACE_ERROR ((LM_ERROR, - "(%P|%t) exception thrown " - "but client is not waiting a response\n")); - ACE_TRY_ENV.print_exception (""); - } - - // It is unfotunate that an exception (probably a system - // exception) was thrown by the upcall code (even by the - // user) when the client was not expecting a response. - // However, in this case, we cannot close the connection - // down, since it really isn't the client's fault. - result = 0; - } - return result; - } -#if defined (TAO_HAS_EXCEPTIONS) - ACE_CATCHALL + if (result == -1 && TAO_debug_level > 0) { - // @@ TODO some c++ exception or another, but what do we do with - // it? - // We are supposed to map it into a CORBA::UNKNOWN exception. - // BTW, this cannot be detected if using the mapping. - // If we have native exceptions but no support for them - // in the ORB we should still be able to catch it. - // If we don't have native exceptions it couldn't have been - // raised in the first place! - - ACE_ERROR ((LM_ERROR, - "(%P|%t) closing conn %d after fault %p\n", - this->peer().get_handle (), - "TAO_UIOP_Server_Connection_Handler::handle_input")); - // this->handle_close (); - return -1; + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "UIOP_Server_CH::handle_input, handle_input")); } -#endif /* TAO_HAS_EXCEPTIONS */ - ACE_ENDTRY; - - if (response_required) + if (result == 1) { - if (!error_encountered) - this->send_response (output); - else + TAO_GIOP_MessageHeader header_copy = this->message_header_; + this->message_header_.message_size = 0; + TAO_InputCDR input (&this->payload_, + header_copy.byte_order, + this->orb_core_); + result = TAO_GIOP::process_server_message (this->transport (), + this->orb_core_, + input, + header_copy); + if (result == -1 && TAO_debug_level > 0) { - // No exception but some kind of error, yet a response is - // required. - if (TAO_orbdebug) - ACE_ERROR ((LM_ERROR, - "TAO: (%P|%t) %s: closing conn, no exception, " - "but expecting response\n", - "TAO_UIOP_Server_Connection_Handler::handle_input")); - // this->handle_close (); - return -1; + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "UIOP_Server_CH::handle_input, upcall")); } } - else if (error_encountered) - { - // No exception, no response expected, but an error ocurred, - // close the socket. - if (TAO_orbdebug) - ACE_ERROR ((LM_ERROR, - "TAO: (%P|%t) %s: closing conn, no exception, " - "but expecting response\n", - "TAO_UIOP_Server_Connection_Handler::handle_input")); - // this->handle_close (); - return -1; - } - - // TAO_MINIMAL_TIMEPROBE (TAO_SERVER_CONNECTION_HANDLER_HANDLE_INPUT_END); - return result; } // **************************************************************** -// @@ For pluggable protocols, added a reference to the corresponding -// transport obj. TAO_UIOP_Client_Connection_Handler:: TAO_UIOP_Client_Connection_Handler (ACE_Thread_Manager *t, TAO_ORB_Core* orb_core) @@ -863,8 +416,6 @@ TAO_UIOP_Client_Connection_Handler::close (u_long) // **************************************************************** -// **************************************************************** - #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) diff --git a/TAO/tao/UIOP_Connect.h b/TAO/tao/UIOP_Connect.h index 1a4f5d9de1a..2ae859bb701 100644 --- a/TAO/tao/UIOP_Connect.h +++ b/TAO/tao/UIOP_Connect.h @@ -17,20 +17,21 @@ #ifndef TAO_UIOP_CONNECT_H #define TAO_UIOP_CONNECT_H -# include "ace/Reactor.h" +#include "ace/Reactor.h" -# if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) #if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once +#pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -# include "ace/Acceptor.h" -# include "ace/LSOCK_Acceptor.h" -# include "ace/Synch.h" -# include "ace/Svc_Handler.h" +#include "ace/Acceptor.h" +#include "ace/LSOCK_Acceptor.h" +#include "ace/Synch.h" +#include "ace/Svc_Handler.h" -# include "tao/corbafwd.h" +#include "tao/corbafwd.h" +#include "tao/GIOP.h" // Forward Decls class TAO_Transport; @@ -158,11 +159,6 @@ protected: virtual void send_response (TAO_OutputCDR &response); // Send to the client on the other end. - void send_error (CORBA::ULong request_id, - CORBA::Exception *ex); - // Send to the client on the other end, which - // means basically sending the exception. - // = Event Handler overloads virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); @@ -178,12 +174,18 @@ protected: TAO_ORB_Core_TSS_Resources *tss_resources_; // Cached tss resources of the ORB that activated this object. + + TAO_GIOP_MessageHeader message_header_; + CORBA::ULong current_offset_; + ACE_Message_Block payload_; + // This keep the state of the current message, to enable + // non-blocking reads. }; #if defined (__ACE_INLINE__) -# include "tao/UIOP_Connect.i" +#include "tao/UIOP_Connect.i" #endif /* __ACE_INLINE__ */ -# endif /* !ACE_LACKS_UNIX_DOMAIN_SOCKETS */ +#endif /* !ACE_LACKS_UNIX_DOMAIN_SOCKETS */ #endif /* TAO_UIOP_CONNECT_H */ diff --git a/TAO/tao/UIOP_Transport.cpp b/TAO/tao/UIOP_Transport.cpp index 5f3ea42b918..d58b202079e 100644 --- a/TAO/tao/UIOP_Transport.cpp +++ b/TAO/tao/UIOP_Transport.cpp @@ -46,7 +46,6 @@ ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Transport_Timeprobe_Description, #endif /* ACE_ENABLE_TIMEPROBES */ - TAO_UIOP_Transport::TAO_UIOP_Transport (TAO_UIOP_Handler_Base *handler, TAO_ORB_Core *orb_core) : TAO_Transport (TAO_IOP_TAG_UNIX_IOP, @@ -59,20 +58,22 @@ TAO_UIOP_Transport::~TAO_UIOP_Transport (void) { } -TAO_UIOP_Server_Transport::TAO_UIOP_Server_Transport (TAO_UIOP_Server_Connection_Handler *handler, - TAO_ORB_Core* orb_core) - : TAO_UIOP_Transport (handler, - orb_core), +TAO_UIOP_Server_Transport:: + TAO_UIOP_Server_Transport (TAO_UIOP_Server_Connection_Handler *handler, + TAO_ORB_Core* orb_core) + : TAO_UIOP_Transport (handler, orb_core), server_handler_ (handler) { } -TAO_UIOP_Client_Transport::TAO_UIOP_Client_Transport (TAO_UIOP_Client_Connection_Handler *handler, - TAO_ORB_Core *orb_core) +TAO_UIOP_Client_Transport:: + TAO_UIOP_Client_Transport (TAO_UIOP_Client_Connection_Handler *handler, + TAO_ORB_Core *orb_core) : TAO_UIOP_Transport (handler, orb_core), client_handler_ (handler) { + message_header_.message_size = 0; } TAO_UIOP_Server_Transport::~TAO_UIOP_Server_Transport (void) @@ -107,18 +108,6 @@ TAO_UIOP_Transport::idle (void) return this->handler_->idle(); } -int -TAO_UIOP_Transport::is_nil (TAO_Transport *obj) -{ - return obj == 0; -} - -TAO_Transport * -TAO_UIOP_Transport::_nil (void) -{ - return (TAO_UIOP_Transport *)0; -} - void TAO_UIOP_Transport::close_connection (void) { @@ -134,13 +123,17 @@ TAO_UIOP_Transport::handle (void) int TAO_UIOP_Client_Transport::send_request (TAO_ORB_Core *orb_core, TAO_OutputCDR &stream, - int twoway) + int two_way) { ACE_FUNCTION_TIMEPROBE (TAO_UIOP_CLIENT_TRANSPORT_SEND_REQUEST_START); - return this->ws_->send_request (orb_core, - stream, - twoway); + if (this->ws_->sending_request (orb_core, + two_way) == -1) + return -1; + + return TAO_GIOP::send_message (this, + stream, + orb_core); } // Return 0, when the reply is not read fully, 1 if it is read fully. @@ -149,9 +142,6 @@ TAO_UIOP_Client_Transport::send_request (TAO_ORB_Core *orb_core, int TAO_UIOP_Client_Transport::handle_client_input (int block) { - // @@ Alex: it should be possible to make this code generic and move - // it to the GIOP class or something similar.... - // When we multiplex several invocations over a connection we need // to allocate the CDR stream *here*, but when there is a single // request over a connection the CDR stream can be pre-allocated on @@ -178,147 +168,63 @@ TAO_UIOP_Client_Transport::handle_client_input (int block) // removed. // Do I make any sense? - // Receive the message. Get also the GIOP version number. - // is non-blocking!!!! - // - // + In , Don't worry about blocking on the GIOP - // header, it's only 12 bytes, use read_n() for the header but - // non-blocking for the rest. - // - // + After reading the header you can allocate memory for the - // complete buffer [this is there already, look at how they - // do it!] - // - - // if (!this->message_size_) - // { - // Reading the header. - - // @@ Where do I keep this CDR? (alex) - // } - - // Get the CDR stream for reading the input. - TAO_InputCDR* cdr = this->input_cdr_stream (); - - // @@ Exclsive RMS instead of giving the CDR given by the Invocation - // class, it should give the preallocated CDR so that it can give - // that CDR to the invocation back, if there is a valid reply or - // it can just forget it, for example, if there was a close - // connection message or something. (Alex) + TAO_InputCDR* cdr = this->rms_->get_cdr_stream (); + ACE_Message_Block* payload = + ACE_const_cast(ACE_Message_Block*, cdr->start ()); - // If RMS not expecting any message, handle the unexpected data. - if (cdr == 0) - return this->check_unexpected_data (); - - TAO_GIOP_Version version; - - TAO_GIOP::Message_Type message_type = - TAO_GIOP::recv_message (this, - *cdr, - this->orb_core_, - version, - block); - switch (message_type) + int result = TAO_GIOP::handle_input (this, + this->orb_core_, + this->message_header_, + this->current_offset_, + payload); + if (result == -1) { - case TAO_GIOP::ShortRead: - // Return a value so that this we will get called again to - // handle the input. - return 0; - // NOT REACHED. - - case TAO_GIOP::EndOfFile: - case TAO_GIOP::CommunicationError: - case TAO_GIOP::MessageError: - // Handle errors like these. - // @@ this->reply_handler_->error (); - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) %N:%l handle_client_input: " - "error on stream.\n"), - -1); - - case TAO_GIOP::Fragment: - // Handle this. - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) %N:%l handle_client_input: " - "fragment.\n"), - -1); - - case TAO_GIOP::Request: - // In GIOP 1.0 and GIOP 1.1 this is an error, but it is - // *possible* to receive requests in GIOP 1.2. Don't handle this - // on the firt iteration, leave it for the nearby future... - // ERROR too. - // @@ this->reply_handler_->error (); - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) %N:%l handle_client_input: " - "request.\n"), - -1); - - case TAO_GIOP::CancelRequest: - case TAO_GIOP::LocateRequest: - case TAO_GIOP::CloseConnection: - default: - // @@ Errors for the time being. - // @@ this->reply_handler_->error (); - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) %N:%l handle_client_input: " - "wrong message.\n"), - -1); - - case TAO_GIOP::LocateReply: - case TAO_GIOP::Reply: - // Handle after the switch. - break; + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "UIOP_Transport::handle_client_input, handle_input")); + return -1; } + if (result == 0) + return result; - // For GIOP 1.0 and 1.1 the reply_ctx comes first: - // @@ Put this reply ctx into the reply dispatcher. so that - // invocation can read it. - // We should pass that reply_ctx to the invocation, interceptors - // will want to read it! + // OK, the complete message is here... - TAO_GIOP_ServiceContextList reply_ctx; - *cdr >> reply_ctx; - - // Read the request id and the reply status type. - // status can be NO_EXCEPTION, SYSTEM_EXCEPTION, USER_EXCEPTION, - // LOCATION_FORWARD or (on GIOP 1.2) LOCATION_FORWARD_PERM + TAO_GIOP_MessageHeader header_copy = this->message_header_; + this->message_header_.message_size = 0; + TAO_GIOP_ServiceContextList reply_ctx; CORBA::ULong request_id; CORBA::ULong reply_status; + + result = TAO_GIOP::parse_reply (this, + this->orb_core_, + *cdr, + header_copy, + reply_ctx, + request_id, + reply_status); + if (result == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "UIOP_Transport::handle_client_input, parse reply")); + return -1; + } - if (!cdr->read_ulong (request_id)) - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) : UIOP_Client_Transport::" - "handle_client_input - error while " - "reading request_id\n"), - -1); - - if (!cdr->read_ulong (reply_status)) - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) : UIOP_Client_Transport::" - "handle_client_input - error while " - "reading reply status\n"), - -1); - - // @@ Alex: for some reason this was causing a crash with the - // leader-follower wait strategy. Somehow it seems like the rms - // still has a pointer to an object that was already destroyed - // (i.e. the stack was unrolled on the thread waiting for this - // event), since this is only needed for *true* asynchronous - // messaging. - //ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - dispatching reply <%x>\n", this)); if (this->rms_->dispatch_reply (request_id, reply_status, - version, + header_copy.giop_version, reply_ctx, cdr) != 0) { - ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) : UIOP_Client_Transport::" - "handle_client_input - " - "dispatch reply failed\n"), - -1); + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) : UIOP_Client_Transport::" + "handle_client_input - " + "dispatch reply failed\n")); + return -1; } // This is a NOOP for the Exclusive request case, but it actually diff --git a/TAO/tao/UIOP_Transport.h b/TAO/tao/UIOP_Transport.h index b8828ded4f7..62465379fb1 100644 --- a/TAO/tao/UIOP_Transport.h +++ b/TAO/tao/UIOP_Transport.h @@ -59,12 +59,6 @@ public: TAO_UIOP_Handler_Base *&handler (void); // Return a reference to the corresponding connection handler. - int is_nil (TAO_Transport *obj); - // Returns 0 if the obj is 0, else 1. - - TAO_Transport *_nil (void); - // Return a NULL pointer of type TAO_Transport *. - ACE_HANDLE handle (void); // Return the underlying connection handle. @@ -158,6 +152,11 @@ protected: private: TAO_UIOP_Client_Connection_Handler *client_handler_; // pointer to the corresponding client side connection handler. + + TAO_GIOP_MessageHeader message_header_; + CORBA::ULong current_offset_; + // This keep the state of the current message, to enable + // non-blocking reads. }; // **************************************************************** diff --git a/TAO/tao/Wait_Strategy.cpp b/TAO/tao/Wait_Strategy.cpp index c1f3d7bde3b..0a9ebf0a4d5 100644 --- a/TAO/tao/Wait_Strategy.cpp +++ b/TAO/tao/Wait_Strategy.cpp @@ -19,18 +19,10 @@ TAO_Wait_Strategy::~TAO_Wait_Strategy (void) } int -TAO_Wait_Strategy::send_request (TAO_ORB_Core *orb_core, - TAO_OutputCDR &stream, - int /* two_way */) +TAO_Wait_Strategy::sending_request (TAO_ORB_Core * /* orb_core */, + int /* two_way */) { - int success = (int) TAO_GIOP::send_request (this->transport_, - stream, - this->transport_->orb_core ()); - - if (!success) - return -1; - else - return 0; + return 0; } // ********************************************************************* @@ -134,9 +126,8 @@ TAO_Wait_On_Leader_Follower::~TAO_Wait_On_Leader_Follower (void) // with the object and flag wont make sense // at this level since this is common for AMI also. (Alex). int -TAO_Wait_On_Leader_Follower::send_request (TAO_ORB_Core *orb_core, - TAO_OutputCDR &stream, - int two_way) +TAO_Wait_On_Leader_Follower::sending_request (TAO_ORB_Core *orb_core, + int two_way) { { ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, @@ -170,12 +161,10 @@ TAO_Wait_On_Leader_Follower::send_request (TAO_ORB_Core *orb_core, // ago) about using the wrong ORB core, but that may have been // fixed... - // Obtain the lock. // Send the request int result = - TAO_Wait_Strategy::send_request (orb_core, - stream, - two_way); + this->TAO_Wait_Strategy::sending_request (orb_core, + two_way); if (result == -1) { diff --git a/TAO/tao/Wait_Strategy.h b/TAO/tao/Wait_Strategy.h index ffce521c48f..ffe71f1cb18 100644 --- a/TAO/tao/Wait_Strategy.h +++ b/TAO/tao/Wait_Strategy.h @@ -48,10 +48,11 @@ public: virtual ~TAO_Wait_Strategy (void); // Destructor. - virtual int send_request (TAO_ORB_Core *orb_core, - TAO_OutputCDR &stream, - int two_way); - // Does the send. + virtual int sending_request (TAO_ORB_Core *orb_core, + int two_way); + // The user is going to send a request, prepare any internal + // variables because the reply may arrive *before* the user calls + // wait. virtual int wait (void) = 0; // Base class virtual method. @@ -129,23 +130,13 @@ public: virtual ~TAO_Wait_On_Leader_Follower (void); // Destructor. - virtual int send_request (TAO_ORB_Core *orb_core, - TAO_OutputCDR &stream, - int two_way); - // Send the request. Set some flags in case of two way call. - + // = Documented in TAO_Wait_Strategy + virtual int sending_request (TAO_ORB_Core *orb_core, + int two_way); virtual int wait (void); - // Wait according to the L-F model. - virtual int handle_input (void); - // Handle the input. Delegate this job to Transport object. Before - // that, suspend the handler in the Reactor. - virtual int handle_close (void); - // The connection was closed, take appropiate action... - virtual int register_handler (void); - // Register the handler with the Reactor. protected: ACE_SYNCH_CONDITION* cond_response_available (void); diff --git a/TAO/tests/MT_Client/test_i.cpp b/TAO/tests/MT_Client/test_i.cpp index a71e2e849d5..90782ea5deb 100644 --- a/TAO/tests/MT_Client/test_i.cpp +++ b/TAO/tests/MT_Client/test_i.cpp @@ -29,5 +29,5 @@ Simple_Server_i::get_number (CORBA::Environment&) void Simple_Server_i::shutdown (CORBA::Environment&) { - this->orb_->shutdown (1); + this->orb_->shutdown (0); } -- cgit v1.2.1