From afbba58b27300d4d2e08d3287168d305d3f69654 Mon Sep 17 00:00:00 2001 From: Chris Cleeland Date: Mon, 15 Dec 2003 22:31:47 +0000 Subject: Tag: pmb_integration Started work on performance enhancements for PMB. --- TAO/tao/GIOP_Message_State.h | 44 ++++++----- TAO/tao/Incoming_Message_Queue.h | 162 ++++++++++++++++++++++++++++++++++----- 2 files changed, 168 insertions(+), 38 deletions(-) diff --git a/TAO/tao/GIOP_Message_State.h b/TAO/tao/GIOP_Message_State.h index f902fa03a0e..9ae3db82230 100644 --- a/TAO/tao/GIOP_Message_State.h +++ b/TAO/tao/GIOP_Message_State.h @@ -41,11 +41,10 @@ class TAO_Export TAO_GIOP_Message_State public: /// Ctor - TAO_GIOP_Message_State (TAO_ORB_Core *orb_core, - TAO_GIOP_Message_Base *base); + TAO_GIOP_Message_State (TAO_ORB_Core *orb_core = 0, + TAO_GIOP_Message_Base *base = 0); - /// Parse the message header. - int parse_message_header (ACE_Message_Block &incoming); + int take_values_from_message_block (const ACE_Message_Block& mb); /// Return the message size CORBA::ULong message_size (void) const; @@ -53,9 +52,24 @@ public: /// Return the message size CORBA::ULong payload_size (void) const; - /// Return the byte order information + /*! + \brief Return the byte order information. + \return 0 big-endian + \return 1 little-endian + */ CORBA::Octet byte_order (void) const; + /*! + \brief Return GIOP version information. + */ + const TAO_GIOP_Message_Version &giop_version () const; + + /// (Requests and Replys) + CORBA::Octet more_fragments () const; + + /// MsgType above + CORBA::Octet message_type () const; + /// Reset the state.. void reset (void); @@ -63,40 +77,30 @@ private: friend class TAO_GIOP_Message_Base; - /// Parse the message header. - int parse_message_header_i (ACE_Message_Block &incoming); - - /// Checks for the magic word 'GIOP' in the start of the incoing - /// stream - int parse_magic_bytes (char *buf); - /// Extracts the version information from the incoming /// stream. Performs a check for whether the version information is /// right and sets the information in the - int get_version_info (char *buf); + int set_version_info_from_buffer (const char *buf); /// Extracts the byte order information from the incoming /// stream. Performs a check for whether the byte order information /// right and sets the information in the - int get_byte_order_info (char *buf); + int set_byte_order_info_from_buffer (const char *buf); /// Gets the size of the payload and set the size in the - void get_payload_size (char *buf); + void set_payload_size_from_buffer (const char *buf); /// Parses the GIOP FRAGMENT_HEADER information from the incoming /// stream. - int parse_fragment_header (char *buf, + int parse_fragment_header (const char *buf, size_t length); /// Read the unsigned long from the buffer. The should just /// point to the next 4 bytes data that represent the ULong - CORBA::ULong read_ulong (char *buf); + CORBA::ULong read_ulong (const char *buf); private: - /// The GIOP base class.. - TAO_GIOP_Message_Base *base_; - // GIOP version information.. TAO_GIOP_Message_Version giop_version_; diff --git a/TAO/tao/Incoming_Message_Queue.h b/TAO/tao/Incoming_Message_Queue.h index 3adfc3d24ac..660a207090b 100644 --- a/TAO/tao/Incoming_Message_Queue.h +++ b/TAO/tao/Incoming_Message_Queue.h @@ -27,6 +27,7 @@ class ACE_Allocator; class TAO_ORB_Core; class TAO_Queued_Data; class TAO_Transport; +class TAO_Pluggable_Messaging; /** * @class TAO_Incoming_Message_Queue @@ -75,31 +76,68 @@ public: /// Return the length of the queue.. CORBA::ULong queue_length (void); - /// Methods for sanity check. Checks to see whether the node on the - /// head or tail is complete or not and ready for further - /// processing. + /*! + @name Node Inspection Predicates + + \brief These methods allow inspection of head and tail nodes for "completeness". + + These methods check to see whether the node on the head or tail is + "complete" and ready for further processing. See each method's + documentation for its definition of "complete". + */ + //@{ + /*! + "complete" == the GIOP message at the tail is not missing any data (it may be a complete GIOP Fragment, though) + + \return -1 queue is empty + \return 0 tail is not "complete" + \return 1 tail is "complete" + */ int is_tail_complete (void); + + /*! + + "complete" == the GIOP message at the head is not missing any data + AND, if it's the first message in a series of GIOP fragments, all + the fragments have been received, parsed, and placed into the + queue + + \return -1 if queue is empty + \return 0 if head is not "complete" + \return 1 if head is "complete" + */ int is_head_complete (void); + //@} - /// This method checks whether the last message that was queued up - /// was fragmented... + /*! + \brief Check to see if the message at the tail (complete or incomplete) is a GIOP Fragment. + */ int is_tail_fragmented (void); /// Return the size of data that is missing in tail of the queue. size_t missing_data_tail (void) const; /// void missing_data (size_t data); + /// Find the first fragment that matches the GIOP version + TAO_Queued_Data *find_fragment (CORBA::Octet major, + CORBA::Octet minor) const; + + /// Find the first fragment that matches the request id + TAO_Queued_Data *find_fragment (CORBA::ULong request_id) const; + private: friend class TAO_Transport; - /// Make a node for the queue. - TAO_Queued_Data *get_node (void); - private: + /*! + \brief A circular linked list of messages awaiting processing. - /// A linked listof messages that await processing - TAO_Queued_Data *queued_data_; + \a last_message_added_ points to the most recent message added to + the list. The earliest addition can be easily accessed via + \a last_message_added_->next_. + */ + TAO_Queued_Data *last_added_; /// The size of the queue CORBA::ULong size_; @@ -123,20 +161,73 @@ private: class TAO_Export TAO_Queued_Data { -public: +protected: /// Default Constructor TAO_Queued_Data (ACE_Allocator *alloc = 0); /// Constructor. TAO_Queued_Data (ACE_Message_Block *mb, ACE_Allocator *alloc = 0); +public: /// Copy constructor. TAO_Queued_Data (const TAO_Queued_Data &qd); - /// Creation and deletion of a node in the queue. - static TAO_Queued_Data* get_queued_data (ACE_Allocator *alloc = 0); + /*! + \name Factory Methods + + These methods manufacture instances of TAO_Queued_Data and return + them. These instances should be removed via TAO_Queued_Data::release. + + Instances are initialized from data in the ACE_Message_Block, + interpreted according to rules defined in the + TAO_Pluggable_Messaging object. + + The manufactured instance adopts the message block \em without + duplicating it; therefore, the caller must duplicate or orphan the + message block. The caller also must insure that the message block + can be released via ACE_Message_Block::release, and that its life + endures beyond the calling scope. + + For the purposes of TAO_Queued_Data, a completed message is a + completely received message as defined by the messaging protocol + object. For GIOP, that means that the number of bytes specified + in the general GIOP header have been completely received. It + specifically DOES NOT mean that all \em fragments have been + received. Fragment reassembly is another matter altogether. + */ + //@{ + /*! + \brief Make and return an instance of TAO_Queued_Data suitable for use as an uncompleted message. + */ + static TAO_Queued_Data* make_uncompleted_message (ACE_Message_Block *mb, + TAO_Pluggable_Messaging &msging_obj, + ACE_Allocator *alloc = 0); + /*! + \brief Make and return an instance of TAO_Queued_Data suitable for use as a completed message. + */ + // THIS IMPLEMENTATION DOESN'T WORK THE SAME AS ITS USAGE! + // WE CAN'T JUST ADOPT mb, BECAUSE IT MAY CONTAIN MORE THAN + // ONE PROTOCOL MESSAGE. WE THEREFORE NEED TO CLONE IT. THIS + // MEANS UPDATING THE DOCUMENTATION, AND IT ALSO MEANS THAT IT + // BEHAVES DIFFERENTLY FROM make_uncompleted_message. + static TAO_Queued_Data* make_completed_message (ACE_Message_Block &mb, + TAO_Pluggable_Messaging &msging_obj, + ACE_Allocator *alloc = 0); + + /// Consolidate this fragments chained message blocks into one. + void consolidate (void); + + /*! + \brief Creation and deletion of a node in the queue. + \todo Maybe this should be private? + */ +private: + static TAO_Queued_Data* make_queued_data (ACE_Allocator *alloc = 0); +public: + //@} static void release (TAO_Queued_Data *qd); + void release (void); /// Duplicate ourselves. This creates a copy of ourselves on the /// heap and returns a pointer to the duplicated node. @@ -146,11 +237,43 @@ public: /// The message block that contains the message. ACE_Message_Block *msg_block_; - /// Data missing in the above message that hasn't been read or - /// processed yet. - CORBA::Long missing_data_; - - /// The byte order of the message that is stored in the node.. + /*! + @name Missing Data details + + The \a missing_data_bytes_ member contains the number of bytes of + data missing from \a msg_block_. However, there can be two places + where data is missing: header and payload. We cannot know how + much data is missing from the payload until we have a complete + header. Fortunately, headers are a fixed length, so we can know + how much we're missing from the header. + + We use \param current_state_ to indicate which portion of the message + \param missing_data_bytes_ refers to, as well as the general state of + the message. + */ + //@{ + /*! + Describes the meaning given to the number stored in \a missing_data_bytes_. + */ + enum Queued_Data_State + { + INVALID = -1, //!< The queued data is in an invalid/uninitialized state, and no data should be trusted. + COMPLETED = 0, //!< Message is complete; \a missing_data_bytes_ should be zero. + WAITING_TO_COMPLETE_HEADER, //!< Value in \a missing_data_bytes_ indicates part of header is missing. + WAITING_TO_COMPLETE_PAYLOAD //!< Value in \a missing_data_bytes_ indicates part of payload is missing. + }; + + /*! + Indicates the current state of the message, including hints at + how to interpret the value stored in \a missing_data_bytes_. + */ + Queued_Data_State current_state_; + + /*! Data missing in the above message that hasn't been read or processed yet. */ + size_t missing_data_bytes_; + //@} + + /*! The byte order of the message that is stored in the node. */ CORBA::Octet byte_order_; /// Many protocols like GIOP have a major and minor version @@ -165,6 +288,9 @@ public: /// queue already has more fragments that is missing.. CORBA::Octet more_fragments_; + /// The fragment request id + CORBA::ULong request_id_; + /// The message type of the message TAO_Pluggable_Message_Type msg_type_; -- cgit v1.2.1