diff options
Diffstat (limited to 'TAO/tao/GIOP_Message_Factory.cpp')
-rw-r--r-- | TAO/tao/GIOP_Message_Factory.cpp | 204 |
1 files changed, 200 insertions, 4 deletions
diff --git a/TAO/tao/GIOP_Message_Factory.cpp b/TAO/tao/GIOP_Message_Factory.cpp index 9ddba82937c..2b62bc0b6be 100644 --- a/TAO/tao/GIOP_Message_Factory.cpp +++ b/TAO/tao/GIOP_Message_Factory.cpp @@ -1,8 +1,52 @@ //$Id$ -#include "GIOP_Message.h" +// @(#)giop.cpp 1.10 95/09/21 +// Copyright 1994-1995 by Sun Microsystems Inc. +// All Rights Reserved +// +// GIOP: Utility routines for sending, receiving GIOP messages +// +// Note that the Internet IOP is just the TCP-specific mapping of the +// General IOP. Areas where other protocols may map differently +// include use of record streams (TCP has none), orderly disconnect +// (TCP has it), endpoint addressing (TCP uses host + port), security +// (Internet security should be leveraged by IIOP) and more. +// +// NOTE: There are a few places where this code knows that it's really +// talking IIOP instead of GIOP. No rush to fix this so long as we +// are really not running atop multiple connection protocols. +// +// THREADING NOTE: currently, the connection manager eliminates tricky +// threading issues by providing this code with the same programming +// model both in threaded and unthreaded environments. Since the GIOP +// APIs were all designed to be reentrant, this makes threading rather +// simple! +// +// That threading model is that the thread making (or handling) a call +// is given exclusive access to a connection for the duration of a +// call, so that no multiplexing or demultiplexing is needed. That +// is, locking is at the "connection level" rather than "message +// level". -#if defined (__ACE_INLINE__) -# include "tao/Pluggable_Messaging.i" +// The down side of this simple threading model is that utilization of +// system resources (mostly connections, but to some extent network +// I/O) in some kinds of environments can be inefficient. However, +// simpler threading models are much easier to get properly debugged, +// and often perform better. Also, such environments haven't been +// seen to be any kind of problem; the model can be changed later if +// needed, it's just an internal implementation detail. Any portable +// ORB client is not allowed to rely on semantic implications of such +// a model. +// +// @@ there is lots of unverified I/O here. In all cases, if an +// error is detected when marshaling or unmarshaling, it should be +// reported. + +#include "tao/GIOP_Message_Factory.h" +#include "tao/Any.h" + + +#if !defined (__ACE_INLINE__) +# include "tao/GIOP_Message_Factory.i" #endif /* __ACE_INLINE__ */ TAO_GIOP_Message_Factory::TAO_GIOP_Message_Factory (void) @@ -13,7 +57,7 @@ TAO_GIOP_Message_Factory::~TAO_GIOP_Message_Factory (void) { } -CORBA::Boolean +/*CORBA::Boolean TAO_GIOP_Message_Factory::start_message (const TAO_GIOP_Version &version, TAO_GIOP_Message_Factory::Message_Type t, TAO_OutputCDR &msg) @@ -43,3 +87,155 @@ TAO_GIOP_Message_Factory::start_message (const TAO_GIOP_Version &version, return 1; } +*/ + +CORBA::Boolean +TAO_GIOP_Message_Factory::write_request_header (const IOP::ServiceContextList& /*svc_ctx*/, + CORBA::ULong request_id, + CORBA::Octet response_flags, + TAO_Stub */*stub*/, + const CORBA::Short address_disposition, + const char */*opname*/, + TAO_OutputCDR &msg) +{ + // Adding only stuff that are common to all versions of GIOP. + // @@ Note: If at any stage we feel that this amount of granularity + // for factorisation is not important we can dispense with it + // anyway. + + // First the request id + msg << request_id; + + // Second the response flags + switch (response_flags) + { + // We have to use magic numbers as the actual variables are + // declared as const short. They cannot be used in switch case + // statements. Probably what we can do is to add them as an + // definitions in this class or in the parent and then use the + // definitions. Hmm. Good idea.. But we will live with this for + // the time being. + case 0: // SYNC_NONE + case 1: // SYNC_WITH_TRANSPORT + case 4: // This one corresponds to the TAO extension SYNC_FLUSH. + // No response required. + msg << CORBA::Any::from_octet (0); + break; + case 2: // SYNC_WITH_SERVER + // Return before dispatching servant. + msg << CORBA::Any::from_octet (1); + break; + case 3: // SYNC_WITH_TARGET + // Return after dispatching servant. + msg << CORBA::Any::from_octet (3); + break; + // Some cases for the DII are missing here. We can add that once + // our IDL compiler starts supporting those stuff. This is + // specific to GIOP 1.2. So some of the services would start + // using this at some point of time and we will have them here + // naturally out of a need. + + default: + // Until more flags are defined by the OMG. + return 0; + } + + return 1; +} + + + + +TAO_GIOP_Message_Factory::send_message (TAO_Transport *transport, + TAO_OutputCDR &stream, + ACE_Time_Value *max_wait_time = 0, + TAO_Stub *stub = 0) +{ + // TAO_FUNCTION_PP_TIMEPROBE (TAO_GIOP_SEND_MESSAGE_START); + + // Ptr to first buffer. + char *buf = (char *) stream.buffer (); + + // Length of all buffers. + size_t total_len = + stream.total_length (); + + // NOTE: Here would also be a fine place to calculate a digital + // signature for the message and place it into a preallocated slot + // in the "ServiceContext". Similarly, this is a good spot to + // encrypt messages (or just the message bodies) if that's needed in + // this particular environment and that isn't handled by the + // networking infrastructure (e.g., IPSEC). + + // Get the header length + size_t header_len = this->get_header_len (); + + // Get the message size offset + size_t offset = this->get_message_size_offset (); + + CORBA::ULong bodylen = total_len - header_len; + +#if !defined (ACE_ENABLE_SWAP_ON_WRITE) + *ACE_reinterpret_cast (CORBA::ULong *, buf + offset) = bodylen; +#else + if (!stream->do_byte_swap ()) + *ACE_reinterpret_cast (CORBA::ULong *, + buf + offset) = bodylen; + else + ACE_CDR::swap_4 (ACE_reinterpret_cast (char *, + &bodylen), + buf + offset); +#endif /* ACE_ENABLE_SWAP_ON_WRITE */ + + // Strictly speaking, should not need to loop here because the + // socket never gets set to a nonblocking mode ... some Linux + // versions seem to need it though. Leaving it costs little. + this->dump_msg ("send", + ACE_reinterpret_cast (u_char *, + buf), + stream.length ()); + + // This guarantees to send all data (bytes) or return an error. + ssize_t n = transport->send (stub, + stream.begin (), + max_wait_time); + + if (n == -1) + { + if (TAO_orbdebug) + ACE_DEBUG ((LM_DEBUG, + "TAO: (%P|%t) closing conn %d after fault %p\n", + transport->handle (), + "GIOP_Message_Factory::send_message ()")); + + return -1; + } + + // EOF. + if (n == 0) + { + if (TAO_orbdebug) + ACE_DEBUG ((LM_DEBUG, + "TAO: (%P|%t) GIOP::send_message () " + "EOF, closing conn %d\n", + transport->handle())); + return -1; + } + + return 1; +} + +void +TAO_GIOP_Message_Factory::dump_msg (const char */*label*/, + const u_char */*ptr*/, + size_t /*len*/) +{ + if (TAO_debug_level >= 5) + { + // I will have to print out all the relevant debug messages!! + // Let me not wory about that now. I will get back to that at a + // later date!! + } +} + + |