diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-09-27 15:26:53 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-09-27 15:26:53 +0000 |
commit | fe63d7b28e1ca4d3813e4adf599540800fc9efa8 (patch) | |
tree | 30e1b983270bb179ebb28185703e24c2f8361d4f /protocols | |
parent | 7e8b3a0398969ba6398b98128dd211d9e1593160 (diff) | |
download | ATCD-fe63d7b28e1ca4d3813e4adf599540800fc9efa8.tar.gz |
ChangeLogTag:Wed Sep 27 08:23:58 2000 Carlos O'Ryan <coryan@uci.edu>
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/ace/RMCast/Makefile | 6 | ||||
-rw-r--r-- | protocols/ace/RMCast/RMCast.h | 292 | ||||
-rw-r--r-- | protocols/ace/RMCast/RMCast_Membership.cpp | 24 | ||||
-rw-r--r-- | protocols/ace/RMCast/RMCast_Module.h | 49 | ||||
-rw-r--r-- | protocols/ace/RMCast/RMCast_Proxy.cpp | 8 | ||||
-rw-r--r-- | protocols/ace/RMCast/RMCast_Proxy.h | 55 | ||||
-rw-r--r-- | protocols/ace/RMCast/RMCast_Reassembly.cpp | 5 | ||||
-rw-r--r-- | protocols/ace/RMCast/RMCast_Reassembly.h | 16 | ||||
-rw-r--r-- | protocols/ace/RMCast/RMCast_Retransmission.cpp | 3 |
9 files changed, 291 insertions, 167 deletions
diff --git a/protocols/ace/RMCast/Makefile b/protocols/ace/RMCast/Makefile index 3241d84bca5..ae13792c4c4 100644 --- a/protocols/ace/RMCast/Makefile +++ b/protocols/ace/RMCast/Makefile @@ -74,7 +74,8 @@ include $(ACE_ROOT)/include/makeinclude/rules.local.GNU .obj/RMCast_Module.o .obj/RMCast_Module.so .shobj/RMCast_Module.o .shobj/RMCast_Module.so: RMCast_Module.cpp RMCast_Module.h \ $(ACE_ROOT)/ace/pre.h \ - RMCast.h $(ACE_ROOT)/ace/OS.h \ + RMCast.h \ + $(ACE_ROOT)/ace/OS.h \ $(ACE_ROOT)/ace/post.h \ $(ACE_ROOT)/ace/ACE_export.h \ $(ACE_ROOT)/ace/svc_export.h \ @@ -99,7 +100,8 @@ include $(ACE_ROOT)/include/makeinclude/rules.local.GNU .obj/RMCast_Module_Factory.o .obj/RMCast_Module_Factory.so .shobj/RMCast_Module_Factory.o .shobj/RMCast_Module_Factory.so: RMCast_Module_Factory.cpp \ RMCast_Module_Factory.h \ $(ACE_ROOT)/ace/pre.h \ - RMCast.h $(ACE_ROOT)/ace/OS.h \ + RMCast.h \ + $(ACE_ROOT)/ace/OS.h \ $(ACE_ROOT)/ace/post.h \ $(ACE_ROOT)/ace/ACE_export.h \ $(ACE_ROOT)/ace/svc_export.h \ diff --git a/protocols/ace/RMCast/RMCast.h b/protocols/ace/RMCast/RMCast.h index c7cdf718c04..abf2a24e946 100644 --- a/protocols/ace/RMCast/RMCast.h +++ b/protocols/ace/RMCast/RMCast.h @@ -28,69 +28,22 @@ class ACE_Message_Block; class ACE_RMCast_Proxy; +//! The RMCast namespace +/*! + Several simple data structures and enums are shared by all the + RMCast components, this is the place where we put them by default. +*/ class ACE_RMCast_Export ACE_RMCast { public: - // Message formats - - // From SENDER to RECEIVER - // - // POLL - // +---------+----------------------+ - // | 8 bits | MT_POLL | - // +---------+----------------------+ - // - // ACK_JOIN - // +---------+----------------------+ - // | 8 bits | MT_ACK_JOIN | - // +---------+----------------------+ - // | 32 bits | next_sequence_number | - // +---------+----------------------+ - // - // ACK_LEAVE - // +---------+----------------------+ - // | 8 bits | ACK_LEAVE | - // +---------+----------------------+ - // - // DATA - // +---------+----------------------+ - // | 8 bits | DATA | - // +---------+----------------------+ - // | 32 bits | sequence_number | - // +---------+----------------------+ - // | 32 bits | message_size | - // +---------+----------------------+ - // | 32 bits | fragment_offset | - // +---------+----------------------+ - // ? ? ? ? ? | 32 bits | payload_size | - // ? ? ? ? ? +---------+----------------------+ - // | | payload | - // +---------+----------------------+ - // - - // From RECEIVER to SENDER - // - // MT_JOIN - // +---------+----------------------+ - // | 8 bits | MT_JOIN | - // +---------+----------------------+ - // - // MT_LEAVE - // +---------+----------------------+ - // | 8 bits | MT_LEAVE | - // +---------+----------------------+ - // - // MT_ACK - // +---------+----------------------+ - // | 8 bits | MT_ACK | - // +---------+----------------------+ - // | 32 bits | highest_in_sequence | - // +---------+----------------------+ - // | 32 bits | highest_received | - // +---------+----------------------+ - // - + //! The message types + /*! + Each message includes a type field in the header used by the + receiver to correctly parse it. + Classes with the same name as the message type describe the actual + format of the message. + */ enum Message_Type { // Sender initiated @@ -105,6 +58,41 @@ public: MT_LAST }; + //! Simple enum used to describe the receiver state transitions + /*! + Receivers go through several states before they can fully accept + messages, the following comments describe those states, as well as + the possible transitions + This configuration is pesimistic, any invalid message is cause + enough to reclaim all the resources. This partially addresses + situations where either accidentally or intentionally a sender is + multicasting packets to the wrong group. + + <CODE> + NON_EXISTENT JOINING JOINED LEAVING<BR> + ----------------------------------------------------------------<BR> + POLL JOINING JOINING JOINED LEAVING<BR> + Send/Join Send/Join Send/Ack Send/Leave<BR> + <BR> + ACK NON_EXISTENT NON_EXISTENT NON_EXISTENT NON_EXISTENT<BR> + Noop Destroy Destroy Destroy<BR> + <BR> + JOIN NON_EXISTENT NON_EXISTENT NON_EXISTENT NON_EXISTENT<BR> + Noop Destroy Destroy Destroy<BR> + <BR> + LEAVE NON_EXISTENT NON_EXISTENT NON_EXISTENT NON_EXISTENT<BR> + Noop Destroy Destroy Destroy<BR> + <BR> + ACK_JOIN JOINING JOINED JOINED LEAVING<BR> + Send/Join Update ACT Update ACT Send/Leave<BR> + <BR> + ACK_LEAVE NON_EXISTENT NON_EXISTENT NON_EXISTENT NON_EXISTENT<BR> + Noop Destroy Destroy Destroy<BR> + <BR> + SEND_DATA JOINING JOINING JOINED LEAVING<BR> + Send/Join Send/Join Recv/Data Send/Leave<BR> + </CODE> + */ enum Receiver_State { RS_NON_EXISTENT, @@ -113,81 +101,75 @@ public: RS_LEAVING }; - // State transition (and actions) for the receivers. - // This configuration is pesimistic, any invalid message is cause - // enough to reclaim all the resources. This partially addresses - // situations where either accidentally or intentionally a sender is - // multicasting packets to the wrong group. - // - // NON_EXISTENT JOINING JOINED LEAVING - // ---------------------------------------------------------------- - // POLL JOINING JOINING JOINED LEAVING - // Send/Join Send/Join Send/Ack Send/Leave - // - // ACK NON_EXISTENT NON_EXISTENT NON_EXISTENT NON_EXISTENT - // Noop Destroy Destroy Destroy - // - // JOIN NON_EXISTENT NON_EXISTENT NON_EXISTENT NON_EXISTENT - // Noop Destroy Destroy Destroy - // - // LEAVE NON_EXISTENT NON_EXISTENT NON_EXISTENT NON_EXISTENT - // Noop Destroy Destroy Destroy - // - // ACK_JOIN JOINING JOINED JOINED LEAVING - // Send/Join Update ACT Update ACT Send/Leave - // - // ACK_LEAVE NON_EXISTENT NON_EXISTENT NON_EXISTENT NON_EXISTENT - // Noop Destroy Destroy Destroy - // - // SEND_DATA JOINING JOINING JOINED LEAVING - // Send/Join Send/Join Recv/Data Send/Leave - // + //! Simle enum used to describe the state transitions for senders + /*! + State transition (and actions) for the senders. + This configuration is pesimistic, any invalid message is cause + enough to reclaim all the resources. This partially addresses + situations where either accidentally or intentionally a sender is + multicasting packets to the wrong group. + + <CODE> + NON_EXISTENT JOINED<BR> + ------------------------------------------<BR> + POLL NON_EXISTENT NON_EXISTENT<BR> + Destroy Destroy<BR> + <BR> + ACK NON_EXISTENT JOINED<BR> + Noop Process/Ack<BR> + <BR> + JOIN JOINED NON_EXISTENT<BR> + Send/Join_Ack Send/Join_Ack<BR> + <BR> + LEAVE NON_EXISTENT NON_EXISTENT<BR> + Send/Leave_Ack Send/Leave_Ack<BR> + Destroy<BR> + <BR> + ACK_JOIN NON_EXISTENT NON_EXISTENT<BR> + Noop Destroy<BR> + <BR> + ACK_LEAVE NON_EXISTENT NON_EXISTENT<BR> + Noop Destroy<BR> + <BR> + SEND_DATA NON_EXISTENT NON_EXISTENT<BR> + Noop Destroy<BR> + </CODE> + */ enum Sender_State { SS_NON_EXISTENT, SS_JOINED }; - // State transition (and actions) for the senders. - // This configuration is pesimistic, any invalid message is cause - // enough to reclaim all the resources. This partially addresses - // situations where either accidentally or intentionally a sender is - // multicasting packets to the wrong group. - // - // NON_EXISTENT JOINED - // ------------------------------------------ - // POLL NON_EXISTENT NON_EXISTENT - // Destroy Destroy - // - // ACK NON_EXISTENT JOINED - // Noop Process/Ack - // - // JOIN JOINED NON_EXISTENT - // Send/Join_Ack Send/Join_Ack - // - // LEAVE NON_EXISTENT NON_EXISTENT - // Send/Leave_Ack Send/Leave_Ack - // Destroy - // - // ACK_JOIN NON_EXISTENT NON_EXISTENT - // Noop Destroy - // - // ACK_LEAVE NON_EXISTENT NON_EXISTENT - // Noop Destroy - // - // SEND_DATA NON_EXISTENT NON_EXISTENT - // Noop Destroy - // - // These structures define the basic layout of the messages. + + //! This is the main message sent by senders + /*! + <CODE> + +---------+----------------------+<BR> + | 8 bits | DATA |<BR> + +---------+----------------------+<BR> + | 32 bits | sequence_number |<BR> + +---------+----------------------+<BR> + | 32 bits | message_size |<BR> + +---------+----------------------+<BR> + | 32 bits | fragment_offset |<BR> + +---------+----------------------+<BR> + ? ? ? ? ? | 32 bits | payload_size |<BR> + ? ? ? ? ? +---------+----------------------+<BR> + | | payload |<BR> + +---------+----------------------+<BR> + </CODE> + */ struct Data { // Source ID is implicit in recvfrom()... ACE_UINT32 sequence_number; ACE_UINT32 total_size; ACE_UINT32 fragment_offset; + // @@ TODO: we may want to add optional fields, such as: // - Polling clients for their status // - Sending the range of messages in the queue @@ -196,41 +178,113 @@ public: ACE_Message_Block *payload; + //! Pass the proxy source between layers ACE_RMCast_Proxy *source; }; + /*! + <CODE> + +---------+----------------------+<BR> + | 8 bits | MT_POLL |<BR> + +---------+----------------------+<BR> + </CODE> + */ struct Poll { + //! Pass the proxy source between layers ACE_RMCast_Proxy *source; }; + //! Receivers accept new members using this message + /*! + <CODE> + +---------+----------------------+<BR> + | 8 bits | MT_ACK_JOIN |<BR> + +---------+----------------------+<BR> + | 32 bits | next_sequence_number |<BR> + +---------+----------------------+<BR> + </CODE> + */ struct Ack_Join { ACE_INT32 next_sequence_number; + //! Pass the proxy source between layers ACE_RMCast_Proxy *source; }; + //! Senders acknowledge when receivers try to leave + /*! + <CODE> + +---------+----------------------+<BR> + | 8 bits | ACK_LEAVE |<BR> + +---------+----------------------+<BR> + </CODE> + */ struct Ack_Leave { + //! Pass the proxy source between layers ACE_RMCast_Proxy *source; }; + //! Provide feedback to the sender about messages received and sent + //! so far. + /*! + * + * This message is used to provide feedback information to senders. + * It contains two sequence numbers: + * - highest_in_sequence: is the sequence number of the last message + * received without any lost messages before it + * - highest_received: is the sequence number of the last_message + * successfully received, there may be some messages lost before it + * + * <CODE> + * +---------+----------------------+<BR> + * | 8 bits | MT_ACK |<BR> + * +---------+----------------------+<BR> + * | 32 bits | highest_in_sequence |<BR> + * +---------+----------------------+<BR> + * | 32 bits | highest_received |<BR> + * +---------+----------------------+<BR> + * </CODE> + */ struct Ack { + //! The last message received without any losses before it. ACE_UINT32 highest_in_sequence; + + //! The last message successfully received ACE_UINT32 highest_received; + //! Pass the proxy source between layers ACE_RMCast_Proxy *source; }; + //! Receivers send this message to indicate they want to join + /* + <CODE> + +---------+----------------------+<BR> + | 8 bits | MT_JOIN |<BR> + +---------+----------------------+<BR> + </CODE> + */ struct Join { + //! Pass the proxy source between layers ACE_RMCast_Proxy *source; }; + //! Receivers send this message to disconnect gracefully + /*! + <CODE> + +---------+----------------------+<BR> + | 8 bits | MT_LEAVE |<BR> + +---------+----------------------+<BR> + </CODE> + */ struct Leave { + //! Pass the proxy source between layers ACE_RMCast_Proxy *source; }; }; diff --git a/protocols/ace/RMCast/RMCast_Membership.cpp b/protocols/ace/RMCast/RMCast_Membership.cpp index 8ab58d84475..6ee2690a41f 100644 --- a/protocols/ace/RMCast/RMCast_Membership.cpp +++ b/protocols/ace/RMCast/RMCast_Membership.cpp @@ -18,11 +18,13 @@ ACE_RMCast_Membership::~ACE_RMCast_Membership (void) int ACE_RMCast_Membership::ack (ACE_RMCast::Ack &ack) { + // ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack\n")); Proxy_Iterator end = this->proxies_.end (); Proxy_Iterator i = this->proxies_.begin (); if (i == end) return 0; + // ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[2]\n")); ACE_RMCast::Ack next_ack; { ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); @@ -30,11 +32,13 @@ ACE_RMCast_Membership::ack (ACE_RMCast::Ack &ack) { // @@ This violates an invariant of the class, shouldn't // happen... + // ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[3]\n")); return -1; } else if (ack.highest_in_sequence == this->highest_in_sequence_) { // Nothing new, just continue.... + // ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[4]\n")); return 0; } // Possible update, re-evaluate the story... @@ -52,12 +56,15 @@ ACE_RMCast_Membership::ack (ACE_RMCast::Ack &ack) if (r > highest_received) highest_received = r; } +#if 0 if (this->highest_in_sequence_ >= highest_in_sequence - || this->highest_received_ < highest_received) + || this->highest_received_ >= highest_received) { // No change.... + // ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[5]\n")); return 0; } +#endif /* 0 */ this->highest_in_sequence_ = highest_in_sequence; this->highest_received_ = highest_received; if (this->next () == 0) @@ -84,10 +91,7 @@ ACE_RMCast_Membership::join (ACE_RMCast::Join &join) return -1; } - if (this->next () == 0) - return 0; - - return this->next ()->join (join); + return this->ACE_RMCast_Module::join (join); } int @@ -98,18 +102,16 @@ ACE_RMCast_Membership::leave (ACE_RMCast::Leave &leave) { ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - if (this->proxies_.remove (leave.source) == -1) - return 0; + (void) this->proxies_.remove (leave.source); } - if (this->next () == 0) - return 0; - - return this->next ()->leave (leave); + return this->ACE_RMCast_Module::leave (leave); } #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_Unbounded_Set<ACE_RMCast_Proxy*>; +template class ACE_Unbounded_Set_Iterator<ACE_RMCast_Proxy*>; +template class ACE_Node<ACE_RMCast_Proxy*>; #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/protocols/ace/RMCast/RMCast_Module.h b/protocols/ace/RMCast/RMCast_Module.h index 9f83c2d5be4..dc4077fa4ab 100644 --- a/protocols/ace/RMCast/RMCast_Module.h +++ b/protocols/ace/RMCast/RMCast_Module.h @@ -27,51 +27,66 @@ class ACE_Message_Block; class ACE_Time_Value; +//! Reliable Multicast Module +/*! + The reliable multicast protocol is implemented as a stack of + "Modules" each one performing one specific task. In short, this is + an instance of the pipes-and-filters architectural pattern. +*/ class ACE_RMCast_Export ACE_RMCast_Module { - // = TITLE - // Reliable Multicast Module - // - // = DESCRIPTION - // The reliable multicast protocol is implemented as a stack of - // "Modules" each one performing one specific task. - // In short, this is an instance of the pipes-and-filters - // architectural pattern. - // public: // = Initialization and termination methods. ACE_RMCast_Module (void); - // Constructor + //!< Constructor virtual ~ACE_RMCast_Module (void); - // Destructor + //!< Destructor virtual int next (ACE_RMCast_Module *next); + //!< Modifier for the next element in the stack + virtual ACE_RMCast_Module* next (void) const; + //!< Accesor for the next element in the stack + virtual int prev (ACE_RMCast_Module *prev); + //!< Modifier for the previous element in the stack + virtual ACE_RMCast_Module* prev (void) const; - // Modifiers and accessors for the previous and next module in the - // stack + //!< Accesor for the previous element in the stack virtual int open (void); - // Initialize the module, setting up the next module + //!< Initialize the module, setting up the next module virtual int close (void); - // Close the module. + //!< Close the module. virtual int data (ACE_RMCast::Data &); + //!< Push data through the stack + virtual int poll (ACE_RMCast::Poll &); + //!< Push a polling request through the stack + virtual int ack_join (ACE_RMCast::Ack_Join &); + //!< Push a message to ack a join request through the stack + virtual int ack_leave (ACE_RMCast::Ack_Leave &); + //!< Push a message to ack a leave request through the stack + virtual int ack (ACE_RMCast::Ack &); + //!< Push an ack mesage through the stack + virtual int join (ACE_RMCast::Join &); + //!< Push a join message through the stack + virtual int leave (ACE_RMCast::Leave &); - // Push data down the stack + //!< Push a leave message through the stack private: + //! The next element in the stack ACE_RMCast_Module *next_; + //! The previous element in the stack ACE_RMCast_Module *prev_; - // The next and previous modules in the stack }; #if defined (__ACE_INLINE__) diff --git a/protocols/ace/RMCast/RMCast_Proxy.cpp b/protocols/ace/RMCast/RMCast_Proxy.cpp index 2a8b2ba40b4..53d9d0b6726 100644 --- a/protocols/ace/RMCast/RMCast_Proxy.cpp +++ b/protocols/ace/RMCast/RMCast_Proxy.cpp @@ -25,3 +25,11 @@ ACE_RMCast_Proxy::highest_received (void) const { return this->highest_received_; } + +int +ACE_RMCast_Proxy::ack (ACE_RMCast::Ack &ack) +{ + this->highest_in_sequence_ = ack.highest_in_sequence; + this->highest_received_ = ack.highest_received; + return this->ACE_RMCast_Module::ack (ack); +} diff --git a/protocols/ace/RMCast/RMCast_Proxy.h b/protocols/ace/RMCast/RMCast_Proxy.h index dca6494e374..414b74174fb 100644 --- a/protocols/ace/RMCast/RMCast_Proxy.h +++ b/protocols/ace/RMCast/RMCast_Proxy.h @@ -27,28 +27,48 @@ class ACE_Message_Block; class ACE_Time_Value; +//! Local representation for remote peers +/*! + Both senders and receivers in the multicast group need to maintain + explicit representations of their "peers". For example, a sender + needs to know the list of all the receivers and what messages they + have reported as successfully received. + Likewise, the receiver needs to maintain separate state for each + remote sender, and must be able to disconnect from all of them + gracefully when needed. + The RMCast_Proxy class is an opaque representation of such a peer, + and hides all the networking details from the rest of the system. +*/ class ACE_RMCast_Export ACE_RMCast_Proxy : public ACE_RMCast_Module { - // = TITLE - // Reliable Multicast Proxy - // - // = DESCRIPTION - // The proxy is used to send back messages to either a single - // receiver (o supplier). - // public: - // = Initialization and termination methods. + //! Constructor ACE_RMCast_Proxy (void); // Constructor + //! Destructor virtual ~ACE_RMCast_Proxy (void); - // Destructor + //! Return the highest sequence number received without any losses + //! before it. Only applies to remote receiver proxies. + /*! + Please read the documentation in ACE_RMCast::Ack + */ virtual ACE_UINT32 highest_in_sequence (void) const; + + //! Return the highest sequence number successfully received. + //! Only applies to remote receiver proxies. + /*! + Please read the documentation in ACE_RMCast::Ack + */ virtual ACE_UINT32 highest_received (void) const; - // Get the sequence numbers received by the remote proxy. - // Return 0 for sender proxies + //@{ + //! Send messages directly to the peer. + /*! Send a message directly to the peer, i.e. the message is not + sent through the multicast group and it may not be processed by + all the layers in the stack. + */ virtual int reply_data (ACE_RMCast::Data &) = 0; virtual int reply_poll (ACE_RMCast::Poll &) = 0; virtual int reply_ack_join (ACE_RMCast::Ack_Join &) = 0; @@ -56,16 +76,21 @@ public: virtual int reply_ack (ACE_RMCast::Ack &) = 0; virtual int reply_join (ACE_RMCast::Join &) = 0; virtual int reply_leave (ACE_RMCast::Leave &) = 0; - // Push data back to the remote proxy + //@} - // = The RMCast_Module methods + /*! + Proxies process the ACK sequence numbers to save the sequence + numbers reported from the remote peer. + */ virtual int ack (ACE_RMCast::Ack &); private: + //@{ + //! Cache the sequence numbers reported from the remote peer using + //! Ack messages ACE_UINT32 highest_in_sequence_; ACE_UINT32 highest_received_; - // Cache the sequence numbers reported from the remote peer using - // Ack messages + //@} }; #if defined (__ACE_INLINE__) diff --git a/protocols/ace/RMCast/RMCast_Reassembly.cpp b/protocols/ace/RMCast/RMCast_Reassembly.cpp index ba2e9b79c1a..ed488341bae 100644 --- a/protocols/ace/RMCast/RMCast_Reassembly.cpp +++ b/protocols/ace/RMCast/RMCast_Reassembly.cpp @@ -22,6 +22,10 @@ ACE_RMCast_Reassembly (void) ACE_RMCast_Reassembly::~ACE_RMCast_Reassembly (void) { + /*!< + We cleanup the resources in the destructor + <B color=red>@@ TODO</B> Why not in the close() operation? + */ for (Message_Map_Iterator i = this->messages_.begin (); i != this->messages_.end (); ++i) @@ -87,6 +91,7 @@ ACE_RMCast_Reassembly::data (ACE_RMCast::Data &data) // Push the message... ACE_RMCast::Data downstream_data; + downstream_data.source = data.source; downstream_data.sequence_number = data.sequence_number; downstream_data.total_size = message->message_body ()->length (); downstream_data.fragment_offset = 0; diff --git a/protocols/ace/RMCast/RMCast_Reassembly.h b/protocols/ace/RMCast/RMCast_Reassembly.h index 0bf0c3a61ee..6dc37e1ae19 100644 --- a/protocols/ace/RMCast/RMCast_Reassembly.h +++ b/protocols/ace/RMCast/RMCast_Reassembly.h @@ -24,19 +24,28 @@ class ACE_RMCast_Partial_Message; +//! Reassemble multiple data fragments into a single data message +/*! + Data messages may not fit in a single MTU in the transport layer, in + that case the application configure a RMCast_Fragment module on the + sender side. On the receiver side this layer reassemble the + messages sent from a <EM>single</EM> source, and passes the messages + up the stream. +*/ class ACE_RMCast_Export ACE_RMCast_Reassembly : public ACE_RMCast_Module { public: + //! Constructor ACE_RMCast_Reassembly (void); - // Constructor + //! Destructor virtual ~ACE_RMCast_Reassembly (void); - // Destructor // = The ACE_RMCast_Module methods virtual int data (ACE_RMCast::Data &data); private: + //! A mutex used to synchronize all the internal operations. ACE_SYNCH_MUTEX mutex_; typedef ACE_Hash_Map_Manager<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Null_Mutex> @@ -45,8 +54,9 @@ private: ACE_Hash_Map_Iterator<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Null_Mutex> Message_Map_Iterator; + //! A map, indexed by sequence number, of the partially received + //! messages. Message_Map messages_; - // The array of partially received messages }; #if defined (__ACE_INLINE__) diff --git a/protocols/ace/RMCast/RMCast_Retransmission.cpp b/protocols/ace/RMCast/RMCast_Retransmission.cpp index b90cf0ddf31..a996e1204d5 100644 --- a/protocols/ace/RMCast/RMCast_Retransmission.cpp +++ b/protocols/ace/RMCast/RMCast_Retransmission.cpp @@ -96,6 +96,9 @@ ACE_RMCast_Retransmission::ack (ACE_RMCast::Ack &ack) #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_RB_Tree<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex>; +template class ACE_RB_Tree_Iterator_Base<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex>; template class ACE_RB_Tree_Iterator<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex>; +template class ACE_RB_Tree_Reverse_Iterator<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex>; +template class ACE_RB_Tree_Node<ACE_UINT32,ACE_RMCast::Data>; #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ |