summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorcoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-09-27 15:26:53 +0000
committercoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-09-27 15:26:53 +0000
commitfe63d7b28e1ca4d3813e4adf599540800fc9efa8 (patch)
tree30e1b983270bb179ebb28185703e24c2f8361d4f /protocols
parent7e8b3a0398969ba6398b98128dd211d9e1593160 (diff)
downloadATCD-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/Makefile6
-rw-r--r--protocols/ace/RMCast/RMCast.h292
-rw-r--r--protocols/ace/RMCast/RMCast_Membership.cpp24
-rw-r--r--protocols/ace/RMCast/RMCast_Module.h49
-rw-r--r--protocols/ace/RMCast/RMCast_Proxy.cpp8
-rw-r--r--protocols/ace/RMCast/RMCast_Proxy.h55
-rw-r--r--protocols/ace/RMCast/RMCast_Reassembly.cpp5
-rw-r--r--protocols/ace/RMCast/RMCast_Reassembly.h16
-rw-r--r--protocols/ace/RMCast/RMCast_Retransmission.cpp3
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 */