diff options
author | Ossama Othman <ossama-othman@users.noreply.github.com> | 2005-02-11 16:44:28 +0000 |
---|---|---|
committer | Ossama Othman <ossama-othman@users.noreply.github.com> | 2005-02-11 16:44:28 +0000 |
commit | b7574d650a11bcac003e4bd7c09b90c97a0f4cf7 (patch) | |
tree | 06681716b6e03e1ec2fd991f63f9c8228f7fdef1 | |
parent | c57ab4efd3a27b32548da59b13bae3af0ebbe05f (diff) | |
download | ATCD-b7574d650a11bcac003e4bd7c09b90c97a0f4cf7.tar.gz |
ChangeLogTag:Fri Feb 11 08:43:04 2005 Ossama Othman <ossama@dre.vanderbilt.edu>
202 files changed, 4784 insertions, 13440 deletions
diff --git a/ChangeLog b/ChangeLog index cae21d4dd9c..202f0a7d630 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,127 @@ +Fri Feb 11 08:43:04 2005 Ossama Othman <ossama@dre.vanderbilt.edu> + + * ace/RMCast/Makefile.am: + * ace/RMCast/RMCast.cpp: + * ace/RMCast/RMCast.h: + * ace/RMCast/RMCast.rc: + * ace/RMCast/RMCast_Ack_Worker.cpp: + * ace/RMCast/RMCast_Ack_Worker.h: + * ace/RMCast/RMCast_Ack_Worker.i: + * ace/RMCast/RMCast_Copy_On_Write.cpp: + * ace/RMCast/RMCast_Copy_On_Write.h: + * ace/RMCast/RMCast_Copy_On_Write.i: + * ace/RMCast/RMCast_Export.h: + * ace/RMCast/RMCast_Fork.cpp: + * ace/RMCast/RMCast_Fork.h: + * ace/RMCast/RMCast_Fork.i: + * ace/RMCast/RMCast_Fragment.cpp: + * ace/RMCast/RMCast_Fragment.h: + * ace/RMCast/RMCast_Fragment.i: + * ace/RMCast/RMCast_IO_UDP.cpp: + * ace/RMCast/RMCast_IO_UDP.h: + * ace/RMCast/RMCast_IO_UDP.i: + * ace/RMCast/RMCast_Membership.cpp: + * ace/RMCast/RMCast_Membership.h: + * ace/RMCast/RMCast_Membership.i: + * ace/RMCast/RMCast_Module.cpp: + * ace/RMCast/RMCast_Module.h: + * ace/RMCast/RMCast_Module.i: + * ace/RMCast/RMCast_Module_Factory.cpp: + * ace/RMCast/RMCast_Module_Factory.h: + * ace/RMCast/RMCast_Partial_Message.cpp: + * ace/RMCast/RMCast_Partial_Message.h: + * ace/RMCast/RMCast_Partial_Message.i: + * ace/RMCast/RMCast_Proxy.cpp: + * ace/RMCast/RMCast_Proxy.h: + * ace/RMCast/RMCast_Proxy.i: + * ace/RMCast/RMCast_Reassembly.cpp: + * ace/RMCast/RMCast_Reassembly.h: + * ace/RMCast/RMCast_Receiver_Module.cpp: + * ace/RMCast/RMCast_Receiver_Module.h: + * ace/RMCast/RMCast_Receiver_Module.i: + * ace/RMCast/RMCast_Reliable_Factory.cpp: + * ace/RMCast/RMCast_Reliable_Factory.h: + * ace/RMCast/RMCast_Reliable_Factory.i: + * ace/RMCast/RMCast_Reordering.cpp: + * ace/RMCast/RMCast_Reordering.h: + * ace/RMCast/RMCast_Reordering.i: + * ace/RMCast/RMCast_Resend_Handler.cpp: + * ace/RMCast/RMCast_Resend_Handler.h: + * ace/RMCast/RMCast_Resend_Handler.i: + * ace/RMCast/RMCast_Resend_Worker.cpp: + * ace/RMCast/RMCast_Resend_Worker.h: + * ace/RMCast/RMCast_Resend_Worker.i: + * ace/RMCast/RMCast_Retransmission.cpp: + * ace/RMCast/RMCast_Retransmission.h: + * ace/RMCast/RMCast_Retransmission.i: + * ace/RMCast/RMCast_Sequencer.cpp: + * ace/RMCast/RMCast_Sequencer.h: + * ace/RMCast/RMCast_Sequencer.i: + * ace/RMCast/RMCast_Singleton_Factory.cpp: + * ace/RMCast/RMCast_Singleton_Factory.h: + * ace/RMCast/RMCast_Singleton_Factory.i: + * ace/RMCast/RMCast_UDP_Event_Handler.cpp: + * ace/RMCast/RMCast_UDP_Event_Handler.h: + * ace/RMCast/RMCast_UDP_Event_Handler.i: + * ace/RMCast/RMCast_UDP_Proxy.cpp: + * ace/RMCast/RMCast_UDP_Proxy.h: + * ace/RMCast/RMCast_UDP_Proxy.i: + * ace/RMCast/RMCast_UDP_Reliable_Receiver.cpp: + * ace/RMCast/RMCast_UDP_Reliable_Receiver.h: + * ace/RMCast/RMCast_UDP_Reliable_Receiver.i: + * ace/RMCast/RMCast_UDP_Reliable_Sender.cpp: + * ace/RMCast/RMCast_UDP_Reliable_Sender.h: + * ace/RMCast/RMCast_UDP_Reliable_Sender.i: + * ace/RMCast/RMCast_Worker.cpp: + * ace/RMCast/RMCast_Worker.h: + * examples/RMCast/Makefile.am: + * examples/RMCast/Send_File/Makefile.am: + * examples/RMCast/Send_File/RMCast_Send_File.mpc: + * examples/RMCast/Send_File/Receiver.cpp: + * examples/RMCast/Send_File/Sender.cpp: + * tests/RMCast/Main.cpp: + * tests/RMCast/Makefile.am: + * tests/RMCast/RMCast_Fragment_Test.cpp: + * tests/RMCast/RMCast_Membership_Test.cpp: + * tests/RMCast/RMCast_Reassembly_Test.cpp: + * tests/RMCast/RMCast_Reordering_Test.cpp: + * tests/RMCast/RMCast_Retransmission_Test.cpp: + * tests/RMCast/RMCast_UDP_Best_Effort_Test.cpp: + * tests/RMCast/acetest.mpb: + * tests/RMCast/tests.mpc: + + Removed old ACE reliable multicast implementation. It is not + maintained, and is now superseded by Boris's implementation + described below. + + From Boris Kolpkacov <boris at kolpackov dot net> + * ace/RMCast/Acknowledge.cpp: + * ace/RMCast/Acknowledge.h: + * ace/RMCast/Agent.tar.bz2: + * ace/RMCast/Bits.h: + * ace/RMCast/Link.cpp: + * ace/RMCast/Link.h: + * ace/RMCast/Protocol.cpp: + * ace/RMCast/Protocol.h: + * ace/RMCast/RMCast.mpc: + * ace/RMCast/Retransmit.cpp: + * ace/RMCast/Retransmit.h: + * ace/RMCast/Simulator.cpp: + * ace/RMCast/Simulator.h: + * ace/RMCast/Socket.cpp: + * ace/RMCast/Socket.h: + * ace/RMCast/Stack.cpp: + * ace/RMCast/Stack.h: + * examples/RMCast/Send_Msg/Protocol.h: + * examples/RMCast/Send_Msg/README: + * examples/RMCast/Send_Msg/Receiver.cpp: + * examples/RMCast/Send_Msg/Send_Msg.mpc: + * examples/RMCast/Send_Msg/Sender.cpp: + + New reliable source-ordered multicast protocol implementation + for message-oriented multi-sender group communication built on + top of IPv4 multicast. + Fri Feb 11 16:01:37 2005 Martin Corino <mcorino@remedy.nl> * tests/Thread_Pool_Reactor_Test.cpp: diff --git a/ace/RMCast/Acknowledge.cpp b/ace/RMCast/Acknowledge.cpp new file mode 100644 index 00000000000..e0d7ce6f376 --- /dev/null +++ b/ace/RMCast/Acknowledge.cpp @@ -0,0 +1,315 @@ +// file : ace/RMCast/Acknowledge.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/OS.h> + +#include <ace/RMCast/Acknowledge.h> + +namespace ACE_RMCast +{ + ACE_Time_Value const tick (0, 5000); + unsigned long const nak_timeout = 20; // # of ticks. + unsigned long const nrtm_timeout = 50; // # of ticks. + + Acknowledge:: + Acknowledge () + : nrtm_timer_ (nrtm_timeout) + { + } + + void Acknowledge:: + in_start (In_Element* in) + { + Element::in_start (in); + } + + void Acknowledge:: + out_start (Out_Element* out) + { + Element::out_start (out); + + tracker_mgr_.spawn (track_thunk, this); + } + + void Acknowledge:: + out_stop () + { + tracker_mgr_.cancel_all (1); + tracker_mgr_.wait (); + + Element::out_stop (); + } + + void Acknowledge:: + collapse (Queue& q) + { + // I would normally use iterators in the logic below but ACE_Map_Manager + // iterates over entries in no particular order so it is pretty much + // unusable here. Instead we will do slow and cumbersome find's. + // + + u64 sn (q.sn () + 1); + + for (;; ++sn) + { + Queue::ENTRY* e; + + if (q.find (sn, e) == -1 || e->int_id_.lost ()) break; + + Message_ptr m (e->int_id_.msg ()); + q.unbind (sn); + + in_->recv (m); + } + + q.sn (sn - 1); + } + + void Acknowledge:: + track () + { + while (true) + { + Messages msgs; + + { + Lock l (mutex_); + + if (hold_.current_size () != 0) + { + for (Map::iterator i (hold_.begin ()), e (hold_.end ()); + i != e; + ++i) + { + Queue& q ((*i).int_id_); + + if (q.current_size () == 0) continue; + + track_queue ((*i).ext_id_, q, msgs); + } + } + + if (--nrtm_timer_ == 0) + { + nrtm_timer_ = nrtm_timeout; + + // Send NRTM. + // + Profile_ptr nrtm (create_nrtm ()); + + if (nrtm.get ()) + { + Message_ptr m (new Message); + m->add (nrtm); + msgs.push_back (m); + + } + } + } + + // Send stuff off. + // + for (Messages::Iterator i (msgs); !i.done (); i.advance ()) + { + Message_ptr* ppm; + i.next (ppm); + send (*ppm); + } + + ACE_OS::sleep (tick); + } + } + + void Acknowledge:: + track_queue (Address const& addr, Queue& q, Messages& msgs) + { + NAK_ptr nak (new NAK (addr)); + + // Track existing losses. + // + for (Queue::iterator i (q.begin ()), e (q.end ()); i != e; ++i) + { + u64 sn ((*i).ext_id_); + Descr& d ((*i).int_id_); + + if (d.lost ()) + { + d.timer (d.timer () - 1); + + if (d.timer () == 0) + { + //@@ Need exp fallback. + // + d.nak_count (d.nak_count () + 1); + d.timer ((d.nak_count () + 1) * nak_timeout); + + nak->add (sn); + + //cerr << 6 << "NAK # " << d.nak_count () << ": " + // << addr << " " << sn << endl; + } + } + } + + // Send NAK. + // + if (nak->count ()) + { + // cerr << 5 << "NAK: " << addr << " " << nak->count () << " sns" + // << endl; + + Message_ptr m (new Message); + + m->add (Profile_ptr (nak.release ())); + + msgs.push_back (m); + } + + // Detect and record new losses. + // + for (u64 sn (q.sn () + 1), end (q.max_sn ()); sn < end; ++sn) + { + if (q.find (sn) == -1) + { + q.bind (sn, Descr (1)); + } + } + } + + void Acknowledge:: + recv (Message_ptr m) + { + // Handle NRTM. There could be some nasty interaction with code + // that handles data below (like missing message and NAK). This + // is why I hold the lock at the beginning (which may be not very + // efficient). + // + Lock l (mutex_); + + if (NRTM const* nrtm = static_cast<NRTM const*> (m->find (NRTM::id))) + { + for (Map::iterator i (hold_.begin ()), e (hold_.end ()); i != e; ++i) + { + u64 sn (nrtm->find ((*i).ext_id_)); + + if (sn != 0) + { + Queue& q ((*i).int_id_); + + u64 old (q.max_sn ()); + + if (old < sn) + { + // Mark as lost. + // + q.bind (sn, Descr (1)); + } + } + } + } + + if (m->find (Data::id)) + { + Address from ( + static_cast<From const*> (m->find (From::id))->address ()); + + u64 sn (static_cast<SN const*> (m->find (SN::id))->num ()); + + Map::ENTRY* e; + + if (hold_.find (from, e) == -1) + { + // First message from this source. + // + hold_.bind (from, Queue (sn)); + hold_.find (from, e); + + in_->recv (m); + } + else + { + Queue& q (e->int_id_); + + if (sn <= q.sn ()) + { + // Duplicate. + // + //cerr << 6 << "DUP " << from << " " << q.sn () << " >= " << sn + // << endl; + } + else if (sn == q.sn () + 1) + { + // Next message. + // + + q.rebind (sn, Descr (m)); + collapse (q); + } + else + { + // Some messages are missing. Insert this one into the queue. + // + q.rebind (sn, Descr (m)); + } + } + } + else + { + l.release (); + + // Just forward it up. + // + in_->recv (m); + } + } + + void Acknowledge:: + send (Message_ptr m) + { + if (m->find (Data::id) != 0) + { + Lock l (mutex_); + + Profile_ptr nrtm (create_nrtm ()); + + if (nrtm.get ()) m->add (nrtm); + + nrtm_timer_ = nrtm_timeout; // Reset timer. + } + + out_->send (m); + } + + Profile_ptr Acknowledge:: + create_nrtm () + { + // Prepare NRTM. + // + NRTM_ptr nrtm (new NRTM ()); + + // Gather the information. + // + { + for (Map::iterator i (hold_.begin ()), e (hold_.end ()); i != e; ++i) + { + Address addr ((*i).ext_id_); + Queue& q ((*i).int_id_); + + //@@ Should look for the highest known number. + // + nrtm->insert (addr, q.sn ()); + } + } + + if (nrtm->empty ()) return 0; + else return Profile_ptr (nrtm.release ()); + } + + ACE_THR_FUNC_RETURN Acknowledge:: + track_thunk (void* obj) + { + reinterpret_cast<Acknowledge*> (obj)->track (); + return 0; + } +} diff --git a/ace/RMCast/Acknowledge.h b/ace/RMCast/Acknowledge.h new file mode 100644 index 00000000000..4289ec729db --- /dev/null +++ b/ace/RMCast/Acknowledge.h @@ -0,0 +1,234 @@ +// file : ace/RMCast/Acknowledge.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_ACKNOWLEDGE_H +#define ACE_RMCAST_ACKNOWLEDGE_H + +#include <ace/Hash_Map_Manager.h> +#include <ace/Thread_Manager.h> + +#include <ace/RMCast/Stack.h> +#include <ace/RMCast/Protocol.h> +#include <ace/RMCast/Bits.h> + +namespace ACE_RMCast +{ + class Acknowledge : public Element + { + public: + Acknowledge (); + + virtual void + in_start (In_Element* in); + + virtual void + out_start (Out_Element* out); + + virtual void + out_stop (); + + public: + virtual void + recv (Message_ptr m); + + virtual void + send (Message_ptr m); + + private: + struct Descr + { + //@@ There should be no default c-tor. + // + Descr () + : nak_count_ (0), timer_ (1) + { + } + + Descr (unsigned long timer) + : nak_count_ (0), timer_ (timer) + { + } + + Descr (Message_ptr m) + : m_ (m) + { + } + + public: + bool + lost () const + { + return m_.get () == 0; + } + + public: + Message_ptr + msg () + { + return m_; + } + + void + msg (Message_ptr m) + { + m_ = m; + } + + public: + unsigned long + nak_count () const + { + return nak_count_; + } + + void + nak_count (unsigned long v) + { + nak_count_ = v; + } + + unsigned long + timer () const + { + return timer_; + } + + void + timer (unsigned long v) + { + timer_ = v; + } + + private: + Message_ptr m_; + + unsigned long nak_count_; + unsigned long timer_; + }; + + struct Queue : ACE_Hash_Map_Manager<u64, Descr, ACE_Null_Mutex> + { + typedef ACE_Hash_Map_Manager<u64, Descr, ACE_Null_Mutex> Base; + + // Should never be here but required by ACE_Hash_Blah_Blah. + // + Queue () + : Base (), sn_ (0), max_sn_ (0) + { + } + + Queue (u64 sn) + : Base (), sn_ (sn), max_sn_ (sn) + { + } + + Queue (Queue const& q) + : Base (), sn_ (q.sn_), max_sn_ (sn_) + { + for (Queue::const_iterator i (q), e (q, 1); i != e; ++i) + { + bind ((*i).ext_id_, (*i).int_id_); + } + } + + public: + int + bind (u64 sn, Descr const& d) + { + int r (Base::bind (sn, d)); + + if (r == 0 && sn > max_sn_) max_sn_ = sn; + + return r; + } + + int + rebind (u64 sn, Descr const& d) + { + int r (Base::rebind (sn, d)); + + if (r == 0 && sn > max_sn_) max_sn_ = sn; + + return r; + } + + int + unbind (u64 sn) + { + int r (Base::unbind (sn)); + + if (r == 0 && sn == max_sn_) + { + for (--max_sn_; max_sn_ >= sn_; --max_sn_) + { + if (find (max_sn_) == 0) break; + } + } + + return r; + } + + public: + u64 + sn () const + { + return sn_; + } + + void + sn (u64 sn) + { + sn_ = sn; + } + + u64 + max_sn () const + { + if (current_size () == 0) return sn_; + + return max_sn_; + } + + private: + u64 sn_, max_sn_; + }; + + typedef + ACE_Hash_Map_Manager_Ex<Address, + Queue, + AddressHasher, + ACE_Equal_To<Address>, + ACE_Null_Mutex> + Map; + + private: + void + collapse (Queue& q); + + void + track (); + + void + track_queue (Address const& addr, Queue& q, Messages& msgs); + + Profile_ptr + create_nrtm (); + + static ACE_THR_FUNC_RETURN + track_thunk (void* obj); + + private: + Map hold_; + Mutex mutex_; + + unsigned long nrtm_timer_; + + ACE_Thread_Manager tracker_mgr_; + }; + + + +} + +#endif // ACE_RMCAST_ACKNOWLEDGE_H diff --git a/ace/RMCast/Agent.tar.bz2 b/ace/RMCast/Agent.tar.bz2 Binary files differnew file mode 100644 index 00000000000..173776420d9 --- /dev/null +++ b/ace/RMCast/Agent.tar.bz2 diff --git a/ace/RMCast/Bits.h b/ace/RMCast/Bits.h new file mode 100644 index 00000000000..0c1090910ce --- /dev/null +++ b/ace/RMCast/Bits.h @@ -0,0 +1,28 @@ +// file : ace/RMCast/Bits.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_BITS_H +#define ACE_RMCAST_BITS_H + +#include <ace/Synch.h> +#include <ace/Auto_Ptr.h> + +//#include <iostream> + +namespace ACE_RMCast +{ + typedef ACE_Thread_Mutex Mutex; + typedef ACE_Guard<Mutex> Lock; + typedef ACE_Condition<Mutex> Condition; + + using ::auto_ptr; // ACE auto_ptr. + + // tmp + // + //using std::cerr; + //using std::endl; +} + + +#endif // ACE_RMCAST_BITS_H diff --git a/ace/RMCast/Link.cpp b/ace/RMCast/Link.cpp new file mode 100644 index 00000000000..e6898cfd76c --- /dev/null +++ b/ace/RMCast/Link.cpp @@ -0,0 +1,271 @@ +// file : ace/RMCast/Link.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/RMCast/Link.h> + +namespace ACE_RMCast +{ + Link:: + Link (Address const& addr) + : addr_ (addr), + ssock_ (Address ((unsigned short) (0), INADDR_ANY), + AF_INET, + IPPROTO_UDP, + 1) + + { + srand (time (0)); + + + rsock_.set_option (IP_MULTICAST_LOOP, 0); + + // Set recv/send buffers. + // + { + int r (131070); + int s (sizeof (r)); + + static_cast<ACE_SOCK&> (rsock_).set_option ( + SOL_SOCKET, SO_RCVBUF, &r, s); + + static_cast<ACE_SOCK&> (ssock_).set_option ( + SOL_SOCKET, SO_RCVBUF, &r, s); + + rsock_.get_option (SOL_SOCKET, SO_RCVBUF, &r, &s); + //cerr << 5 << "recv buffer size: " << r << endl; + + ssock_.get_option (SOL_SOCKET, SO_RCVBUF, &r, &s); + //cerr << 5 << "send buffer size: " << r << endl; + + } + + // Bind address and port. + // + if (ACE_OS::connect (ssock_.get_handle (), + reinterpret_cast<sockaddr*> (addr_.get_addr ()), + addr_.get_addr_size ()) == -1) + { + perror ("connect: "); + abort (); + } + + + ssock_.get_local_addr (self_); + + //cerr << 5 << "self: " << self_ << endl; + } + + void Link:: + in_start (In_Element* in) + { + Element::in_start (in); + + rsock_.join (addr_); + + // Start receiving thread. + // + recv_mgr_.spawn (recv_thunk, this); + } + + void Link:: + out_start (Out_Element* out) + { + Element::out_start (out); + } + + void Link:: + in_stop () + { + // Stop receiving thread. + // + recv_mgr_.cancel_all (1); + recv_mgr_.wait (); + + Element::in_stop (); + } + + void Link:: + send (Message_ptr m) + { + bool const sim = false; + + // Simulate message loss and reordering. + // + if (sim) + { + if ((rand () % 5) != 0) + { + Lock l (mutex_); + + if (hold_.get ()) + { + send_ (m); + send_ (hold_); + hold_ = 0; + } + else + { + hold_ = m; + + // Make a copy in M so that the reliable loop below + // won't add FROM and TO to HOLD_. + // + m = Message_ptr (new Message (*hold_)); + } + } + } + else + send_ (m); + + // Reliable loop. + // + m->add (Profile_ptr (new From (self_))); + m->add (Profile_ptr (new To (self_))); + + in_->recv (m); + } + + void Link:: + send_ (Message_ptr m) + { + ostream os (m->size (), 1); // Always little-endian. + + os << *m; + + ssock_.send (os.buffer (), os.length (), addr_); + + /* + if (m->find (nrtm::id)) + { + write (1, os.buffer (), os.length ()); + exit (1); + } + */ + } + + void Link:: + recv () + { + // I could have used ACE_Data_Block but it does not support + // resizing... + // + size_t size (0), capacity (8192); + char* data (reinterpret_cast<char*> (operator new (capacity))); + + auto_ptr<char> holder (data); // This is wicked. + + while (true) + { + //@@ Should I lock here? + // + + Address addr; + + //@@ CDR-specific. + // + size = rsock_.recv (data, 4, addr, MSG_PEEK); + + if (size != 4 || addr == self_) + { + // Discard bad messages and ones from ourselvs since + // we are using reliable loopback. + // + rsock_.recv (data, 0, addr); + continue; + } + + u32 msg_size; + { + istream is (data, size, 1); // Always little-endian. + is >> msg_size; + } + + if (msg_size <= 4) + { + // Bad message. + // + rsock_.recv (data, 0, addr); + continue; + } + + if (capacity < msg_size) + { + capacity = msg_size; + holder = auto_ptr<char> (0); + data = reinterpret_cast<char*> (operator new (capacity)); + holder = auto_ptr<char> (data); + } + + size = rsock_.recv (data, capacity, addr); + + if (msg_size != size) + { + // Bad message. + // + continue; + } + + //cerr << 6 << "from: " << addr << endl; + + Message_ptr m (new Message ()); + + m->add (Profile_ptr (new From (addr))); + m->add (Profile_ptr (new To (self_))); + + istream is (data, size, 1); // Always little-endian. + + is >> msg_size; + + while (true) + { + u16 id, size; + + if (!((is >> id) && (is >> size))) break; + + //cerr << 6 << "reading profile with id " << id << " " + // << size << " bytes long" << endl; + + Profile::Header hdr (id, size); + + switch (hdr.id ()) + { + case SN::id: + { + m->add (Profile_ptr (new SN (hdr, is))); + break; + } + case Data::id: + { + m->add (Profile_ptr (new Data (hdr, is))); + break; + } + case NAK::id: + { + m->add (Profile_ptr (new NAK (hdr, is))); + break; + } + case NRTM::id: + { + m->add (Profile_ptr (new NRTM (hdr, is))); + break; + } + default: + { + //cerr << 0 << "unknown profile id " << hdr.id () << endl; + abort (); + } + } + } + + in_->recv (m); + } + } + + ACE_THR_FUNC_RETURN Link:: + recv_thunk (void* obj) + { + reinterpret_cast<Link*> (obj)->recv (); + return 0; + } +} diff --git a/ace/RMCast/Link.h b/ace/RMCast/Link.h new file mode 100644 index 00000000000..e6e66bbbd80 --- /dev/null +++ b/ace/RMCast/Link.h @@ -0,0 +1,62 @@ +// file : ace/RMCast/Link.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_LINK_H +#define ACE_RMCAST_LINK_H + +#include <ace/SOCK_Dgram.h> +#include <ace/SOCK_Dgram_Mcast.h> + +#include <ace/Thread_Manager.h> + +#include <ace/RMCast/Stack.h> +#include <ace/RMCast/Protocol.h> + +namespace ACE_RMCast +{ + class Link : public Element + { + public: + Link (Address const& addr); + + virtual void + in_start (In_Element* in); + + virtual void + out_start (Out_Element* out); + + virtual void + in_stop (); + + public: + virtual void + send (Message_ptr m); + + private: + virtual void + send_ (Message_ptr m); + + private: + void + recv (); + + static ACE_THR_FUNC_RETURN + recv_thunk (void* obj); + + private: + Address addr_, self_; + ACE_SOCK_Dgram_Mcast rsock_; + ACE_SOCK_Dgram ssock_; + + ACE_Thread_Manager recv_mgr_; + + // Simulator. + // + Message_ptr hold_; + Mutex mutex_; + }; +} + + +#endif // ACE_RMCAST_LINK_H diff --git a/ace/RMCast/Makefile.am b/ace/RMCast/Makefile.am deleted file mode 100644 index 78f36853be0..00000000000 --- a/ace/RMCast/Makefile.am +++ /dev/null @@ -1,127 +0,0 @@ -## Process this file with automake to create Makefile.in -## -## $Id$ -## -## This file was generated by MPC. Any changes made directly to -## this file will be lost the next time it is generated. -## -## MPC Command: -## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu - -includedir = @includedir@/ace/RMCast -pkgconfigdatadir = ${prefix}/lib/pkgconfig - -ACE_BUILDDIR = $(top_builddir) -ACE_ROOT = $(top_srcdir) - -nobase_include_HEADERS = -lib_LTLIBRARIES = -## Makefile.RMCast.am - -if BUILD_RMCAST -lib_LTLIBRARIES += libACE_RMCast.la - -libACE_RMCast_la_CPPFLAGS = \ - -I$(ACE_ROOT) \ - -I$(ACE_BUILDDIR) \ - -DACE_RMCAST_BUILD_DLL - -libACE_RMCast_la_SOURCES = \ - RMCast.cpp \ - RMCast_Ack_Worker.cpp \ - RMCast_Copy_On_Write.cpp \ - RMCast_Fork.cpp \ - RMCast_Fragment.cpp \ - RMCast_IO_UDP.cpp \ - RMCast_Membership.cpp \ - RMCast_Module.cpp \ - RMCast_Module_Factory.cpp \ - RMCast_Partial_Message.cpp \ - RMCast_Proxy.cpp \ - RMCast_Reassembly.cpp \ - RMCast_Receiver_Module.cpp \ - RMCast_Reliable_Factory.cpp \ - RMCast_Reordering.cpp \ - RMCast_Resend_Handler.cpp \ - RMCast_Resend_Worker.cpp \ - RMCast_Retransmission.cpp \ - RMCast_Sequencer.cpp \ - RMCast_Singleton_Factory.cpp \ - RMCast_UDP_Event_Handler.cpp \ - RMCast_UDP_Proxy.cpp \ - RMCast_UDP_Reliable_Receiver.cpp \ - RMCast_UDP_Reliable_Sender.cpp \ - RMCast_Worker.cpp - -libACE_RMCast_la_LDFLAGS = \ - -version-number @ACE_MAJOR@:@ACE_MINOR@:@ACE_BETA@ - -libACE_RMCast_la_LIBADD = \ - $(top_builddir)/ace/libACE.la - -nobase_include_HEADERS += \ - RMCast.h \ - RMCast_Ack_Worker.h \ - RMCast_Copy_On_Write.h \ - RMCast_Export.h \ - RMCast_Fork.h \ - RMCast_Fragment.h \ - RMCast_IO_UDP.h \ - RMCast_Membership.h \ - RMCast_Module.h \ - RMCast_Module_Factory.h \ - RMCast_Partial_Message.h \ - RMCast_Proxy.h \ - RMCast_Reassembly.h \ - RMCast_Receiver_Module.h \ - RMCast_Reliable_Factory.h \ - RMCast_Reordering.h \ - RMCast_Resend_Handler.h \ - RMCast_Resend_Worker.h \ - RMCast_Retransmission.h \ - RMCast_Sequencer.h \ - RMCast_Singleton_Factory.h \ - RMCast_UDP_Event_Handler.h \ - RMCast_UDP_Proxy.h \ - RMCast_UDP_Reliable_Receiver.h \ - RMCast_UDP_Reliable_Sender.h \ - RMCast_Worker.h \ - RMCast_Ack_Worker.i \ - RMCast_Copy_On_Write.i \ - RMCast_Fork.i \ - RMCast_Fragment.i \ - RMCast_IO_UDP.i \ - RMCast_Membership.i \ - RMCast_Module.i \ - RMCast_Partial_Message.i \ - RMCast_Proxy.i \ - RMCast_Receiver_Module.i \ - RMCast_Reliable_Factory.i \ - RMCast_Reordering.i \ - RMCast_Resend_Handler.i \ - RMCast_Resend_Worker.i \ - RMCast_Retransmission.i \ - RMCast_Sequencer.i \ - RMCast_Singleton_Factory.i \ - RMCast_UDP_Event_Handler.i \ - RMCast_UDP_Proxy.i \ - RMCast_UDP_Reliable_Receiver.i \ - RMCast_UDP_Reliable_Sender.i - -pkgconfigdata_DATA = ACE_RMCast.pc - -ACE_RMCast.pc: ${top_builddir}/config.status ACE_RMCast.pc.in - ${top_builddir}/config.status --file $@:${srcdir}/ACE_RMCast.pc.in - -endif BUILD_RMCAST - -EXTRA_DIST = \ - RMCast.rc - -## Clean up template repositories, etc. -clean-local: - -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* - -rm -f gcctemp.c gcctemp so_locations *.ics - -rm -rf cxx_repository ptrepository ti_files - -rm -rf templateregistry ir.out - -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ace/RMCast/Protocol.cpp b/ace/RMCast/Protocol.cpp new file mode 100644 index 00000000000..4082d6bd139 --- /dev/null +++ b/ace/RMCast/Protocol.cpp @@ -0,0 +1,9 @@ +// file : ace/RMCast/Protocol.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/RMCast/Protocol.h> + +namespace ACE_RMCast +{ +} diff --git a/ace/RMCast/Protocol.h b/ace/RMCast/Protocol.h new file mode 100644 index 00000000000..f9f2956920f --- /dev/null +++ b/ace/RMCast/Protocol.h @@ -0,0 +1,715 @@ +// file : ace/RMCast/Protocol.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_PROTOCOL_H +#define ACE_RMCAST_PROTOCOL_H + +#include <ace/Refcounted_Auto_Ptr.h> + +#include <ace/Vector_T.h> +#include <ace/Hash_Map_Manager.h> + +#include <ace/OS.h> +#include <ace/CDR_Stream.h> +#include <ace/INET_Addr.h> + +#include <ace/RMCast/Bits.h> + +namespace ACE_RMCast +{ + // Basic types. + // + typedef ACE_CDR::UShort u16; + typedef ACE_CDR::ULong u32; + typedef ACE_CDR::ULongLong u64; + + typedef ACE_INET_Addr Address; + + struct AddressHasher + { + unsigned long + operator() (Address const& a) const + { + unsigned long port (a.get_port_number ()); + unsigned long ip (a.get_ip_address ()); + + port <<= sizeof (sizeof (unsigned long) - sizeof (unsigned short)); + + return port ^ ip; + } + }; + + //@@ Provide stream<< (Address const&) + // + + typedef ACE_OutputCDR ostream; + typedef ACE_InputCDR istream; + + struct Profile; + + typedef + ACE_Refcounted_Auto_Ptr<Profile, ACE_Null_Mutex> + Profile_ptr; + + struct Profile + { + public: + class Header + { + public: + Header (u16 id, u16 size) + : id_ (id), size_ (size) + { + } + + Header (istream& is) + { + is >> id_ >> size_; + } + + public: + u16 + id () const + { + return id_; + } + + u16 + size () const + { + return size_; + } + + protected: + void + size (u16 s) + { + size_ = s; + } + + friend class Profile; + + private: + u16 id_; + u16 size_; + }; + + public: + virtual + ~Profile () + { + } + + protected: + Profile (u16 id, u16 size, u16 boundary) + : header_ (id, size), boundary_ (boundary) + { + } + + Profile (Header const& h, u16 boundary) + : header_ (h), boundary_ (boundary) + { + } + public: + u16 + id () const + { + return header_.id (); + } + + u16 + size () const + { + return header_.size (); + } + + u16 + boundary () const + { + return boundary_; + } + + protected: + void + size (u16 s) + { + header_.size (s); + } + + public: + virtual void + serialize_body (ostream&) const = 0; + + friend + ostream& + operator<< (ostream& os, Profile const& p); + + private: + Header header_; + u16 boundary_; + }; + + inline + ostream& + operator<< (ostream& os, Profile::Header const& hdr) + { + os << hdr.id (); + os << hdr.size (); + + return os; + } + + inline + ostream& + operator<< (ostream& os, Profile const& p) + { + os << p.header_; + p.serialize_body (os); + + return os; + } + + // + // + // + + class Message; + + typedef + ACE_Refcounted_Auto_Ptr<Message, ACE_Null_Mutex> + Message_ptr; + + class Message + { + public: + Message () + : profiles_ (4) + { + } + + Message (Message const& m) + : profiles_ (4) + { + for (Profiles::const_iterator i (m.profiles_); !i.done (); i.advance ()) + { + // Shallow copy of profiles. + // + profiles_.bind ((*i).ext_id_, (*i).int_id_); + } + } + + public: + struct duplicate {}; + + void + add (Profile_ptr p) + { + u16 id (p->id ()); + + if (profiles_.find (id) == 0) + { + throw duplicate (); + } + + profiles_.bind (id, p); + } + + Profile const* + find (u16 id) const + { + Profiles::ENTRY* e; + + if (profiles_.find (id, e) == -1) return 0; + + return e->int_id_.get (); + } + + public: + size_t + size () const + { + size_t s (4); // 4 is for size (u32) + + for (Profiles::const_iterator i (profiles_); !i.done (); i.advance ()) + { + //@@ This is so broken: in CDR the padding depends on + // what comes after. + // + s += s % 2; // Padding to the boundary of 2. + s += 4; // Profile header: u16 + u16 + s += s % (*i).int_id_->boundary (); // Padding to the b. of profile body. + s += (*i).int_id_->size (); // Profile body. + } + + return s; + } + + friend + ostream& + operator<< (ostream& os, Message const& m) + { + u32 s (m.size ()); + + os << s; + + for (Profiles::const_iterator i (m.profiles_); !i.done (); i.advance ()) + { + os << *((*i).int_id_); + } + + return os; + } + + typedef + ACE_Hash_Map_Manager<u16, Profile_ptr, ACE_Null_Mutex> + Profiles; + + Profiles profiles_; + }; + + typedef + ACE_Vector<Message_ptr> + Messages; + + + // + // + // + struct From; + + typedef + ACE_Refcounted_Auto_Ptr<From, ACE_Null_Mutex> + From_ptr; + + struct From : Profile + { + static u16 const id = 0x0001; + + public: + From (Header const& h, istream& is) + : Profile (h, 4) + { + u32 addr; + u16 port; + + is >> addr; + is >> port; + + address_ = Address (port, addr); + } + + // 6 is CDR-specific. + // + From (Address const& addr) + : Profile (id, 6, 4), address_ (addr) + { + } + + public: + Address const& + address () const + { + return address_; + } + + public: + virtual void + serialize_body (ostream& os) const + { + u32 addr (address_.get_ip_address ()); + u16 port (address_.get_port_number ()); + + os << addr; + os << port; + } + + private: + Address address_; + }; + + + // + // + // + struct To; + + typedef + ACE_Refcounted_Auto_Ptr<To, ACE_Null_Mutex> + To_ptr; + + struct To : Profile + { + static u16 const id = 0x0002; + + public: + To (Header const& h, istream& is) + : Profile (h, 4) + { + u32 addr; + u16 port; + + is >> addr; + is >> port; + + address_ = Address (port, addr); + } + + // 6 is CDR-specific. + // + To (Address const& addr) + : Profile (id, 6, 4), address_ (addr) + { + } + + public: + Address const& + address () const + { + return address_; + } + + public: + virtual void + serialize_body (ostream& os) const + { + u32 addr (address_.get_ip_address ()); + u16 port (address_.get_port_number ()); + + os << addr; + os << port; + } + + private: + Address address_; + }; + + // + // + // + struct Data; + + typedef + ACE_Refcounted_Auto_Ptr<Data, ACE_Null_Mutex> + Data_ptr; + + struct Data : Profile + { + static u16 const id = 0x0003; + + public: + Data (Header const& h, istream& is) + : Profile (h, 1), buf_ (0), size_ (h.size ()) + { + if (size_) + { + buf_ = reinterpret_cast<char*> (operator new (size_)); + is.read_char_array (buf_, size_); + } + + } + + Data (void const* buf, size_t s) + : Profile (id, s, 1), buf_ (0), size_ (s) + { + if (size_) + { + buf_ = reinterpret_cast<char*> (operator new (size_)); + ACE_OS::memcpy (buf_, buf, size_); + } + } + + public: + char const* + buf () const + { + return buf_; + } + + size_t + size () const + { + return size_; + } + + public: + virtual void + serialize_body (ostream& os) const + { + os.write_char_array (buf_, size_); + } + + private: + char* buf_; + size_t size_; + }; + + // + // + // + struct SN; + + typedef + ACE_Refcounted_Auto_Ptr<SN, ACE_Null_Mutex> + SN_ptr; + + struct SN : Profile + { + static u16 const id = 0x0004; + + public: + SN (Header const& h, istream& is) + : Profile (h, 8) + { + is >> n_; + } + + // 8 is CDR-specific. + // + SN (u64 n) + : Profile (id, 8, 8), n_ (n) + { + } + + public: + u64 + num () const + { + return n_; + } + + public: + virtual void + serialize_body (ostream& os) const + { + os << n_; + } + + private: + u64 n_; + }; + + + // + // + // + struct NAK; + + typedef + ACE_Refcounted_Auto_Ptr<NAK, ACE_Null_Mutex> + NAK_ptr; + + struct NAK : Profile + { + static u16 const id = 0x0005; + + typedef + ACE_Vector<u64> + SerialNumbers; + + typedef + SerialNumbers::Iterator + iterator; + + public: + NAK (Header const& h, istream& is) + : Profile (h, 8) + { + //@@ All the numbers are CDR-specific. + // + // 8 = u32 + u16 + 2(padding to u64) + // + for (long i (0); i < ((h.size () - 8) / 8); ++i) + { + u64 sn; + is >> sn; + sns_.push_back (sn); + } + + u32 addr; + u16 port; + + is >> port; + is >> addr; + + address_ = Address (port, addr); + } + + // 8 is CDR-specific. + // + NAK (Address const& src) + : Profile (id, 8, 8), address_ (src) + { + } + + public: + void + add (u64 sn) + { + sns_.push_back (sn); + size (size () + 8); //@@ 8 is CDR-specific + } + + public: + Address const& + address () const + { + return address_; + } + + + iterator + begin () /* const */ + { + return iterator (sns_); + } + + /* + iterator + end () const + { + return sns_.end (); + } + */ + + size_t + count () const + { + return sns_.size (); + } + + public: + virtual void + serialize_body (ostream& os) const + { + NAK& this_ (const_cast<NAK&> (*this)); // Don't put in ROM. + + // Stone age iteration. + // + for (iterator i (this_.begin ()); !i.done (); i.advance ()) + { + u64* psn; + i.next (psn); + os << *psn; + } + + + u32 addr (address_.get_ip_address ()); + u16 port (address_.get_port_number ()); + + os << port; + os << addr; + } + + private: + Address address_; + SerialNumbers sns_; + }; + + // + // + // + struct NRTM; + + typedef + ACE_Refcounted_Auto_Ptr<NRTM, ACE_Null_Mutex> + NRTM_ptr; + + struct NRTM : Profile + { + static u16 const id = 0x0006; + + public: + NRTM (Header const& h, istream& is) + : Profile (h, 8), map_ (10) + { + //@@ 16 is CDR-specific. + // + // 16 = u32 + u16 + 2(padding to u64) + u64 + for (u16 i (0); i < (h.size () / 16); ++i) + { + u32 addr; + u16 port; + u64 sn; + + is >> sn; + is >> port; + is >> addr; + + map_.bind (Address (port, addr), sn); + } + } + + NRTM () + : Profile (id, 0, 8), map_ (10) + { + } + + public: + void + insert (Address const& addr, u64 sn) + { + map_.bind (addr, sn); + + size (size () + 16); //@@ 16 is CDR-specific. + } + + u64 + find (Address const& addr) const + { + u64 sn; + + if (map_.find (addr, sn) == -1) return 0; + + return sn; + } + + bool + empty () const + { + return map_.current_size () == 0; + } + + public: + virtual void + serialize_body (ostream& os) const + { + for (Map::const_iterator i (map_), e (map_, 1); i != e; ++i) + { + u32 addr ((*i).ext_id_.get_ip_address ()); + u16 port ((*i).ext_id_.get_port_number ()); + u64 sn ((*i).int_id_); + + os << sn; + os << port; + os << addr; + } + } + + private: + typedef + ACE_Hash_Map_Manager_Ex<Address, + u64, + AddressHasher, + ACE_Equal_To<Address>, + ACE_Null_Mutex> + Map; + + Map map_; + }; + +} + +/* +inline +std::ostream& +operator<< (std::ostream& os, RMCast::Address const& a) +{ + char buf[64]; + a.addr_to_string (buf, 64, 1); + return os << buf; +} +*/ + + +#endif // ACE_RMCAST_PROTOCOL_H diff --git a/ace/RMCast/README b/ace/RMCast/README index ed6b22bf1c6..d8cfbc040c7 100644 --- a/ace/RMCast/README +++ b/ace/RMCast/README @@ -1,57 +1,22 @@ -# $Id$ - - This directory will contain a simple, small-scale reliable -multicast framework for ACE. The framework is based on the ASX -components of the ACE library: the protocol is implemented as a stack -of interchangeable "modules", each one in charge of a very small task. -For example, one module implements fragmentation and reassembly, other -modules implement retransmission, send ACK and NAK messages, and -maintain receiver membership. - - The modules are replaced to achieve different levels of -reliability. For example, the retransmission module can be either the -"Best_Effort", "Semi_Reliable" or "Reliable" implementation. In the -first case no retransmissions are performed, but lost messages are -detected and reported to the receiver. The "Semi_Reliable" case -messages are held for a pre-specified amount of time, and -re-transmited if requested, but it is possible to loose some messages -if multiple re-transmissions fail. As in the "Best_Effort" case the -lost messages are detected and flagged to the application. Finally -in the "Reliable" mode the senders are flowed controlled until enough -messages are successfully transmitted. - - In general the stack looks like this: - - -SENDER: - ----------------------------------------------------------------- -Buffering : Save lost messages -Retransmission : Retransmit ----------------------------------------------------------------- -Fragmentation : Fragment messages in smaller chunks -Reassembly : and ensure that the IOVMAX limit is not - : reached ----------------------------------------------------------------- -Transport : Encapsulate the specific transport media - : such as TCP/IP, ATM, or shared memory - : Demuxes incoming data to the right chain - : Change control messages and data messages - : to the right dynamic types. ----------------------------------------------------------------- - -RECEIVER: - ----------------------------------------------------------------- -Lost detection : Detect lost messages and send control - : messages back ----------------------------------------------------------------- -Reassembly : Reassemble messages, fragment control -Fragmentation : data ----------------------------------------------------------------- -Transport : Group membership, ACT reception, - : handle keep-alive messages... ----------------------------------------------------------------- - - -@@ TODO: Piggybacking... +RMCast is a reliable source-ordered multicast protocol implementation +for message-oriented multi-sender group communication built on top of +IPv4 multicast. It uses sequence numbers for re-ordering, duplicate +suppression and loss detection. Negative acknowledgments (NAK) with +retransmissions are used to recover from losses. + +One new and interesting idea implemented in this protocol is history +transmission (dubbed negative retransmission). In a nutshell, each +sender, along with normal payload, transmits a list of other sender's +IDs along with sequence numbers of last messages received from those +senders by this member. This, in some sense, builds a pyramid of +information: each subsequent message carries some information for a +number of previous messages (from other senders). This helps other +receivers detect losses. + +The protocol does not track group membership. Messages are retained +for retransmission for a predefined amount of time. The "last message +or lost message" dilemma is solved by periodic history transmissions +in cases when there is no useful traffic (idle network). + +-- +Boris Kolpackov <boris@kolpackov.net> diff --git a/ace/RMCast/RMCast.cpp b/ace/RMCast/RMCast.cpp deleted file mode 100644 index eb9887f8883..00000000000 --- a/ace/RMCast/RMCast.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// $Id$ - -#include "RMCast.h" - -ACE_RCSID(RMCast, RMCast, "$Id$") diff --git a/ace/RMCast/RMCast.h b/ace/RMCast/RMCast.h deleted file mode 100644 index 2339daa6f8e..00000000000 --- a/ace/RMCast/RMCast.h +++ /dev/null @@ -1,253 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_H -#define ACE_RMCAST_H -#include /**/ "ace/pre.h" - -#include "RMCast_Export.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/Basic_Types.h" - -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: - - //! 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 - RMCAST_MT_POLL, - RMCAST_MT_ACK_JOIN, - RMCAST_MT_ACK_LEAVE, - RMCAST_MT_DATA, - // Receiver initiated - RMCAST_MT_JOIN, - RMCAST_MT_LEAVE, - RMCAST_MT_ACK, - RMCAST_MT_LAST - }; - - //! 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 - }; - - - // 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 - // - If we are using authentic group communication we may - // piggyback the ACK / NAK messages - - ACE_Message_Block *payload; - - //! Pass the proxy source between layers - ACE_RMCast_Proxy *source; - }; - - /*! - <CODE> - +---------+----------------------+<BR> - | 8 bits | RMCAST_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 | RMCAST_MT_ACK_JOIN |<BR> - +---------+----------------------+<BR> - | 32 bits | next_sequence_number |<BR> - +---------+----------------------+<BR> - </CODE> - */ - struct Ack_Join - { - ACE_UINT32 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: - * - \param next_expected: is the sequence number of the next message - * expected, i.e. (next_expected-1) is the last message received - * without any losses before it. - * - \param highest_received: is the highest sequence number among - * all the messages successfully received. - * In other words, all messages lost (if any) are in the range: - * [next_expected,highest_received) - * - * <CODE> - * +---------+----------------------+<BR> - * | 8 bits | RMCAST_MT_ACK |<BR> - * +---------+----------------------+<BR> - * | 32 bits | next_expected |<BR> - * +---------+----------------------+<BR> - * | 32 bits | highest_received |<BR> - * +---------+----------------------+<BR> - * </CODE> - */ - struct Ack - { - //! The last message received without any losses before it. - ACE_UINT32 next_expected; - - //! 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 | RMCAST_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 | RMCAST_MT_LEAVE |<BR> - +---------+----------------------+<BR> - </CODE> - */ - struct Leave - { - //! Pass the proxy source between layers - ACE_RMCast_Proxy *source; - }; -}; - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_H */ diff --git a/ace/RMCast/rmcast.mpc b/ace/RMCast/RMCast.mpc index 5f98b38d8b0..5ba1bd21b2d 100644 --- a/ace/RMCast/rmcast.mpc +++ b/ace/RMCast/RMCast.mpc @@ -2,7 +2,6 @@ // $Id$ project(RMCast) : acelib, core { - requires += rmcast sharedname = ACE_RMCast dynamicflags = ACE_RMCAST_BUILD_DLL } diff --git a/ace/RMCast/RMCast.rc b/ace/RMCast/RMCast.rc deleted file mode 100644 index 142de8a5625..00000000000 --- a/ace/RMCast/RMCast.rc +++ /dev/null @@ -1,30 +0,0 @@ -#include "..\Version.h" - -1 VERSIONINFO - FILEVERSION ACE_MAJOR_VERSION,ACE_MINOR_VERSION,ACE_BETA_VERSION,0 - PRODUCTVERSION ACE_MAJOR_VERSION,ACE_MINOR_VERSION,ACE_BETA_VERSION,0 - FILEFLAGSMASK 0x3fL - FILEFLAGS 0x0L - FILEOS 0x4L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904B0" - BEGIN - VALUE "FileDescription", "RMCast\0" - VALUE "FileVersion", ACE_VERSION "\0" - VALUE "InternalName", "RMCastDLL\0" - VALUE "LegalCopyright", "\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "RMCast.DLL\0" - VALUE "ProductName", "ACE\0" - VALUE "ProductVersion", ACE_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/ace/RMCast/RMCast_Ack_Worker.cpp b/ace/RMCast/RMCast_Ack_Worker.cpp deleted file mode 100644 index d454e013056..00000000000 --- a/ace/RMCast/RMCast_Ack_Worker.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Ack_Worker.h" -#include "ace/Message_Block.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Ack_Worker.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Ack_Worker, "$Id$") - -int -ACE_RMCast_Ack_Worker::work (ACE_UINT32 const & key, - ACE_RMCast::Data const &item) -{ - if (key >= this->ack_.next_expected) - return 0; - // ACE_DEBUG ((LM_DEBUG, - // " Retransmission::ack - message %d erased\n", - // key)); - ACE_Message_Block::release (item.payload); - return this->messages_->unbind_i (this->ace_mon_, key); -} diff --git a/ace/RMCast/RMCast_Ack_Worker.h b/ace/RMCast/RMCast_Ack_Worker.h deleted file mode 100644 index b4d81e4e972..00000000000 --- a/ace/RMCast/RMCast_Ack_Worker.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_ACK_WORKER_H -#define ACE_RMCAST_ACK_WORKER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Retransmission.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Process an Ack message in the ACE_RMCast_Retransmission module -/** - * The retransmission module uses internal iterators, thus it needs to - * create helper Worker classes to process some messages. - */ -class ACE_RMCast_Ack_Worker - : public ACE_RMCast_Worker<ACE_UINT32,ACE_RMCast::Data> -{ -public: - ACE_RMCast_Ack_Worker (ACE_RMCast::Ack &ack, - ACE_RMCast_Retransmission::Messages::Write_Guard &g, - ACE_RMCast_Retransmission::Messages *messages); - - virtual int work (ACE_UINT32 const & key, - ACE_RMCast::Data const &item); - -private: - ACE_RMCast_Ack_Worker (const ACE_RMCast_Ack_Worker&); - ACE_RMCast_Ack_Worker& operator= (const ACE_RMCast_Ack_Worker&); - -private: - ACE_RMCast::Ack &ack_; - - ACE_RMCast_Retransmission::Messages::Write_Guard &ace_mon_; - - ACE_RMCast_Retransmission::Messages *messages_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Ack_Worker.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_ACK_WORKER_H */ diff --git a/ace/RMCast/RMCast_Ack_Worker.i b/ace/RMCast/RMCast_Ack_Worker.i deleted file mode 100644 index 54d94d21167..00000000000 --- a/ace/RMCast/RMCast_Ack_Worker.i +++ /dev/null @@ -1,12 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Ack_Worker:: -ACE_RMCast_Ack_Worker (ACE_RMCast::Ack &ack, - ACE_RMCast_Retransmission::Messages::Write_Guard &g, - ACE_RMCast_Retransmission::Messages *messages) - : ack_ (ack) - , ace_mon_ (g) - , messages_ (messages) -{ -} diff --git a/ace/RMCast/RMCast_Copy_On_Write.cpp b/ace/RMCast/RMCast_Copy_On_Write.cpp deleted file mode 100644 index 39bf16f88a2..00000000000 --- a/ace/RMCast/RMCast_Copy_On_Write.cpp +++ /dev/null @@ -1,199 +0,0 @@ -// $Id$ - -#ifndef ACE_RMCAST_COPY_ON_WRITE_CPP -#define ACE_RMCAST_COPY_ON_WRITE_CPP - -#include "RMCast_Copy_On_Write.h" - -#if ! defined (__ACE_INLINE__) -#include "RMCast_Copy_On_Write.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Copy_On_Write, "$Id$") - -template<class COLLECTION, class ITERATOR> void -ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR>::_incr_refcnt (void) -{ - // LOCKING: no locking is required, the caller grabs the mutex. - this->refcount_++; -} - -template<class COLLECTION, class ITERATOR> void -ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR>::_decr_refcnt (void) -{ - // LOCKING: no locking is required, the caller grabs the mutex. - { - this->refcount_--; - if (this->refcount_ != 0) - return; - } - //@@ TODO: If this wrapper is going to be completely general some - // kind of functor has to be provided to remove the elements in the - // collection, in case the are no self-managed - - delete this; -} - -// **************************************************************** - -template<class KEY, class ITEM, class COLLECTION, class ITERATOR> -ACE_RMCast_Copy_On_Write<KEY,ITEM,COLLECTION,ITERATOR>:: - ACE_RMCast_Copy_On_Write (void) - : ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR> () -{ -} - -template<class KEY, class ITEM, class COLLECTION, class ITERATOR> -ACE_RMCast_Copy_On_Write<KEY,ITEM,COLLECTION,ITERATOR>:: - ~ACE_RMCast_Copy_On_Write (void) -{ - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_); - - while (this->pending_writes_ != 0) - this->cond_.wait (); - - this->collection_->_decr_refcnt (); - this->collection_ = 0; -} - -template<class KEY, class ITEM, class COLLECTION, class ITERATOR> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,COLLECTION,ITERATOR>:: - for_each (ACE_RMCast_Worker<KEY,ITEM> *worker) -{ - Read_Guard ace_mon (*this); - - ITERATOR end = ace_mon.collection->collection.end (); - for (ITERATOR i = ace_mon.collection->collection.begin (); i != end; ++i) - { - int r = worker->work ((*i).key (), (*i).item ()); - if (r == 1) - return 0; // Abort loop, but no error - if (r == -1) - return -1; - } - return 0; -} - -template<class KEY, class ITEM, class C, class ITERATOR> KEY -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,ITERATOR>::first_key (void) -{ - Read_Guard ace_mon (*this); - ITERATOR end = ace_mon.collection->collection.end (); - ITERATOR begin = ace_mon.collection->collection.begin (); - if (begin == end) - { - return KEY (); - } - return (*begin).key (); -} - -template<class KEY, class ITEM, class C, class ITERATOR> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,ITERATOR>::empty (void) -{ - Read_Guard ace_mon (*this); - ITERATOR end = ace_mon.collection->collection.end (); - ITERATOR begin = ace_mon.collection->collection.begin (); - - return end == begin; -} - -template<class KEY, class ITEM, class C, class I> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,I>::bind (KEY const & k, - ITEM const & i) -{ - Write_Guard ace_mon (*this); - - return this->bind_i (ace_mon, k, i); -} - -template<class KEY, class ITEM, class C, class I> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,I>::unbind (KEY const & k) -{ - Write_Guard ace_mon (*this); - - return this->unbind_i (ace_mon, k); -} - -template<class KEY, class ITEM, class C, class I> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,I>::bind_i (Write_Guard &ace_mon, - KEY const & k, - ITEM const & i) -{ - return ace_mon.copy->collection.bind (k, i); -} - -template<class KEY, class ITEM, class C, class I> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,I>::unbind_i (Write_Guard &ace_mon, - KEY const & k) -{ - return ace_mon.copy->collection.unbind (k); -} - -// **************************************************************** - -template<class COLLECTION, class ITERATOR> -ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR>::ACE_RMCast_Copy_On_Write_Container (void) - : pending_writes_ (0) - , writing_ (0) - , cond_ (mutex_) -{ - ACE_NEW (this->collection_, Collection); -} - -// **************************************************************** - -template<class COLLECTION, class ITERATOR> -ACE_RMCast_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR>:: - ACE_RMCast_Copy_On_Write_Write_Guard (Container &container) - : copy (0) - , mutex (container.mutex_) - , cond (container.cond_) - , pending_writes (container.pending_writes_) - , writing_flag (container.writing_) - , collection (container.collection_) -{ - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex); - - this->pending_writes++; - - while (this->writing_flag != 0) - this->cond.wait (); - - this->writing_flag = 1; - } - - // Copy outside the mutex, because it may take a long time. - // Nobody can change it, because it is protected by the - // writing_flag. - - // First initialize it (with the correct reference count - ACE_NEW (this->copy, Collection); - // Copy the contents - this->copy->collection = this->collection->collection; -} - -template<class COLLECTION, class ITERATOR> -ACE_RMCast_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR>:: - ~ACE_RMCast_Copy_On_Write_Write_Guard (void) -{ - Collection *tmp = 0; - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex); - - tmp = this->collection; - this->collection = this->copy; - this->writing_flag = 0; - this->pending_writes--; - - this->cond.signal (); - } - // Delete outside the mutex, because it may take a long time. - // @@ Is this right? What happens if several readers are still - // using the old copy? - tmp->_decr_refcnt (); -} - -// **************************************************************** - -#endif /* ACE_RMCAST_COPY_ON_WRITE_CPP */ diff --git a/ace/RMCast/RMCast_Copy_On_Write.h b/ace/RMCast/RMCast_Copy_On_Write.h deleted file mode 100644 index bad0318638e..00000000000 --- a/ace/RMCast/RMCast_Copy_On_Write.h +++ /dev/null @@ -1,214 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_COPY_ON_WRITE_H -#define ACE_RMCAST_COPY_ON_WRITE_H -#include /**/ "ace/pre.h" - -#include "RMCast_Worker.h" -#include "ace/Synch_Traits.h" -#include "ace/Basic_Types.h" -#include "ace/Condition_Thread_Mutex.h" - -//! A wrapper to implement reference counted collections -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Collection -{ -public: - //! Constructor - ACE_RMCast_Copy_On_Write_Collection (void); - - //! Increment the reference count - void _incr_refcnt (void); - - //! Decrement the reference count - void _decr_refcnt (void); - - //! The actual collection - COLLECTION collection; - -private: - //! The reference count - ACE_UINT32 refcount_; -}; - -// **************************************************************** - -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Read_Guard; - -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Write_Guard; - -//! Base class for the Copy_On_Write collection, used to simplify the -//! declaration of the Write_Guard -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Container -{ -public: - //! Constructor - ACE_RMCast_Copy_On_Write_Container (void); - - //! Let the Write_Guard access the internal fields. - friend class ACE_RMCast_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR>; - - //! Let the Read_Guard access the internal fields. - friend class ACE_RMCast_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR>; - - //! A shorter name for the actual collection type - typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection; - -protected: - //! Number of pending writes - int pending_writes_; - - //! If non-zero then a thread is changing the collection. - /*! - * Many threads can use the collection simulatenously, but only one - * change it. - */ - int writing_; - - //! A mutex to serialize access to the collection pointer. - ACE_SYNCH_MUTEX mutex_; - - //! A condition variable to wait to synchronize multiple writers. - ACE_SYNCH_CONDITION cond_; - - //! The collection, with reference counting added - Collection *collection_; -}; - -// **************************************************************** - -//! Implement a read guard for a reference counted collection -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Read_Guard -{ -public: - typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection; - typedef ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR> Container; - - //! Constructor - ACE_RMCast_Copy_On_Write_Read_Guard (Container &container); - - //! Destructor - ~ACE_RMCast_Copy_On_Write_Read_Guard (void); - - //! A reference to the collection - Collection *collection; - -private: - //! Synchronization - ACE_SYNCH_MUTEX &mutex_; -}; - -// **************************************************************** - -//! Implement the write guard for a reference counted collecion -/*! - * This helper class atomically increments the reference count of a - * ACE_RMCast_Copy_On_Write_Collection and reads the current - * collection in the Copy_On_Write class. - */ -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Write_Guard -{ -public: - typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection; - typedef ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR> Container; - - //! Constructor - ACE_RMCast_Copy_On_Write_Write_Guard (Container &container); - - //! Destructor - ~ACE_RMCast_Copy_On_Write_Write_Guard (void); - - //! The collection - Collection *copy; - -private: - //! Keep a reference to the mutex - ACE_SYNCH_MUTEX &mutex; - - //! Keep a reference to the condition variable - ACE_SYNCH_CONDITION &cond; - - //! Use a reference to update the pending writes count - int &pending_writes; - - //! Use a reference to update the writing flag - int &writing_flag; - - //! Use this reference to update the collection once the - //! modifications are finished. - Collection *&collection; -}; - - -// **************************************************************** - -//! Implement a copy on write wrapper for a map-like collection -/* - * - * <B>WARNING: </B> This class may be moved away in the future, I'm - * investigating how it could be converted into a reusable component - * in ACE. I won't make promises on when will that happen, but I - * won't promise that it will stay here either. - * - */ -template<class KEY, class ITEM, class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write : public ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR> -{ -public: - //! The Read_Guard trait - typedef ACE_RMCast_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR> Read_Guard; - - //! The Write_Guard trait - typedef ACE_RMCast_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR> Write_Guard; - - //! The underlying collection type - typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection; - - //! Constructor - ACE_RMCast_Copy_On_Write (void); - - //! Destructor - ~ACE_RMCast_Copy_On_Write (void); - - //! Iterate over all the elements invoking worker on each one. - int for_each (ACE_RMCast_Worker<KEY,ITEM> *worker); - - //! Get the first key - KEY first_key (void); - - /// Return non-zero if the collection is empty - int empty (void); - - //! Add a new element - int bind (KEY const & key, ITEM const & item); - - //! Remove an element - int unbind (KEY const & key); - - //! Bind assuming the Write_Guard is held - int bind_i (Write_Guard &guard, KEY const & key, ITEM const & item); - - //! Unbind assuming the Write_Guard is held - int unbind_i (Write_Guard &guard, KEY const & key); -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Copy_On_Write.i" -#endif /* __ACE_INLINE__ */ - -#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "RMCast_Copy_On_Write.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - -#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) -#pragma implementation ("RMCast_Copy_On_Write.cpp") -#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_COPY_ON_WRITE_H */ diff --git a/ace/RMCast/RMCast_Copy_On_Write.i b/ace/RMCast/RMCast_Copy_On_Write.i deleted file mode 100644 index c83483c0729..00000000000 --- a/ace/RMCast/RMCast_Copy_On_Write.i +++ /dev/null @@ -1,38 +0,0 @@ -// -*- C++ -*- -// $Id$ - -#include "ace/Guard_T.h" -#include "ace/Null_Mutex.h" - -template<class COLLECTION, class ITERATOR> ACE_INLINE -ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR>:: - ACE_RMCast_Copy_On_Write_Collection (void) - : refcount_ (1) -{ -} - -// **************************************************************** - -template<class COLLECTION, class ITERATOR> ACE_INLINE -ACE_RMCast_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR>:: - ACE_RMCast_Copy_On_Write_Read_Guard (Container &container) - : collection (0) - , mutex_ (container.mutex_) -{ - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_); - this->collection = container.collection_; - this->collection->_incr_refcnt (); -} - -template<class COLLECTION, class ITERATOR> ACE_INLINE -ACE_RMCast_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR>:: - ~ACE_RMCast_Copy_On_Write_Read_Guard (void) -{ - if (this->collection != 0) - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_); - this->collection->_decr_refcnt (); - } -} - -// **************************************************************** diff --git a/ace/RMCast/RMCast_Fork.cpp b/ace/RMCast/RMCast_Fork.cpp deleted file mode 100644 index 92c81b9d33e..00000000000 --- a/ace/RMCast/RMCast_Fork.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// $Id$ - -#include "RMCast_Fork.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Fork.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Fork, "$Id$") - -ACE_RMCast_Fork::~ACE_RMCast_Fork (void) -{ -} - -int -ACE_RMCast_Fork::open (void) -{ - int r = this->ACE_RMCast_Module::open (); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->open (); - return 0; -} - -int -ACE_RMCast_Fork::close (void) -{ - int r = this->ACE_RMCast_Module::close (); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->close (); - return 0; -} - -int -ACE_RMCast_Fork::data (ACE_RMCast::Data &data) -{ - int r = this->ACE_RMCast_Module::data (data); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->data (data); - return 0; -} - -int -ACE_RMCast_Fork::poll (ACE_RMCast::Poll &poll) -{ - int r = this->ACE_RMCast_Module::poll (poll); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->poll (poll); - return 0; -} - -int -ACE_RMCast_Fork::ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - int r = this->ACE_RMCast_Module::ack_join (ack_join); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->ack_join (ack_join); - return 0; -} - -int -ACE_RMCast_Fork::ack_leave (ACE_RMCast::Ack_Leave &ack_leave) -{ - int r = this->ACE_RMCast_Module::ack_leave (ack_leave); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->ack_leave (ack_leave); - return 0; -} - -int -ACE_RMCast_Fork::ack (ACE_RMCast::Ack &ack) -{ - int r = this->ACE_RMCast_Module::ack (ack); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->ack (ack); - return 0; -} - -int -ACE_RMCast_Fork::join (ACE_RMCast::Join &join) -{ - int r = this->ACE_RMCast_Module::join (join); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->join (join); - return 0; -} - -int -ACE_RMCast_Fork::leave (ACE_RMCast::Leave &leave) -{ - int r = this->ACE_RMCast_Module::leave (leave); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->leave (leave); - return 0; -} diff --git a/ace/RMCast/RMCast_Fork.h b/ace/RMCast/RMCast_Fork.h deleted file mode 100644 index 498ee2d6d63..00000000000 --- a/ace/RMCast/RMCast_Fork.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_FORK_H -#define ACE_RMCAST_FORK_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Fork messages to multiple destinations -/** - * In some instances the messages must be sent to multiple - * destinations, this module is a generic component to duplicate such - * messages. - */ -class ACE_RMCast_Export ACE_RMCast_Fork : public ACE_RMCast_Module -{ -public: - //! Constructor - ACE_RMCast_Fork (void); - - //! Destructor - virtual ~ACE_RMCast_Fork (void); - - /// Set the control module, all incoming control messages go to it - void secondary (ACE_RMCast_Module *module); - - /// Return the current control module - ACE_RMCast_Module *secondary (void) const; - - virtual int open (void); - virtual int close (void); - virtual int data (ACE_RMCast::Data &); - virtual int poll (ACE_RMCast::Poll &); - virtual int ack_join (ACE_RMCast::Ack_Join &); - virtual int ack_leave (ACE_RMCast::Ack_Leave &); - virtual int ack (ACE_RMCast::Ack &); - virtual int join (ACE_RMCast::Join &); - virtual int leave (ACE_RMCast::Leave &); - -private: - /// The control module - ACE_RMCast_Module *secondary_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Fork.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_FORK_H */ diff --git a/ace/RMCast/RMCast_Fork.i b/ace/RMCast/RMCast_Fork.i deleted file mode 100644 index bbcd4f23ae1..00000000000 --- a/ace/RMCast/RMCast_Fork.i +++ /dev/null @@ -1,21 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Fork::ACE_RMCast_Fork (void) - : ACE_RMCast_Module () - , secondary_ (0) -{ -} - -ACE_INLINE void -ACE_RMCast_Fork::secondary (ACE_RMCast_Module *module) -{ - this->secondary_ = module; -} - - -ACE_INLINE ACE_RMCast_Module * -ACE_RMCast_Fork::secondary (void) const -{ - return this->secondary_; -} diff --git a/ace/RMCast/RMCast_Fragment.cpp b/ace/RMCast/RMCast_Fragment.cpp deleted file mode 100644 index 2c8cae86d7e..00000000000 --- a/ace/RMCast/RMCast_Fragment.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// $Id$ - -#include "RMCast_Fragment.h" -#include "ace/Message_Block.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#if !defined (__ACE_INLINE__) -#include "RMCast_Fragment.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Fragment, "$Id$") - -ACE_RMCast_Fragment:: -ACE_RMCast_Fragment (void) - : ACE_RMCast_Module () - , max_fragment_size_ (ACE_RMCAST_DEFAULT_FRAGMENT_SIZE) -{ -} - -ACE_RMCast_Fragment::~ACE_RMCast_Fragment (void) -{ -} - -int -ACE_RMCast_Fragment::data (ACE_RMCast::Data &received_data) -{ - if (this->next () == 0) - return 0; - - // The Data object sent downstream - ACE_RMCast::Data data = received_data; - - ACE_Message_Block *mb = data.payload; - - // @@ We should keep the total size precomputed - data.total_size = static_cast<ACE_UINT32> (mb->total_length ()); - - // We must leave room for the header -#if defined (ACE_HAS_BROKEN_DGRAM_SENDV) - const int ACE_RMCAST_WRITEV_MAX = ACE_IOV_MAX - 2; -#else - const int ACE_RMCAST_WRITEV_MAX = ACE_IOV_MAX - 1; -#endif /* ACE_HAS_BROKEN_DGRAM_SENDV */ - - // Assume the header will be included on each fragment, so readuce - // the maximum amount of memory allowed on each fragment.... - const size_t fragment_header_size = 1 + 3 * sizeof(ACE_UINT32); - - const size_t max_fragment_payload = - this->max_fragment_size_ - fragment_header_size; - - // Iterate over all the message blocks in the chain. If there is - // enough data to send an MTU then it is sent immediately. - // The last fragment is sent with whatever data remains. - // A single fragment can expand multiple message blocks, put - // together in an <iovec> array, it is also possible that a single - // message block requires multiple fragments... so the code below is - // as simple as possible, but not any simpler ;-) - - - // The first piece of each fragment is a header that contains: - // - A sequence number for reassembly, this is unrelated to - // the sequence number for re-transmission. - // NOTE: yes, this increases the bandwidth requires by 4 bytes on - // each message, I don't think this is a big deal. - // - A fragment offset for reassembly. - // - The total size of the message, so the reassembly layer knows - // when a complete message has been received. - - // Complete the initialization of the <data> structure - - data.fragment_offset = 0; - - // The underlying transport layer can only tolerate so many elements - // in a chain, so we must count them and send a fragment if we are - // going over the limit. - - ACE_Message_Block blocks[ACE_RMCAST_WRITEV_MAX]; - - - // How many elements of the <blocks> array are in use... - int iovcnt = 0; - - // The size of the current message, adding the size of all its - // message blocks. - size_t fragment_size = 0; - - for (ACE_Message_Block* b = mb; b != 0; b = b->cont ()) - { - ACE_Message_Block *current_block = &blocks[iovcnt]; - - // Add the block to the vector... - - current_block->data_block (b->data_block ()->duplicate ()); - current_block->rd_ptr (b->rd_ptr ()); - current_block->wr_ptr (b->wr_ptr ()); - current_block->cont (0); - - // Set the continuation field - if (iovcnt != 0) - blocks[iovcnt-1].cont (current_block); - - size_t current_block_length = current_block->length (); - - // Recompute the state of the fragment - fragment_size += current_block_length; - iovcnt++; - - while (fragment_size >= max_fragment_payload) - { - // We have filled a fragment. It is possible that we need - // to split the last message block in multiple fragments, - // thus the loop above... - - // First adjust the last message block to exactly fit in the - // fragment: - size_t last_sent_mb_len = - max_fragment_payload - (fragment_size - current_block_length); - - // Send only enough data of the last message block to fill - // the fragment... - current_block->wr_ptr (current_block->rd_ptr () - + last_sent_mb_len); - - data.payload = blocks; - if (this->next ()->data (data) == -1) - return -1; - - // adjust the offset - data.fragment_offset += static_cast<ACE_UINT32> (max_fragment_payload); - - // Now compute how much data is left in the last message - // block, to check if we should continue sending it... - current_block_length -= last_sent_mb_len; - if (current_block_length == 0) - { - // No more data from this message block, just continue - // the outer loop... - iovcnt = 0; - fragment_size = 0; - blocks[0].cont (0); - break; // while - } - - // There is some data left, we try to send it in a single - // fragment, if it is still too big the beginning of this - // loop will adjust things. - - // We must put the data in the right place in the array.. - char *rd_ptr = current_block->rd_ptr () + last_sent_mb_len; - char *wr_ptr = rd_ptr + current_block_length; - blocks[0].data_block (current_block->replace_data_block (0)); - - // And determine what segment of the data will be sent.. - blocks[0].rd_ptr (rd_ptr); - blocks[0].wr_ptr (wr_ptr); - blocks[0].cont (0); - - // Adjust the state of the fragment - fragment_size = current_block_length; - iovcnt = 1; - - // Notice that if <fragment_size> is too big the start of - // this loop will continue the fragmentation. - } - - // It is also possible to fill up the iovec array before the - // fragment is completed, in this case we must send whatever we - // have: - if (iovcnt == ACE_RMCAST_WRITEV_MAX) - { - if (this->next ()->data (data) == -1) - return -1; - - iovcnt = 0; - fragment_size = 0; - blocks[0].cont (0); - } - } - - if (iovcnt == 0) - return 0; - - return this->next ()->data (data); -} diff --git a/ace/RMCast/RMCast_Fragment.h b/ace/RMCast/RMCast_Fragment.h deleted file mode 100644 index f180087ce3e..00000000000 --- a/ace/RMCast/RMCast_Fragment.h +++ /dev/null @@ -1,61 +0,0 @@ -// $Id$ - -#ifndef ACE_RMCAST_FRAGMENT_H -#define ACE_RMCAST_FRAGMENT_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -//! Default fragment size -#ifndef ACE_RMCAST_DEFAULT_FRAGMENT_SIZE -# define ACE_RMCAST_DEFAULT_FRAGMENT_SIZE 1024 -#endif /* ACE_RMCAST_DEFAULT_FRAGMENT_SIZE */ - -//! Fragmentation module -/*! - * Some transports cannot send very big messages, for example UDP - * imposes a limit of 64K, and in practice the limit is even more - * strict than that. - * This class decomposes a message into multiple fragments, using an - * application defined maximum size. - */ -class ACE_RMCast_Export ACE_RMCast_Fragment : public ACE_RMCast_Module -{ -public: - //! Constructor - ACE_RMCast_Fragment (void); - - //! Destructor - virtual ~ACE_RMCast_Fragment (void); - - //! Accessor for the max_fragment size. - /*! There is no modifier, the maximum fragment size is obtained - * using feedback from the lower layers (transport?) - * @@TODO We have not implemented the feedback mechanisms yet! - */ - size_t max_fragment_size (void) const; - - /*! - * Only data messages need fragmentation, the control messages are - * all small enough for all the transports that I know about. - * Well, actually for CAN-Bus (Controller Area Network), they may be - * too big, because the max payload there is 8 bytes, but we don't - * play with those in ACE. - */ - virtual int data (ACE_RMCast::Data &data); - -private: - //! Current fragment size limit - size_t max_fragment_size_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Fragment.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_FRAGMENT_H */ diff --git a/ace/RMCast/RMCast_Fragment.i b/ace/RMCast/RMCast_Fragment.i deleted file mode 100644 index 8e628093b8c..00000000000 --- a/ace/RMCast/RMCast_Fragment.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE size_t -ACE_RMCast_Fragment::max_fragment_size (void) const -{ - return this->max_fragment_size_; -} diff --git a/ace/RMCast/RMCast_IO_UDP.cpp b/ace/RMCast/RMCast_IO_UDP.cpp deleted file mode 100644 index 60940ad9465..00000000000 --- a/ace/RMCast/RMCast_IO_UDP.cpp +++ /dev/null @@ -1,461 +0,0 @@ -// $Id$ - -#include "RMCast_IO_UDP.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_IO_UDP.i" -#endif /* ! __ACE_INLINE__ */ - -#include "RMCast_UDP_Proxy.h" -#include "RMCast_Module_Factory.h" - -#include "ace/Handle_Set.h" -#include "ace/Reactor.h" -#include "ace/Message_Block.h" -#include "ace/OS_NS_string.h" -#include "ace/OS_NS_sys_select.h" -#include "ace/os_include/arpa/os_inet.h" -#include "ace/OS_NS_unistd.h" - -ACE_RCSID(RMCast, RMCast_IO_UDP, "RMCast_IO_UDP.cpp,v 1.12 2000/12/20 22:00:33 oci Exp") - -ACE_RMCast_IO_UDP::~ACE_RMCast_IO_UDP (void) -{ -} - -int -ACE_RMCast_IO_UDP::init (const ACE_INET_Addr &mcast_group, - const ACE_Addr &local, - int protocol_family, - int protocol, - int reuse_addr) -{ - this->mcast_group_ = mcast_group; - - ACE_SOCK_Dgram &dgram = this->dgram_; - return dgram.open (local, protocol_family, protocol, reuse_addr); -} - -int -ACE_RMCast_IO_UDP::subscribe (const ACE_INET_Addr &mcast_addr, - int reuse_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol) -{ - this->mcast_group_ = mcast_addr; - return this->dgram_.subscribe (mcast_addr, - reuse_addr, - net_if, - protocol_family, - protocol); -} - -int -ACE_RMCast_IO_UDP::handle_events (ACE_Time_Value *tv) -{ - ACE_HANDLE h = this->dgram_.get_handle (); - if (h == ACE_INVALID_HANDLE) - return -1; - - ACE_Handle_Set handle_set; - handle_set.set_bit (h); - - ACE_Countdown_Time countdown (tv); - - int r = ACE_OS::select (int(size_t(h)) + 1, - handle_set, 0, 0, - tv); - if (r == -1) - { - if (errno == EINTR) - return 0; - else - return -1; - } - else if (r == 0) - { - return 0; - } - - return this->handle_input (h); -} - -int -ACE_RMCast_IO_UDP::handle_input (ACE_HANDLE) -{ - char buffer[ACE_MAX_UDP_PACKET_SIZE]; - - ACE_INET_Addr from_address; - ssize_t r = - this->dgram_.recv (buffer, sizeof(buffer), from_address); - - if (r == -1) - { - // @@ LOG?? - ACE_ERROR ((LM_ERROR, - "RMCast_IO_UDP::handle_input () - error in recv %p\n", - ACE_TEXT (""))); - return -1; - } - - // ACE_HEX_DUMP ((LM_DEBUG, buffer, 16, "Receiver::handle_input")); - - // @@ Locking! - - int type = buffer[0]; - - if (type < 0 || type >= ACE_RMCast::RMCAST_MT_LAST) - { - // @@ Log: invalid message type!! - // @@ TODO: should we return -1? The socket is still valid, it - // makes little sense to destroy it just because one remote - // sender is sending invalid messages. Maybe we should - // strategize this too, and report the problem to the - // application, this could indicate a misconfiguration or - // something worse... - - // In any case the proxy should be destroyed, its peer is making - // something really wrong. - ACE_RMCast_UDP_Proxy *proxy; - if (this->map_.unbind (from_address, proxy) == 0) - { - this->factory_->destroy (proxy->next ()); - delete proxy; - } - return 0; - } - - ACE_RMCast_UDP_Proxy *proxy; - if (this->map_.find (from_address, proxy) != 0) - { - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::handle_input - new proxy from <%s:%d>\n", - // from_address.get_host_addr (), - // from_address.get_port_number ())); - - // @@ We should validate the message *before* creating the - // object, all we need is some sort of validation strategy, a - // different one for the receiver and another one for the - // sender. - -#if 0 - if (type == ACE_RMCast::RMCAST_MT_ACK - || type == ACE_RMCast::RMCAST_MT_JOIN - || type == ACE_RMCast::RMCAST_MT_LEAVE - || type == ACE_RMCast::RMCAST_MT_ACK_LEAVE) - { - // All these message types indicate a problem, the should be - // generated by receivers, not received by them. - return 0; - } -#endif /* 0 */ - ACE_RMCast_Module *module = this->factory_->create (); - if (module == 0) - { - // @@ LOG?? - // Try to continue working, maybe the module can be created - // later. - return 0; - } - // This is necessary to satisfy the xgcc for Lynx on Solaris - // by including the code directly causes : - // RMCast_IO_UDP.cpp:202: error: internal error--unrecognizable insn: - // (insn 1510 1507 524 (set (mem:SI (plus:SI (reg:SI 28 r28) - // (const_int 65536))) - // (reg:SI 0 r0)) -1 (insn_list 528 (insn_list 1507 (nil))) - // (nil)) - // /usr/lynx/home2/jose/98r2/src/gcc/toplev.c:1489: Internal compiler error in function fatal_insn - // to be thrown at the end of the function. - if ((proxy = allocate_and_bind_proxy(module,from_address)) == 0) - return 0; - } - - // Have the proxy process the message and do the right thing. - if (proxy->receive_message (buffer, r) != 0) - { - (void) this->map_.unbind (from_address); - this->factory_->destroy (proxy->next ()); - delete proxy; - } - - return 0; -} - -ACE_HANDLE -ACE_RMCast_IO_UDP::get_handle (void) const -{ - return this->dgram_.get_handle (); -} - -int -ACE_RMCast_IO_UDP::data (ACE_RMCast::Data &data) -{ - return this->send_data (data, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::poll (ACE_RMCast::Poll &poll) -{ - return this->send_poll (poll, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - return this->send_ack_join (ack_join, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::ack_leave (ACE_RMCast::Ack_Leave &ack_leave) -{ - return this->send_ack_leave (ack_leave, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::ack (ACE_RMCast::Ack &ack) -{ - return this->send_ack (ack, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::join (ACE_RMCast::Join &join) -{ - return this->send_join (join, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::leave (ACE_RMCast::Leave &leave) -{ - return this->send_leave (leave, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::send_data (ACE_RMCast::Data &data, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_data - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // The first message block contains the header - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - ACE_UINT32 tmp; - char header[1 + 3 * sizeof(ACE_UINT32)]; - header[0] = ACE_RMCast::RMCAST_MT_DATA; - - tmp = ACE_HTONL (data.sequence_number); - ACE_OS::memcpy (header + 1, - &tmp, sizeof(ACE_UINT32)); - tmp = ACE_HTONL (data.total_size); - ACE_OS::memcpy (header + 1 + sizeof(ACE_UINT32), - &tmp, sizeof(ACE_UINT32)); - tmp = ACE_HTONL (data.fragment_offset); - ACE_OS::memcpy (header + 1 + 2 * sizeof(ACE_UINT32), - &tmp, sizeof(ACE_UINT32)); - - iovec iov[ACE_IOV_MAX]; - int iovcnt = 1; - - iov[0].iov_base = header; - iov[0].iov_len = sizeof(header); - - ACE_Message_Block *mb = data.payload; - - for (const ACE_Message_Block *i = mb; i != 0; i = i->cont ()) - { - iov[iovcnt].iov_base = i->rd_ptr (); - iov[iovcnt].iov_len = static_cast<u_long> (i->length ()); - iovcnt++; - if (iovcnt >= IOV_MAX) - return -1; - } - - // @@ This pacing stuff here reduced the number of packet lost in - // loopback tests, but it should be taken out for real applications - // (or at least made configurable!) - ACE_Time_Value tv (0, 10000); - ACE_OS::sleep (tv); - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (iov, iovcnt, to) == -1) - return -1; - -#if 0 - ACE_HEX_DUMP ((LM_DEBUG, - (char*)iov[0].iov_base, - iov[0].iov_len, - "Sending")); -#endif - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_poll (ACE_RMCast::Poll &, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_poll - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_POLL; - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1, to) == -1) - return -1; - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_ack_join (ACE_RMCast::Ack_Join &ack_join, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_ack_join - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_ACK_JOIN; - - ACE_UINT32 tmp = ACE_HTONL (ack_join.next_sequence_number); - ACE_OS::memcpy (header + 1, - &tmp, sizeof(ACE_UINT32)); - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1 + sizeof(ACE_UINT32), to) == -1) - return -1; - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_ack_leave (ACE_RMCast::Ack_Leave &, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_ack_leave - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_ACK_LEAVE; - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1, to) == -1) - return -1; - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_ack (ACE_RMCast::Ack &ack, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_ack - pushing (%d:%d) out to <%s:%d>\n", - // ack.next_expected, - // ack.highest_received, - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_ACK; - - ACE_UINT32 tmp = ACE_HTONL (ack.next_expected); - ACE_OS::memcpy (header + 1, - &tmp, sizeof(ACE_UINT32)); - tmp = ACE_HTONL (ack.highest_received); - ACE_OS::memcpy (header + 1 + sizeof(ACE_UINT32), - &tmp, sizeof(ACE_UINT32)); - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1 + 2*sizeof(ACE_UINT32), to) == -1) - return -1; - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_join (ACE_RMCast::Join &, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_join - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_JOIN; - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1, to) == -1) - return -1; - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_leave (ACE_RMCast::Leave &, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_leave - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_LEAVE; - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1, to) == -1) - return -1; - - return 0; -} - - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - -template class ACE_Hash_Map_Manager<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Null_Mutex>; -template class ACE_Hash_Map_Manager_Ex<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Hash<ACE_INET_Addr>,ACE_Equal_To<ACE_INET_Addr>,ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator_Ex<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Hash<ACE_INET_Addr>,ACE_Equal_To<ACE_INET_Addr>,ACE_Null_Mutex>; -template class ACE_Hash_Map_Reverse_Iterator_Ex<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Hash<ACE_INET_Addr>,ACE_Equal_To<ACE_INET_Addr>,ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator_Base_Ex<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Hash<ACE_INET_Addr>,ACE_Equal_To<ACE_INET_Addr>,ACE_Null_Mutex>; -template class ACE_Hash_Map_Entry<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*>; -template class ACE_Equal_To<ACE_INET_Addr>; -template class ACE_Hash<ACE_INET_Addr>; - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/ace/RMCast/RMCast_IO_UDP.h b/ace/RMCast/RMCast_IO_UDP.h deleted file mode 100644 index 9cad38a0506..00000000000 --- a/ace/RMCast/RMCast_IO_UDP.h +++ /dev/null @@ -1,138 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = DESCRIPTION -// Encapsulate the I/O layer for a UDP based receiver -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_IO_UDP_H -#define ACE_RMCAST_IO_UDP_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "ace/SOCK_Dgram_Mcast.h" -#include "ace/Hash_Map_Manager.h" -#include "ace/INET_Addr.h" -#include "ace/Null_Mutex.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_UDP_Proxy; -class ACE_RMCast_Module_Factory; -class ACE_Time_Value; - -class ACE_RMCast_Export ACE_RMCast_IO_UDP : public ACE_RMCast_Module -{ -public: - //! Constructor - /*! - * The <factory> argument is used to create the modules for each - * proxy that process incoming messages. The class does *not* assume - * ownership of <factory>, the caller owns it. But it does assume - * ownership of the modules returned by the factory, and it may ask - * the factory to release them eventually. - */ - ACE_RMCast_IO_UDP (ACE_RMCast_Module_Factory *factory); - - //! Destructor - ~ACE_RMCast_IO_UDP (void); - - /// Open the internal socket, but only to send multicast data. - /** - * It is not clear to me if this is a valid configuration. Maybe it - * would be a problem to expose two separate, incompatible - * interfaces (check the subscribe() method). However, the - * alternative would be to implement almost identical class for - * outgoing and incoming UDP I/O - */ - int init (const ACE_INET_Addr &mcast_group, - const ACE_Addr &local, - int protocol_family = PF_INET, - int protocol = 0, - int reuse_addr = 0); - - //! Join a new multicast group - /*! - * Start receiving data for the <mcast_addr> multicast group. - * Please read the documentation of ACE_SOCK_Dgram_Mcast for more - * details. - */ - int subscribe (const ACE_INET_Addr &mcast_addr, - int reuse_addr = 1, - const ACE_TCHAR *net_if = 0, - int protocol_family = PF_INET, - int protocol = 0); - - // The class can be used with a Reactor or using blocking I/O - // depending on what method of the following two is called. - - //! Wait for events for the period <tv>. If <tv> is zero it blocks - //! forever. - int handle_events (ACE_Time_Value *tv = 0); - - //! There is data to read, read it and process it. - int handle_input (ACE_HANDLE h); - - //! Obtain the handle for the underlying socket - ACE_HANDLE get_handle (void) const; - - //@{ - //! Send the message to the ACE_INET_Addr argument. - /*! - * These methods are used in the implementation of the - * ACE_RMCast_UDP_Proxy objects and the implementation of the - * inherited ACE_RMCast_Module methods in this class. - */ - int send_data (ACE_RMCast::Data &, const ACE_INET_Addr &); - int send_poll (ACE_RMCast::Poll &, const ACE_INET_Addr &); - int send_ack_join (ACE_RMCast::Ack_Join &, const ACE_INET_Addr &); - int send_ack_leave (ACE_RMCast::Ack_Leave &, const ACE_INET_Addr &); - int send_ack (ACE_RMCast::Ack &, const ACE_INET_Addr &); - int send_join (ACE_RMCast::Join &, const ACE_INET_Addr &); - int send_leave (ACE_RMCast::Leave &, const ACE_INET_Addr &); - //@} - - // Please read the documentation in ACE_RMCast_Module for more details - virtual int data (ACE_RMCast::Data &); - virtual int poll (ACE_RMCast::Poll &); - virtual int ack_join (ACE_RMCast::Ack_Join &); - virtual int ack_leave (ACE_RMCast::Ack_Leave &); - virtual int ack (ACE_RMCast::Ack &); - virtual int join (ACE_RMCast::Join &); - virtual int leave (ACE_RMCast::Leave &); - -private: - - // This is necessary to satisfy the stupid xgcc for Lynx on Solaris - // The compiler barfs up lisp code errors - ACE_RMCast_UDP_Proxy *allocate_and_bind_proxy (ACE_RMCast_Module *module, - const ACE_INET_Addr &); - - //! The factory used to create the modules attached to each proxy - ACE_RMCast_Module_Factory *factory_; - - //! The multicast group we subscribe and send to - ACE_INET_Addr mcast_group_; - - //! The socket used to receive and send data - ACE_SOCK_Dgram_Mcast dgram_; - - //! Use a Hash_Map to maintain the collection of proxies - typedef ACE_Hash_Map_Manager<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Null_Mutex> Map; - //! The collection of proxies - Map map_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_IO_UDP.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_IO_UDP_H */ diff --git a/ace/RMCast/RMCast_IO_UDP.i b/ace/RMCast/RMCast_IO_UDP.i deleted file mode 100644 index 5468ae292af..00000000000 --- a/ace/RMCast/RMCast_IO_UDP.i +++ /dev/null @@ -1,37 +0,0 @@ -// $Id$ - -#include "RMCast_UDP_Proxy.h" -#include "RMCast_Module_Factory.h" -#include "ace/OS_Memory.h" - -ACE_INLINE -ACE_RMCast_IO_UDP:: - ACE_RMCast_IO_UDP (ACE_RMCast_Module_Factory *factory) - : factory_ (factory), - dgram_ (ACE_SOCK_Dgram_Mcast::OPT_BINDADDR_NO) -{ -} - -// Workaround failure in gcc for lynx hosted on solaris -// see ACE_RMCast_IO_UDP::handle_input() for more details -ACE_INLINE ACE_RMCast_UDP_Proxy * -ACE_RMCast_IO_UDP::allocate_and_bind_proxy (ACE_RMCast_Module *module, - const ACE_INET_Addr& from_address) -{ - ACE_RMCast_UDP_Proxy *proxy; - ACE_NEW_RETURN (proxy, - ACE_RMCast_UDP_Proxy(this, - from_address), - 0); - proxy->next (module); - - if (this->map_.bind (from_address, proxy) != 0) - { - // @@ LOG?? - return 0; - } - - return proxy; -} - - diff --git a/ace/RMCast/RMCast_Membership.cpp b/ace/RMCast/RMCast_Membership.cpp deleted file mode 100644 index 7511c72f7fe..00000000000 --- a/ace/RMCast/RMCast_Membership.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Membership.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Membership.i" -#endif /* ! __ACE_INLINE__ */ - -#include "RMCast_Proxy.h" -#include "ace/Guard_T.h" - -ACE_RCSID(RMCast, RMCast_Membership, "$Id$") - -ACE_RMCast_Membership::~ACE_RMCast_Membership (void) -{ -} - -int -ACE_RMCast_Membership::has_members (void) -{ - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - - Proxy_Iterator end = this->proxies_.end (); - Proxy_Iterator i = this->proxies_.begin (); - return (i != end); -} - -int -ACE_RMCast_Membership::ack (ACE_RMCast::Ack &ack) -{ - //ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack (%d:%d)\n", - // ack.next_expected, ack.highest_received)); - - ACE_RMCast::Ack next_ack; - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - if (ack.next_expected < this->next_expected_) - { - // @@ This violates an invariant of the class, shouldn't - // happen... - //ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[2]\n")); - return 0; - } - else if (ack.next_expected == this->next_expected_) - { - // Nothing new, just continue.... - //ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[3]\n")); - return 0; - } - - int r = this->compute_ack_i (ack.source, next_ack); - if (r < 0) - return r; - if (r == 1) - return 0; - } - - //ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[4] (%d:%d)\n", - // next_ack.next_expected, next_ack.highest_received)); - - return this->ACE_RMCast_Module::ack (next_ack); -} - -int -ACE_RMCast_Membership::join (ACE_RMCast::Join &join) -{ - if (join.source == 0) - return 0; - - { - // ACE_DEBUG ((LM_DEBUG, - // "RMCast_Membership::join - %d\n", - // long(join.source))); - - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - if (this->proxies_.insert (join.source) == -1) - return -1; - } - (void) this->generate_ack (join.source); - - return this->ACE_RMCast_Module::join (join); -} - -int -ACE_RMCast_Membership::leave (ACE_RMCast::Leave &leave) -{ - if (leave.source == 0) - return 0; - - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - (void) this->proxies_.remove (leave.source); - } - (void) this->generate_ack (leave.source); - - return this->ACE_RMCast_Module::leave (leave); -} - -int -ACE_RMCast_Membership::generate_ack (ACE_RMCast_Proxy *proxy) -{ - ACE_RMCast::Ack next_ack; - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - int r = this->compute_ack_i (proxy, next_ack); - if (r < 0) - return r; - if (r == 1) - return 0; - } - - //ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[6] (%d:%d)\n", - // next_ack.next_expected, next_ack.highest_received)); - - return this->ACE_RMCast_Module::ack (next_ack); -} - -int -ACE_RMCast_Membership::compute_ack_i (ACE_RMCast_Proxy *source, - ACE_RMCast::Ack &next_ack) -{ - Proxy_Iterator end = this->proxies_.end (); - Proxy_Iterator i = this->proxies_.begin (); - if (i == end) - return 1; - - //ACE_DEBUG ((LM_DEBUG, - // "RMCast_Membership::generate_ack[1] - %d -> (%d:%d)\n", - // long(*i), - // (*i)->next_expected (), - // (*i)->highest_received ())); - - ACE_UINT32 next_expected = (*i)->next_expected (); - ACE_UINT32 highest_received = (*i)->highest_received (); - ++i; - - for (; i != end; ++i) - { - // ACE_DEBUG ((LM_DEBUG, - // "RMCast_Membership::generate_ack[2] - %d -> (%d:%d)\n", - // long(*i), - // (*i)->next_expected (), - // (*i)->highest_received ())); - - ACE_UINT32 s = (*i)->next_expected (); - if (s < next_expected) - next_expected = s; - ACE_UINT32 r = (*i)->highest_received (); - if (r > highest_received) - highest_received = r; - } -#if 0 - // @@TODO: this is an important feature, disabled until it is - // fully debugged - if (this->next_expected_ >= next_expected - || this->highest_received_ >= highest_received) - { - // No change.... - ACE_DEBUG ((LM_DEBUG, - "RMCast_Membership::generate_ack[3]\n")); - return 1; - } -#endif /* 0 */ - this->next_expected_ = next_expected; - this->highest_received_ = highest_received; - next_ack.source = source; - next_ack.next_expected = this->next_expected_; - next_ack.highest_received = this->highest_received_; - - //ACE_DEBUG ((LM_DEBUG, - // "RMCast_Membership::generate_ack[4] - (%d:%d)\n", - // next_ack.next_expected, - // next_ack.highest_received)); - - return 0; -} - -#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/ace/RMCast/RMCast_Membership.h b/ace/RMCast/RMCast_Membership.h deleted file mode 100644 index d6bbbe503f9..00000000000 --- a/ace/RMCast/RMCast_Membership.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Membership.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_MEMBERSHIP_H -#define ACE_RMCAST_MEMBERSHIP_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "ace/Containers.h" -#include "ace/Synch_Traits.h" -#include "ace/Thread_Mutex.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_Proxy; - -/// Track peer membership -/** - * Reliable senders of events need to know exactly how many peers are - * receiving the events, and how many events has each peer received so - * far. - * This class uses the Join, Leave and Ack messages to build that - * information, it also summarizes the Ack events and propagate only - * the global info to the upper layer. - */ -class ACE_RMCast_Export ACE_RMCast_Membership : public ACE_RMCast_Module -{ -public: - /// Constructor - ACE_RMCast_Membership (void); - - /// Destructor - virtual ~ACE_RMCast_Membership (void); - - /// Return 1 if there are still members in the group - int has_members (void); - - /// Receive an process an Ack message - /** - * After receiving the Ack message we find out what is the lowest - * sequence number received in order among all the acks received by - * the proxies in the collection. We also find out what is the - * highest sequence number received by any proxy. - * We only propagate that information back to the upper layer, and - * then only if there are any news since the last Ack. - */ - virtual int ack (ACE_RMCast::Ack &); - - /// Add a new member to the collection, using the <source> field in - /// the Join message - virtual int join (ACE_RMCast::Join &); - - /// Remove a member from the collection, using the <source> field in - /// the Join message - virtual int leave (ACE_RMCast::Leave &); - -private: - /// Generate an Ack message, normally due to changes in the - /// collection, such as new proxys joining or leaving - int generate_ack (ACE_RMCast_Proxy *proxy); - - /// Compute an Ack message to propagate to the upper layers. - int compute_ack_i (ACE_RMCast_Proxy *source, - ACE_RMCast::Ack &next_ack); - -protected: - /// Use an unbounded set to maintain the collection of proxies. - typedef ACE_Unbounded_Set<ACE_RMCast_Proxy*> Proxy_Collection; - typedef ACE_Unbounded_Set_Iterator<ACE_RMCast_Proxy*> Proxy_Iterator; - - /// The collection of proxies - Proxy_Collection proxies_; - - /// The smallest value of next_expected for all the proxies - ACE_UINT32 next_expected_; - - /// The highest value of highest_received for all the proxies - ACE_UINT32 highest_received_; - - /// Synchronization - ACE_SYNCH_MUTEX mutex_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Membership.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_MEMBERSHIP_H */ diff --git a/ace/RMCast/RMCast_Membership.i b/ace/RMCast/RMCast_Membership.i deleted file mode 100644 index b513c2d5141..00000000000 --- a/ace/RMCast/RMCast_Membership.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Membership::ACE_RMCast_Membership (void) - : next_expected_ (0) - , highest_received_ (0) -{ -} diff --git a/ace/RMCast/RMCast_Module.cpp b/ace/RMCast/RMCast_Module.cpp deleted file mode 100644 index d2b954ee03b..00000000000 --- a/ace/RMCast/RMCast_Module.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Module.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Module.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Module, "$Id$") - -ACE_RMCast_Module::~ACE_RMCast_Module (void) -{ -} - -int -ACE_RMCast_Module::next (ACE_RMCast_Module *next) -{ - if (this->next_ != 0 && next != 0) - return 1; - this->next_ = next; - return 0; -} - -ACE_RMCast_Module * -ACE_RMCast_Module::next (void) const -{ - return this->next_; -} - -int -ACE_RMCast_Module::open (void) -{ - if (this->next () != 0) - return this->next ()->open (); - return 0; -} - -int -ACE_RMCast_Module::close (void) -{ - if (this->next () != 0) - return this->next ()->close (); - return 0; -} - -int -ACE_RMCast_Module::data (ACE_RMCast::Data &data) -{ - if (this->next () != 0) - return this->next ()->data (data); - return 0; -} - -int -ACE_RMCast_Module::poll (ACE_RMCast::Poll &poll) -{ - if (this->next () != 0) - return this->next ()->poll (poll); - return 0; -} - -int -ACE_RMCast_Module::ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - if (this->next () != 0) - return this->next ()->ack_join (ack_join); - return 0; -} - -int -ACE_RMCast_Module::ack_leave (ACE_RMCast::Ack_Leave &ack_leave) -{ - if (this->next () != 0) - return this->next ()->ack_leave (ack_leave); - return 0; -} - -int -ACE_RMCast_Module::ack (ACE_RMCast::Ack &ack) -{ - if (this->next () != 0) - return this->next ()->ack (ack); - return 0; -} - -int -ACE_RMCast_Module::join (ACE_RMCast::Join &join) -{ - if (this->next () != 0) - return this->next ()->join (join); - return 0; -} - -int -ACE_RMCast_Module::leave (ACE_RMCast::Leave &leave) -{ - if (this->next () != 0) - return this->next ()->leave (leave); - return 0; -} diff --git a/ace/RMCast/RMCast_Module.h b/ace/RMCast/RMCast_Module.h deleted file mode 100644 index 8497b367776..00000000000 --- a/ace/RMCast/RMCast_Module.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Module.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_MODULE_H -#define ACE_RMCAST_MODULE_H -#include /**/ "ace/pre.h" - -#include "RMCast.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -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 -{ -public: - //! Constructor - ACE_RMCast_Module (void); - - //! Destructor - virtual ~ACE_RMCast_Module (void); - - //! Modifier for the next element in the stack - virtual int next (ACE_RMCast_Module *next); - - //! Accesor for the next element in the stack - virtual ACE_RMCast_Module* next (void) const; - - //! Initialize the module, setting up the next module - virtual int open (void); - - //! Close the module. - virtual int close (void); - - //! Push data through the stack - virtual int data (ACE_RMCast::Data &); - - //! Push a polling request through the stack - virtual int poll (ACE_RMCast::Poll &); - - //! Push a message to ack a join request through the stack - virtual int ack_join (ACE_RMCast::Ack_Join &); - - //! Push a message to ack a leave request through the stack - virtual int ack_leave (ACE_RMCast::Ack_Leave &); - - //! Push an ack mesage through the stack - virtual int ack (ACE_RMCast::Ack &); - - //! Push a join message through the stack - virtual int join (ACE_RMCast::Join &); - - //! Push a leave message through the stack - virtual int leave (ACE_RMCast::Leave &); - -private: - //! The next element in the stack - ACE_RMCast_Module *next_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Module.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_MODULE_H */ diff --git a/ace/RMCast/RMCast_Module.i b/ace/RMCast/RMCast_Module.i deleted file mode 100644 index af299d706e3..00000000000 --- a/ace/RMCast/RMCast_Module.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Module::ACE_RMCast_Module (void) - : next_ (0) -{ -} diff --git a/ace/RMCast/RMCast_Module_Factory.cpp b/ace/RMCast/RMCast_Module_Factory.cpp deleted file mode 100644 index a693c0f0bf5..00000000000 --- a/ace/RMCast/RMCast_Module_Factory.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// $Id$ - -#include "RMCast_Module_Factory.h" - -ACE_RCSID(RMCast, RMCast_Module_Factory, "$Id$") - -ACE_RMCast_Module_Factory::~ACE_RMCast_Module_Factory (void) -{ -} diff --git a/ace/RMCast/RMCast_Module_Factory.h b/ace/RMCast/RMCast_Module_Factory.h deleted file mode 100644 index eada18f8aca..00000000000 --- a/ace/RMCast/RMCast_Module_Factory.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Module_Factory.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_MODULE_FACTORY_H -#define ACE_RMCAST_MODULE_FACTORY_H -#include /**/ "ace/pre.h" - -#include "RMCast.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_Module; -class ACE_RMCast_IO_UDP; - -//! Create Module stacks -/*! - * Different application will probably require different - * configurations in their Module stack, some will just want best - * effort semantics. Others will use Reliable communication with a - * maximum retransmission time. Furthermore, applications may want to - * receive messages in send order, or just as soon as they are - * received. - * Obviously most applications will want to change want happens once a - * message is completely received. - * - * To achieve all this flexibility the IO layer uses this factory to - * create the full stack of Modules corresponding to a single - * consumer. - * To keep the complexity under control the intention is to create - * helper Factories, such as Reliable_Module_Factory where - * applications only need to customize a few features. - */ -class ACE_RMCast_Export ACE_RMCast_Module_Factory -{ -public: - //! Destructor - virtual ~ACE_RMCast_Module_Factory (void); - - //! Create a new proxy - virtual ACE_RMCast_Module *create (void) = 0; - - //! Destroy a proxy - /*! - * Some factories may allocate modules from a pool, or return the - * same module for all proxies. Consequently, only the factory - * knows how to destroy them. - */ - virtual void destroy (ACE_RMCast_Module *) = 0; -}; - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_MODULE_FACTORY_H */ diff --git a/ace/RMCast/RMCast_Partial_Message.cpp b/ace/RMCast/RMCast_Partial_Message.cpp deleted file mode 100644 index 5b5101a23dd..00000000000 --- a/ace/RMCast/RMCast_Partial_Message.cpp +++ /dev/null @@ -1,216 +0,0 @@ -// $Id$ - -#include "RMCast_Partial_Message.h" -#include "ace/OS_NS_string.h" - -#if !defined (__ACE_INLINE__) -#include "RMCast_Partial_Message.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Partial_Message, "$Id$") - -ACE_RMCast_Partial_Message:: -ACE_RMCast_Partial_Message (ACE_UINT32 message_size) - : max_hole_count_ (ACE_RMCAST_DEFAULT_HOLE_COUNT), - hole_count_ (1) -{ - ACE_NEW (this->hole_list_, - ACE_RMCast_Partial_Message::Hole[this->max_hole_count_]); - this->hole_list_[0].start = 0; - this->hole_list_[0].end = message_size; - - this->message_body_.size (message_size); - this->message_body_.wr_ptr (message_size); -} - -ACE_RMCast_Partial_Message:: -~ACE_RMCast_Partial_Message (void) -{ - delete[] this->hole_list_; -} - -int -ACE_RMCast_Partial_Message::fragment_received (ACE_UINT32 message_size, - ACE_UINT32 offset, - ACE_Message_Block *mb) -{ - if (this->message_body_.length () != message_size) - { - // ACE_DEBUG ((LM_DEBUG, - // "Partial_Message::fragment_received - " - // "invalid message length\n")); - return -1; - } - - // Just copy the data... - char *rd_ptr = this->message_body_.rd_ptr () + offset; - size_t total_length = 0; - { - for (const ACE_Message_Block *i = mb; i != 0; i = i->cont ()) - { - if (rd_ptr + i->length () > this->message_body_.wr_ptr ()) - { - // ACE_DEBUG ((LM_DEBUG, - // "Partial_Message::fragment_received - " - // "invalid payload length\n")); - return -1; - } - ACE_OS::memcpy (rd_ptr, i->rd_ptr (), i->length ()); - rd_ptr += i->length (); - total_length += i->length (); - } - } - - // The algorithm works like this: - // - // For each hole we determine if there is an intersection between - // the hole and the incoming fragment. If there is none we do - // nothing (actually since the holes are ordered we can stop the - // iteration if the - - ACE_UINT32 start = offset; - ACE_UINT32 end = static_cast<ACE_UINT32> (offset + total_length); - - while (start != end && this->hole_count_ != 0) - { - for (size_t i = 0; i < this->hole_count_; ++i) - { - Hole& hole = this->hole_list_[i]; - - // First check if the new data insersects the hole... - if (end <= hole.start) - return 0; - if (start >= hole.end) - { - if (i == this->hole_count_ - 1) - return 0; - else - continue; - } - - // The hole and the new fragment intersect, we have to - // update the hole list. - // - // There are only three cases for the <start> value: - // start < hole.start - // start == hole.start - // hole.start < start < hole.end - // - // But the code for both start == hole.start and start < - // hole.start is identical.... - - if (start <= hole.start) - { - if (end < hole.end) - { - // NOTE: hole.start < end, because of previous test - - // In this case we shrink the hole, but it is not - // removed! - hole.start = end; - return 0; - } - else // end >= hole.end - { - start = hole.end; - // We remove the hole, and continue the iteration... - if (this->remove_hole (i) == -1) - return -1; - break; - } - } - else // hole.start < start < hole.end - { - if (end >= hole.end) - { - // Just adjust the size of the hole... - ACE_UINT32 tmp = hole.end; - hole.end = start; - start = tmp; - break; - } - else // if (end < hole.end) - { - // Nasty, we need to insert a new hole... - if (this->insert_hole (i, end, hole.end) == -1) - return -1; - // and change the old hole... - // NOTE: we have to refetch it because the array may - // have been reallocated! - this->hole_list_[i].end = start; - return 0; - } - } - } - } - return 0; - // @@ OLD COMMENTS, the algorithm has changed since! - // There are several cases: - // - // 1) The fragment is completely contained in data already received, - // nothing changes in this case. - // - // 2) Part of the fragment is contained in data already received and - // part is new data: - // 2.1) The new data closes a hole, remove it from the list - // 2.2) The beginning of the new fragment is the new data, reduce - // the size of the hole - // 2.3) The end of the new fragment is the new data, increment - // the size of the received block - // - // 3) The fragment is completely contained in a hole - // 3.1) It closes the hole, remove it from the list - // 3.2) It starts at the beginning of a hole, grow the received - // block - // 3.3) It ends at the end of a hole, reduce the hole size - // 3.4) It is in the middle of a hole, insert a new hole - // -} - -int -ACE_RMCast_Partial_Message::insert_hole (size_t i, - ACE_UINT32 start, - ACE_UINT32 end) -{ - // ACE_DEBUG ((LM_DEBUG, - // "Partial_Message::insert_hole %d = [%d,%d]\n", - // i, start, end)); - if (this->hole_count_ + 1 > this->max_hole_count_) - { - this->max_hole_count_ *= 2; - Hole *tmp; - ACE_NEW_RETURN (tmp, Hole[this->max_hole_count_], -1); - for (size_t j = 0; j != this->hole_count_; ++j) - { - tmp[j] = this->hole_list_[j]; - } - delete[] this->hole_list_; - this->hole_list_ = tmp; - } - if (this->hole_count_ != 0) - { - for (size_t j = this->hole_count_ - 1; j >= i + 1; --j) - { - this->hole_list_[j+1] = this->hole_list_[j]; - } - } - - this->hole_list_[i + 1].start = start; - this->hole_list_[i + 1].end = end; - this->hole_count_++; - - return 0; -} - -int -ACE_RMCast_Partial_Message::remove_hole (size_t i) -{ - // ACE_DEBUG ((LM_DEBUG, - // "Partial_Message::remove_hole %d\n", - // i)); - for (size_t j = i; j != this->hole_count_ - 1; ++j) - this->hole_list_[j] = this->hole_list_[j + 1]; - - this->hole_count_--; - return 0; -} diff --git a/ace/RMCast/RMCast_Partial_Message.h b/ace/RMCast/RMCast_Partial_Message.h deleted file mode 100644 index 0c14cd7828a..00000000000 --- a/ace/RMCast/RMCast_Partial_Message.h +++ /dev/null @@ -1,102 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = DESCRIPTION -// Helper class used in the reassembly layer of the realiable -// multicast library. -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_PARTIAL_MESSAGE_H -#define ACE_RMCAST_PARTIAL_MESSAGE_H -#include /**/ "ace/pre.h" - -#include "RMCast_Export.h" -#include "ace/Task.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#ifndef ACE_RMCAST_DEFAULT_HOLE_COUNT -#define ACE_RMCAST_DEFAULT_HOLE_COUNT 16 -#endif /* ACE_RMCAST_DEFAULT_HOLE_COUNT */ - -//! Represent a partially received message in the -//! ACE_RMCast_Reassembly module -/*! - * This class provides temporary storage for the fragments as they are - * received in the ACE_RMCast_Reassembly module. It also keeps track - * of what portions of the message are still missing. - */ -class ACE_RMCast_Export ACE_RMCast_Partial_Message -{ -public: - //! Constructor, reserve enough memory for the complete message - ACE_RMCast_Partial_Message (ACE_UINT32 message_size); - - //! Destructor - ~ACE_RMCast_Partial_Message (void); - - //! Process a fragment - /*! - * A fragment starting at <offset> has been received, copy the - * fragment contents and update the list of holes. - */ - int fragment_received (ACE_UINT32 message_size, - ACE_UINT32 offset, - ACE_Message_Block *mb); - - //! Return 1 if the message is complete - int is_complete (void) const; - - //! Return the body of the message, the memory is *not* owned by the - //! caller - ACE_Message_Block *message_body (void); - -private: - //! Insert a new hole into the list - /*! - * The class keeps an array to represent the missing portions of the - * message. This method inserts a new hole, i.e. a new element in - * the array at index <i>. The <start> and <end> arguments represent - * the offsets of the missing portion of the message. - */ - int insert_hole (size_t i, - ACE_UINT32 start, - ACE_UINT32 end); - - //! Remove a hole from the list - int remove_hole (size_t i); - -private: - //! Maintain the message storage - ACE_Message_Block message_body_; - - //! Represent a missing portion of a message - struct Hole - { - //! Offset where the missing portion of the message starts - ACE_UINT32 start; - //! Offset where the missing portion of the message ends - ACE_UINT32 end; - }; - - //! Implement a growing array of Hole structures - //@{ - Hole *hole_list_; - size_t max_hole_count_; - size_t hole_count_; - //@} -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Partial_Message.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_PARTIAL_MESSAGE_H */ diff --git a/ace/RMCast/RMCast_Partial_Message.i b/ace/RMCast/RMCast_Partial_Message.i deleted file mode 100644 index 7be89aa1932..00000000000 --- a/ace/RMCast/RMCast_Partial_Message.i +++ /dev/null @@ -1,15 +0,0 @@ -// $Id$ - -ACE_INLINE int -ACE_RMCast_Partial_Message::is_complete (void) const -{ - return (this->hole_count_ == 0) - || (this->hole_count_ == 1 - && this->hole_list_[0].start == this->hole_list_[0].end); -} - -ACE_INLINE ACE_Message_Block * -ACE_RMCast_Partial_Message::message_body (void) -{ - return &this->message_body_; -} diff --git a/ace/RMCast/RMCast_Proxy.cpp b/ace/RMCast/RMCast_Proxy.cpp deleted file mode 100644 index 6aa870ea702..00000000000 --- a/ace/RMCast/RMCast_Proxy.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Proxy.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Proxy.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Proxy, "$Id$") - -ACE_RMCast_Proxy::~ACE_RMCast_Proxy (void) -{ -} - -ACE_UINT32 -ACE_RMCast_Proxy::next_expected (void) const -{ - return this->next_expected_; -} - -ACE_UINT32 -ACE_RMCast_Proxy::highest_received (void) const -{ - return this->highest_received_; -} - -int -ACE_RMCast_Proxy::ack (ACE_RMCast::Ack &ack) -{ - this->next_expected_ = ack.next_expected; - this->highest_received_ = ack.highest_received; - return this->ACE_RMCast_Module::ack (ack); -} - -int -ACE_RMCast_Proxy::reply_ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - if (this->next_expected_ < ack_join.next_sequence_number) - { - this->next_expected_ = ack_join.next_sequence_number; - this->highest_received_ = ack_join.next_sequence_number; - } - return 0; -} diff --git a/ace/RMCast/RMCast_Proxy.h b/ace/RMCast/RMCast_Proxy.h deleted file mode 100644 index 303a5e8ffe4..00000000000 --- a/ace/RMCast/RMCast_Proxy.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Proxy.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_PROXY_H -#define ACE_RMCAST_PROXY_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -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 -{ -public: - //! Constructor - ACE_RMCast_Proxy (void); - // Constructor - - //! Destructor - virtual ~ACE_RMCast_Proxy (void); - - //! Return the next sequence number expected by the peer. Only - //! applies to remote receiver proxies. - /*! - * Please read the documentation in ACE_RMCast::Ack - */ - virtual ACE_UINT32 next_expected (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; - - //@{ - //! 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 &); - virtual int reply_ack_leave (ACE_RMCast::Ack_Leave &) = 0; - virtual int reply_ack (ACE_RMCast::Ack &) = 0; - virtual int reply_join (ACE_RMCast::Join &) = 0; - virtual int reply_leave (ACE_RMCast::Leave &) = 0; - //@} - - /*! - * Proxies process the ACK sequence numbers to cache the ack - * information from the peer. - */ - virtual int ack (ACE_RMCast::Ack &); - -private: - //@{ - //! Cache the sequence numbers reported from the remote peer using - //! Ack messages - ACE_UINT32 next_expected_; - ACE_UINT32 highest_received_; - //@} -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Proxy.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_PROXY_H */ diff --git a/ace/RMCast/RMCast_Proxy.i b/ace/RMCast/RMCast_Proxy.i deleted file mode 100644 index 6fee09fe9e5..00000000000 --- a/ace/RMCast/RMCast_Proxy.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Proxy::ACE_RMCast_Proxy (void) - : next_expected_ (0) - , highest_received_ (0) -{ -} diff --git a/ace/RMCast/RMCast_Reassembly.cpp b/ace/RMCast/RMCast_Reassembly.cpp deleted file mode 100644 index 7f48b06d5e1..00000000000 --- a/ace/RMCast/RMCast_Reassembly.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// $Id$ - -#include "RMCast_Reassembly.h" -#include "RMCast_Partial_Message.h" -#include "ace/Message_Block.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -ACE_RCSID(RMCast, RMCast_Reassembly, "$Id$") - -ACE_RMCast_Reassembly:: -ACE_RMCast_Reassembly (void) - : ACE_RMCast_Module () -{ -} - -ACE_RMCast_Reassembly::~ACE_RMCast_Reassembly (void) -{ - (void) this->close_i (); -} - -/** - * - * We cleanup the resources in the destructor - */ -int -ACE_RMCast_Reassembly::close () -{ - this->close_i (); - return this->ACE_RMCast_Module::close (); -} - -int -ACE_RMCast_Reassembly::data (ACE_RMCast::Data &data) -{ - if (this->next () == 0) - return 0; - - // ACE_DEBUG ((LM_DEBUG, - // "Reassembly::data - %d,%d,%d\n", - // data.sequence_number, - // data.total_size, - // data.fragment_offset)); - - if (data.payload->length () + data.fragment_offset > data.total_size) - { - ACE_ERROR ((LM_ERROR, - "RMCast_Reassembly::data - invalid size\n")); - return -1; // Corrupt message? - } - - ACE_RMCast_Partial_Message *message; - - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - if (this->messages_.find (data.sequence_number, message) == -1) - { - ACE_NEW_RETURN (message, - ACE_RMCast_Partial_Message (data.total_size), - -1); - - // ACE_DEBUG ((LM_DEBUG, - // "Reassembly::data - new message\n")); - if (this->messages_.bind (data.sequence_number, - message) == -1) - return -1; // Internal error? - } - - if (message->fragment_received (data.total_size, - data.fragment_offset, - data.payload) == -1) - { - // ACE_DEBUG ((LM_DEBUG, - // "Error in fragment_received\n")); - return -1; - } - - if (!message->is_complete ()) - { - // ACE_DEBUG ((LM_DEBUG, - // "Reassembly::data - message still incomplete\n")); - return 0; - } - - if (this->messages_.unbind (data.sequence_number) == -1) - { - // ACE_DEBUG ((LM_DEBUG, - // "Reassembly::data - message now complete\n")); - return -1; - } - } - - // Push the message... - ACE_RMCast::Data downstream_data; - downstream_data.source = data.source; - downstream_data.sequence_number = data.sequence_number; - downstream_data.total_size = static_cast<ACE_UINT32> (message->message_body ()->length ()); - downstream_data.fragment_offset = 0; - downstream_data.payload = message->message_body (); - - int r = this->next ()->data (downstream_data); - - delete message; - - return r; -} - -void -ACE_RMCast_Reassembly::close_i (void) -{ - for (Message_Map_Iterator i = this->messages_.begin (); - i != this->messages_.end (); - ++i) - { - ACE_RMCast_Partial_Message *message = (*i).int_id_; - if (message != 0) - delete message; - } - this->messages_.unbind_all (); -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - -template class ACE_Hash_Map_Manager<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Null_Mutex>; -template class ACE_Hash_Map_Manager_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex >; -template class ACE_Hash_Map_Reverse_Iterator_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex >; -template class ACE_Hash_Map_Iterator_Base_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex >; -template class ACE_Hash_Map_Entry<ACE_UINT32,ACE_RMCast_Partial_Message*>; - -template class ACE_Less_Than<ACE_UINT32>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Hash_Map_Manager<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Null_Mutex> -#pragma instantiate ACE_Hash_Map_Manager_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex> -#pragma instantiate ACE_Hash_Map_Iterator<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Null_Mutex> -#pragma instantiate ACE_Hash_Map_Iterator_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex > -#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex > -#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex > -#pragma instantiate ACE_Hash_Map_Entry<ACE_UINT32,ACE_RMCast_Partial_Message*> - -#pragma instantiate ACE_Less_Than<ACE_UINT32> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - diff --git a/ace/RMCast/RMCast_Reassembly.h b/ace/RMCast/RMCast_Reassembly.h deleted file mode 100644 index f6fc8989719..00000000000 --- a/ace/RMCast/RMCast_Reassembly.h +++ /dev/null @@ -1,71 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = DESCRIPTION -// The reassembly task for the reliable multicast library -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_REASSEMBLY_H -#define ACE_RMCAST_REASSEMBLY_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "ace/Hash_Map_Manager.h" -#include "ace/Synch_Traits.h" -#include "ace/Thread_Mutex.h" -#include "ace/Null_Mutex.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -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); - - //! Destructor - virtual ~ACE_RMCast_Reassembly (void); - - // = The ACE_RMCast_Module methods - virtual int close (void); - virtual int data (ACE_RMCast::Data &data); - -private: - /// Cleanup resources, but do not close the other modules in the - /// stack - void close_i (void); - -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> - Message_Map; - typedef - 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_; -}; - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_REASSEMBLY_H */ diff --git a/ace/RMCast/RMCast_Receiver_Module.cpp b/ace/RMCast/RMCast_Receiver_Module.cpp deleted file mode 100644 index 05e6ceb8c7f..00000000000 --- a/ace/RMCast/RMCast_Receiver_Module.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Receiver_Module.h" -#include "RMCast_Proxy.h" -#include "ace/Log_Msg.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Receiver_Module.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Receiver_Module, "$Id$") - -ACE_RMCast_Receiver_Module::~ACE_RMCast_Receiver_Module (void) -{ -} - -int -ACE_RMCast_Receiver_Module::data (ACE_RMCast::Data &data) -{ - switch (this->state_) - { - case RS_NON_EXISTENT: - case RS_JOINING: - if (data.source != 0) - { - //ACE_DEBUG ((LM_DEBUG, - // "Receiver_Module::data - joining\n")); - - this->state_ = RS_JOINING; - ACE_RMCast::Join join; - if (data.source->reply_join (join) != 0) - this->leaving (data.source); - } - break; - - case RS_JOINED: - // ACE_DEBUG ((LM_DEBUG, - // "Receiver_Module::data - joined\n")); - if (this->ACE_RMCast_Module::data (data) != 0) - this->leaving (data.source); - break; - - default: - case RS_LEAVING: - this->leaving (data.source); - break; - } - return 0; -} - -int -ACE_RMCast_Receiver_Module::poll (ACE_RMCast::Poll &poll) -{ - switch (this->state_) - { - case RS_NON_EXISTENT: - case RS_JOINING: - if (poll.source != 0) - { - this->state_ = RS_JOINING; - ACE_RMCast::Join join; - if (poll.source->reply_join (join) != 0) - this->leaving (poll.source); - } - break; - - case RS_JOINED: - if (this->ACE_RMCast_Module::poll (poll) != 0) - this->leaving (poll.source); - - default: - case RS_LEAVING: - this->leaving (poll.source); - break; - } - return 0; -} - -int -ACE_RMCast_Receiver_Module::ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - switch (this->state_) - { - case RS_NON_EXISTENT: - if (ack_join.source != 0) - { - //ACE_DEBUG ((LM_DEBUG, - // "Receiver_Module::ack_join - joining\n")); - - this->state_ = RS_JOINING; - ACE_RMCast::Join join; - if (ack_join.source->reply_join (join) != 0) - this->leaving (ack_join.source); - } - break; - - case RS_JOINING: - case RS_JOINED: - //ACE_DEBUG ((LM_DEBUG, - // "Receiver_Module::ack_join - joined\n")); - - this->state_ = RS_JOINED; - if (this->ACE_RMCast_Module::ack_join (ack_join) != 0) - this->leaving (ack_join.source); - break; - - default: - case RS_LEAVING: - this->leaving (ack_join.source); - break; - } - return 0; -} - -int -ACE_RMCast_Receiver_Module::ack_leave (ACE_RMCast::Ack_Leave &ack_leave) -{ - //ACE_DEBUG ((LM_DEBUG, - // "Receiver_Module::ack_leave\n")); - - (void) this->ACE_RMCast_Module::ack_leave (ack_leave); - - // Returning -1 should remove the Proxy from the local set - return -1; -} - -int -ACE_RMCast_Receiver_Module::ack (ACE_RMCast::Ack &) -{ - return -1; -} - -int -ACE_RMCast_Receiver_Module::join (ACE_RMCast::Join &) -{ - return -1; -} - -int -ACE_RMCast_Receiver_Module::leave (ACE_RMCast::Leave &) -{ - return -1; -} - -void -ACE_RMCast_Receiver_Module::leaving (ACE_RMCast_Proxy *proxy) -{ - this->state_ = RS_LEAVING; - if (proxy != 0) - { - ACE_RMCast::Leave leave; - (void) proxy->reply_leave (leave); - } - (void) this->close (); -} diff --git a/ace/RMCast/RMCast_Receiver_Module.h b/ace/RMCast/RMCast_Receiver_Module.h deleted file mode 100644 index 112ad768696..00000000000 --- a/ace/RMCast/RMCast_Receiver_Module.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace/RMCast -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_RECEIVER_MODULE_H -#define ACE_RMCAST_RECEIVER_MODULE_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Keep track of the receiver module. -/** - * A receiver proxy must reject invalid messages and communicate with - * the sender to join and leave the multicast group. - * - * This module performs all the task related to - * - */ -class ACE_RMCast_Export ACE_RMCast_Receiver_Module : public ACE_RMCast_Module -{ -public: - //! Constructor - ACE_RMCast_Receiver_Module (void); - - //! Destructor - virtual ~ACE_RMCast_Receiver_Module (void); - - virtual int data (ACE_RMCast::Data &); - virtual int poll (ACE_RMCast::Poll &); - virtual int ack_join (ACE_RMCast::Ack_Join &); - virtual int ack_leave (ACE_RMCast::Ack_Leave &); - virtual int ack (ACE_RMCast::Ack &); - virtual int join (ACE_RMCast::Join &); - virtual int leave (ACE_RMCast::Leave &); - - /// 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> - <BR> - DATA JOINING JOINING JOINED LEAVING<BR> - Send/Join Send/Join Recv/Data Send/Leave<BR> - <BR> - POLL JOINING JOINING JOINED LEAVING<BR> - Send/Join Send/Join Send/Ack Send/Leave<BR> - <BR> - ACK_JOIN JOINING JOINED JOINED LEAVING<BR> - Send/Join Receive Msg Receive Msg Send/Leave<BR> - <BR> - ACK_LEAVE NON_EXISTENT NON_EXISTENT NON_EXISTENT NON_EXISTENT<BR> - Noop Destroy Destroy Destroy<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> - </CODE> - */ - enum Receiver_State - { - RS_NON_EXISTENT, - RS_JOINING, - RS_JOINED, - RS_LEAVING - }; - -private: - /// Enter the leaving state, prepare for termination - void leaving (ACE_RMCast_Proxy *proxy); - -private: - /// The current state of the receiver - int state_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Receiver_Module.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_RECEIVER_MODULE_H */ diff --git a/ace/RMCast/RMCast_Receiver_Module.i b/ace/RMCast/RMCast_Receiver_Module.i deleted file mode 100644 index 6662f7f048a..00000000000 --- a/ace/RMCast/RMCast_Receiver_Module.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Receiver_Module::ACE_RMCast_Receiver_Module (void) - : state_ (ACE_RMCast_Receiver_Module::RS_NON_EXISTENT) -{ -} diff --git a/ace/RMCast/RMCast_Reliable_Factory.cpp b/ace/RMCast/RMCast_Reliable_Factory.cpp deleted file mode 100644 index b471af89c3d..00000000000 --- a/ace/RMCast/RMCast_Reliable_Factory.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// $Id$ - -#include "RMCast_Reliable_Factory.h" -#include "RMCast_Receiver_Module.h" -#include "RMCast_Reassembly.h" -#include "RMCast_Reordering.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Reliable_Factory.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Reliable_Factory, "$Id$") - -ACE_RMCast_Reliable_Factory::~ACE_RMCast_Reliable_Factory (void) -{ -} - -ACE_RMCast_Module* -ACE_RMCast_Reliable_Factory::create (void) -{ - ACE_RMCast_Module *receiver; - ACE_NEW_RETURN (receiver, ACE_RMCast_Receiver_Module, 0); - - ACE_RMCast_Module *reassembly; - ACE_NEW_RETURN (reassembly, ACE_RMCast_Reassembly, 0); - - ACE_RMCast_Module *reordering; - ACE_NEW_RETURN (reordering, ACE_RMCast_Reordering, 0); - - ACE_RMCast_Module *user = this->factory_->create (); - if (user == 0) - { - delete receiver; - delete reordering; - delete reassembly; - return 0; - } - receiver->next (reassembly); - reassembly->next (reordering); - reordering->next (user); - return receiver; -} - -void -ACE_RMCast_Reliable_Factory::destroy (ACE_RMCast_Module *receiver) -{ - ACE_RMCast_Module *reassembly = receiver->next (); - ACE_RMCast_Module *reordering = reassembly->next (); - ACE_RMCast_Module *user = reordering->next (); - this->factory_->destroy (user); - delete reordering; - delete reassembly; - delete receiver; -} diff --git a/ace/RMCast/RMCast_Reliable_Factory.h b/ace/RMCast/RMCast_Reliable_Factory.h deleted file mode 100644 index 8f9b9aa6aa1..00000000000 --- a/ace/RMCast/RMCast_Reliable_Factory.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Reliable_Factory.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_RELIABLE_FACTORY_H -#define ACE_RMCAST_RELIABLE_FACTORY_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module_Factory.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Implement an ACE_RMCast_Module_Factory that "creates" a single -/// object. -/** - * Many applications (and even some internal components), will use a - * single ACE_RMCast_Module to process all the events, for example, a - * receiver may decide to use the same ACE_RMCast_Module to process - * all incoming events, instead of using one per remote sender. - */ -class ACE_RMCast_Export ACE_RMCast_Reliable_Factory : public ACE_RMCast_Module_Factory -{ -public: - /// Constructor - ACE_RMCast_Reliable_Factory (ACE_RMCast_Module_Factory *factory); - - //! Destructor - virtual ~ACE_RMCast_Reliable_Factory (void); - - /** - * The create() method will return always @c reliable. - */ - virtual ACE_RMCast_Module *create (void); - virtual void destroy (ACE_RMCast_Module *); - -private: - /// Delegate on another factory to create the user module - ACE_RMCast_Module_Factory *factory_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Reliable_Factory.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_RELIABLE_FACTORY_H */ diff --git a/ace/RMCast/RMCast_Reliable_Factory.i b/ace/RMCast/RMCast_Reliable_Factory.i deleted file mode 100644 index 47ba22754ec..00000000000 --- a/ace/RMCast/RMCast_Reliable_Factory.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Reliable_Factory:: - ACE_RMCast_Reliable_Factory (ACE_RMCast_Module_Factory *factory) - : factory_ (factory) -{ -} diff --git a/ace/RMCast/RMCast_Reordering.cpp b/ace/RMCast/RMCast_Reordering.cpp deleted file mode 100644 index 1aebf27d8ee..00000000000 --- a/ace/RMCast/RMCast_Reordering.cpp +++ /dev/null @@ -1,179 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Reordering.h" -#include "RMCast_Proxy.h" -#include "ace/Guard_T.h" -#include "ace/Message_Block.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Reordering.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Reordering, "$Id$") - -ACE_RMCast_Reordering::~ACE_RMCast_Reordering (void) -{ -} - -int -ACE_RMCast_Reordering::close (void) -{ - Messages_Iterator i = this->messages_.begin (); - Messages_Iterator end = this->messages_.end (); - - while (i != end) - { - ACE_Message_Block::release ((*i).item ().payload); - this->messages_.unbind ((*i).key ()); - i = this->messages_.begin (); - } - return this->ACE_RMCast_Module::close (); -} - -int -ACE_RMCast_Reordering::data (ACE_RMCast::Data &data) -{ - int must_ack = 0; - int result = 0; - ACE_RMCast::Ack ack; - - //ACE_DEBUG ((LM_DEBUG, "Received message (%d)\n", data.sequence_number)); - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - - if (data.sequence_number < this->next_expected_) - { - // Old message. Ack with the current status (look at the end - // of this block). - must_ack = 1; - - //ACE_DEBUG ((LM_DEBUG, ".... old message is ignored\n")); - } - - else if (data.sequence_number == this->next_expected_) - { - //ACE_DEBUG ((LM_DEBUG, ".... message is in order, received\n")); - - // Accept the message, the current thread will dispatch it, so - // it is marked as accepted (using the <next_expected> field). - // Any other thread will not push that message because now it - // is "old". - - this->next_expected_++; - - // Right message, process as many messages as possible from - // the queue, then ack the right level... - - // NOTE: we cannot release the mutex while dispatching - // events, otherwise: how do we stop other threads from - // delivering messages out of order? I.E. what if the - // next thread receives the next message? - if (this->next () != 0) - { - result = this->next ()->data (data); - } - - // After delivering one message there may be more messages - // pending - if (result == 0) - result = this->push_queued_messages (); - - //@@ This should be strategized, for example, only Ack if - // there is a message out of order or something, otherwise - // continue with happiness. That works well for "optimistic - // models". - must_ack = 1; - } - - else - { - //ACE_DEBUG ((LM_DEBUG, ".... message out of sequence, saved\n")); - - // Out of sequence. - if (this->highest_received_ < data.sequence_number) - { - this->highest_received_ = data.sequence_number; - } - ACE_RMCast::Data new_data = data; - new_data.payload = ACE_Message_Block::duplicate (data.payload); - (void) this->messages_.bind (data.sequence_number, new_data); - // re-ack, otherwise save it and ack. - } - - ack.next_expected = this->next_expected_; - ack.highest_received = this->highest_received_; - } - - if (must_ack && data.source != 0) - (void) data.source->reply_ack (ack); - - return result; -} - -int -ACE_RMCast_Reordering::ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - //ACE_DEBUG ((LM_DEBUG, "RMCast_Reordering::ack_join - <%d,%d>\n", - // this->next_expected_, - // ack_join.next_sequence_number)); - - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - if (this->next_expected_ >= ack_join.next_sequence_number) - { - // Nothing to do in this case... - return 0; - } - - Messages_Iterator i = this->messages_.begin (); - Messages_Iterator end = this->messages_.end (); - - while (i != end - && (*i).key () < ack_join.next_sequence_number) - { - ACE_Message_Block::release ((*i).item ().payload); - this->messages_.unbind ((*i).key ()); - i = this->messages_.begin (); - } - - this->next_expected_ = ack_join.next_sequence_number; - if (this->highest_received_ < ack_join.next_sequence_number) - this->highest_received_ = ack_join.next_sequence_number; - - this->push_queued_messages (); - } - - return 0; -} - -int -ACE_RMCast_Reordering::push_queued_messages (void) -{ - Messages_Iterator i = this->messages_.begin (); - Messages_Iterator end = this->messages_.end (); - - while (i != end - && (*i).key () == this->next_expected_) - { - int r = 0; - if (this->next () != 0) - { - ACE_RMCast::Data data = (*i).item (); - r = this->next ()->data (data); - } - - ACE_Message_Block::release ((*i).item ().payload); - this->messages_.unbind ((*i).key ()); - i = this->messages_.begin (); - this->next_expected_++; - if (r != 0) - return r; - } - return 0; -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/ace/RMCast/RMCast_Reordering.h b/ace/RMCast/RMCast_Reordering.h deleted file mode 100644 index 68901480ef5..00000000000 --- a/ace/RMCast/RMCast_Reordering.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace/RMCast -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_REORDERING_H -#define ACE_RMCAST_REORDERING_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "ace/RB_Tree.h" -#include "ace/Synch_Traits.h" -#include "ace/Thread_Mutex.h" -#include "ace/Null_Mutex.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_Proxy; - -/// Pass messages up in sent order -/** - * Some applications require receivers to process messages in the same - * order that messages are sent. This module buffers out of order - * messages and only delivers a message if: - * - All the previous messages have been delivered. - * - The sender sends a notification that previous messages will not - * be resent. - * - * The module also sends the Ack feedback to the sender. - * - * NOTE: This is not the same as causal or total ordering, that could - * be implemented someday, but requires a lot more than what we have - * right now. - * - */ -class ACE_RMCast_Export ACE_RMCast_Reordering : public ACE_RMCast_Module -{ -public: - /// Constructor - ACE_RMCast_Reordering (void); - - /// Destructor - virtual ~ACE_RMCast_Reordering (void); - - /// Use a Red-Black Tree to keep the queue of messages - //@{ - typedef ACE_RB_Tree<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> Messages; - typedef ACE_RB_Tree_Iterator<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> Messages_Iterator; - //@} - - /// Remove messages still pending - virtual int close (void); - - /// Process a Data message. - /** - * Process a Data message, sending the right Ack message back. - * The message is passed up only if it is in order. - */ - virtual int data (ACE_RMCast::Data &); - - /// During the join process the server informs us of the next - /// expected message - virtual int ack_join (ACE_RMCast::Ack_Join &); - -private: - /// Push any messages that are pending in the queue - int push_queued_messages (void); - -protected: - /// The reordering buffer - Messages messages_; - - /// The smallest value of next_expected for all the proxies - ACE_UINT32 next_expected_; - - /// The highest value of highest_received for all the proxies - ACE_UINT32 highest_received_; - - /// Synchronization - ACE_SYNCH_MUTEX mutex_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Reordering.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_REORDERING_H */ diff --git a/ace/RMCast/RMCast_Reordering.i b/ace/RMCast/RMCast_Reordering.i deleted file mode 100644 index ccbf852bc67..00000000000 --- a/ace/RMCast/RMCast_Reordering.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Reordering::ACE_RMCast_Reordering (void) - : next_expected_ (0) - , highest_received_ (0) -{ -} diff --git a/ace/RMCast/RMCast_Resend_Handler.cpp b/ace/RMCast/RMCast_Resend_Handler.cpp deleted file mode 100644 index 4bb5d717742..00000000000 --- a/ace/RMCast/RMCast_Resend_Handler.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// $Id$ - -#include "RMCast_Resend_Handler.h" -#include "RMCast_Retransmission.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Resend_Handler.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Resend_Handler, "$Id$") - -ACE_RMCast_Resend_Handler::~ACE_RMCast_Resend_Handler (void) -{ -} - -int -ACE_RMCast_Resend_Handler::handle_timeout (const ACE_Time_Value &, - const void *) -{ - (void) this->retransmission_->resend_all (); - return 0; -} diff --git a/ace/RMCast/RMCast_Resend_Handler.h b/ace/RMCast/RMCast_Resend_Handler.h deleted file mode 100644 index 363b0ee5cc3..00000000000 --- a/ace/RMCast/RMCast_Resend_Handler.h +++ /dev/null @@ -1,44 +0,0 @@ -// $Id$ - -#ifndef ACE_RMCAST_RESEND_HANDLER_H -#define ACE_RMCAST_RESEND_HANDLER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Export.h" -#include "ace/Event_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_Retransmission; - -/// Implement an adapter to resend messages in the -/// ACE_RMCast_Retransmission layer, but based on Reactor based -/// timeouts. -class ACE_RMCast_Export ACE_RMCast_Resend_Handler : public ACE_Event_Handler -{ -public: - /// Constructor, save io_udp as the Adaptee in the Adapter pattern. - ACE_RMCast_Resend_Handler (ACE_RMCast_Retransmission *retransmission); - - /// Destructor - ~ACE_RMCast_Resend_Handler (void); - - //@{ - //! Documented in ACE_Event_Handler class - virtual int handle_timeout (const ACE_Time_Value ¤t_time, - const void *act = 0); - //@} - -private: - //! The adaptee - ACE_RMCast_Retransmission *retransmission_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Resend_Handler.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_RESEND_HANDLER_H */ diff --git a/ace/RMCast/RMCast_Resend_Handler.i b/ace/RMCast/RMCast_Resend_Handler.i deleted file mode 100644 index 9ad6cd8870d..00000000000 --- a/ace/RMCast/RMCast_Resend_Handler.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Resend_Handler:: -ACE_RMCast_Resend_Handler (ACE_RMCast_Retransmission *r) - : retransmission_ (r) -{ -} diff --git a/ace/RMCast/RMCast_Resend_Worker.cpp b/ace/RMCast/RMCast_Resend_Worker.cpp deleted file mode 100644 index 77f41aee1fb..00000000000 --- a/ace/RMCast/RMCast_Resend_Worker.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Resend_Worker.h" -#include "RMCast_Module.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Resend_Worker.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Resend_Worker, "$Id$") - -int -ACE_RMCast_Resend_Worker::work (ACE_UINT32 const & key, - ACE_RMCast::Data const &item) -{ - if (key > this->max_sequence_number_) - return 0; - //ACE_DEBUG ((LM_DEBUG, - // "RMCast_Resend_Worker::work - message %d resent\n", - // key)); - - ACE_RMCast::Data data = item; - int r = this->next_->data (data); - if (r != 0) - return r; - this->n++; - - return 1; // @@ Stop after the first message... -} diff --git a/ace/RMCast/RMCast_Resend_Worker.h b/ace/RMCast/RMCast_Resend_Worker.h deleted file mode 100644 index 2b49f97876a..00000000000 --- a/ace/RMCast/RMCast_Resend_Worker.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_RESEND_WORKER_H -#define ACE_RMCAST_RESEND_WORKER_H -#include /**/ "ace/pre.h" - -#include "RMCast.h" -#include "RMCast_Copy_On_Write.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_Module; - -/// Process an Ack message in the ACE_RMCast_Retransmission module -/** - * The retransmission module uses internal iterators, thus it needs to - * create helper Worker classes to process some messages. - */ -class ACE_RMCast_Resend_Worker - : public ACE_RMCast_Worker<ACE_UINT32,ACE_RMCast::Data> -{ -public: - ACE_RMCast_Resend_Worker (ACE_RMCast_Module *next, - ACE_UINT32 max_sequence_number); - - virtual int work (ACE_UINT32 const & key, - ACE_RMCast::Data const &item); - - int n; - -private: - ACE_RMCast_Module *next_; - - ACE_UINT32 max_sequence_number_; - -private: - ACE_RMCast_Resend_Worker (const ACE_RMCast_Resend_Worker&); - ACE_RMCast_Resend_Worker& operator= (const ACE_RMCast_Resend_Worker&); -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Resend_Worker.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_RESEND_WORKER_H */ diff --git a/ace/RMCast/RMCast_Resend_Worker.i b/ace/RMCast/RMCast_Resend_Worker.i deleted file mode 100644 index d609c27f006..00000000000 --- a/ace/RMCast/RMCast_Resend_Worker.i +++ /dev/null @@ -1,12 +0,0 @@ -// $Id$ - -ACE_INLINE - -ACE_RMCast_Resend_Worker:: -ACE_RMCast_Resend_Worker (ACE_RMCast_Module *next, - ACE_UINT32 max_sequence_number) - : n (0) - , next_ (next) - , max_sequence_number_ (max_sequence_number) -{ -} diff --git a/ace/RMCast/RMCast_Retransmission.cpp b/ace/RMCast/RMCast_Retransmission.cpp deleted file mode 100644 index c6f03626e39..00000000000 --- a/ace/RMCast/RMCast_Retransmission.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Retransmission.h" -#include "RMCast_Proxy.h" -#include "RMCast_Ack_Worker.h" -#include "RMCast_Resend_Worker.h" -#include "ace/Message_Block.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Retransmission.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Retransmission, "$Id$") - -ACE_RMCast_Retransmission::~ACE_RMCast_Retransmission (void) -{ -} - -int -ACE_RMCast_Retransmission::resend (ACE_UINT32 max_sequence_number) -{ - if (this->next () == 0) - return 0; - - ACE_RMCast_Resend_Worker worker (this->next (), max_sequence_number); - - if (this->messages_.for_each (&worker) == -1) - return -1; - - return worker.n; -} - -int -ACE_RMCast_Retransmission::resend_all (void) -{ - if (this->next () == 0) - return 0; - - ACE_RMCast_Resend_Worker worker (this->next (), ACE_UINT32_MAX); - - if (this->messages_.for_each (&worker) == -1) - return -1; - - return worker.n; -} - -int -ACE_RMCast_Retransmission::has_data (void) -{ - return !this->messages_.empty (); -} - -int -ACE_RMCast_Retransmission::close (void) -{ - // @@ - return 0; -} - -int -ACE_RMCast_Retransmission::data (ACE_RMCast::Data &data) -{ - if (this->next () == 0) - return 0; - - int r = this->next ()->data (data); - if (r == 0) - { - ACE_RMCast::Data copy = data; - copy.payload = ACE_Message_Block::duplicate (data.payload); - r = this->messages_.bind (data.sequence_number, copy); - } - return r; -} - -int -ACE_RMCast_Retransmission::join (ACE_RMCast::Join &join) -{ - if (join.source == 0) - return 0; - - ACE_RMCast::Ack_Join ack_join; - ack_join.source = 0; - ack_join.next_sequence_number = this->messages_.first_key (); - - (void) join.source->reply_ack_join (ack_join); - - // @@ We should force a full retransmission of all the messages! - - return 0; -} - -int -ACE_RMCast_Retransmission::leave (ACE_RMCast::Leave &leave) -{ - if (leave.source == 0) - return 0; - - ACE_RMCast::Ack_Leave ack_leave; - ack_leave.source = 0; - - (void) leave.source->reply_ack_leave (ack_leave); - - return 0; -} - -int -ACE_RMCast_Retransmission::ack (ACE_RMCast::Ack &ack) -{ - Messages::Write_Guard ace_mon (this->messages_); - - ACE_RMCast_Ack_Worker worker (ack, ace_mon, &this->messages_); - - return this->messages_.for_each (&worker); -} - -#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>; - -template class ACE_RMCast_Copy_On_Write<ACE_UINT32,ACE_RMCast::Data,ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator>; -template class ACE_RMCast_Copy_On_Write_Container<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator>; -template class ACE_RMCast_Copy_On_Write_Write_Guard<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator>; -template class ACE_RMCast_Copy_On_Write_Read_Guard<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator>; -template class ACE_RMCast_Copy_On_Write_Collection<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator>; -template class ACE_RMCast_Worker<ACE_UINT32,ACE_RMCast::Data>; - -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) - -#pragma instantiate ACE_RB_Tree<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> -#pragma instantiate ACE_RB_Tree_Iterator_Base<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> -#pragma instantiate ACE_RB_Tree_Iterator<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> -#pragma instantiate ACE_RB_Tree_Reverse_Iterator<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> -#pragma instantiate ACE_RB_Tree_Node<ACE_UINT32,ACE_RMCast::Data> - -#pragma instantiate ACE_RMCast_Copy_On_Write<ACE_UINT32,ACE_RMCast::Data,ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator> -#pragma instantiate ACE_RMCast_Copy_On_Write_Container<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator> -#pragma instantiate ACE_RMCast_Copy_On_Write_Write_Guard<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator> -#pragma instantiate ACE_RMCast_Copy_On_Write_Read_Guard<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator> -#pragma instantiate ACE_RMCast_Copy_On_Write_Collection<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator> -#pragma instantiate ACE_RMCast_Worker<ACE_UINT32,ACE_RMCast::Data> - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/ace/RMCast/RMCast_Retransmission.h b/ace/RMCast/RMCast_Retransmission.h deleted file mode 100644 index b51d1438c2a..00000000000 --- a/ace/RMCast/RMCast_Retransmission.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Retransmission.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_RETRANSMISSION_H -#define ACE_RMCAST_RETRANSMISSION_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "RMCast_Copy_On_Write.h" -#include "ace/RB_Tree.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Store messages for retransmission in reliable configurations -/** - * Reliable configurations of the RMCast framework need to store - * messages on the sender side to resend them if one or more clients - * do not receive them successfully. - */ -class ACE_RMCast_Export ACE_RMCast_Retransmission : public ACE_RMCast_Module -{ -public: - // = Initialization and termination methods. - /// Constructor - ACE_RMCast_Retransmission (void); - - /// Destructor - virtual ~ACE_RMCast_Retransmission (void); - - /// Use a Red-Black Tree to keep the queue of messages - typedef ACE_RB_Tree<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> Collection; - typedef ACE_RB_Tree_Iterator<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> Collection_Iterator; - - /// The messages are stored in the Copy_On_Write wrapper to provide - /// an efficient, but thread safe interface. - typedef ACE_RMCast_Copy_On_Write<ACE_UINT32,ACE_RMCast::Data,Collection,Collection_Iterator> Messages; - - /// Resend messages - /** - * Resends all the messages up to \param max_sequence_number - * Returns the number of messages sent, or -1 if there where any - * errors. - */ - int resend (ACE_UINT32 max_sequence_number); - - /// Resend all messages - /** - * Resends all the messages currently in the queue. - */ - int resend_all (void); - - /// Return 0 if there is no pending data to send - int has_data (void); - - /// Cleanup all the stored messages - virtual int close (void); - - /// Pass the message downstream, but also save it in the - /// retransmission queue - /** - * Sequence number are assigned by the ACE_RMCast_Fragmentation - * class, consequently this class first passes the message - * downstream, to obtain the sequence number and then stores the - * message for later retransmission. - */ - virtual int data (ACE_RMCast::Data &data); - - /// Process an Ack message from the remote receivers. - /** - * Normally this Ack message will be a summary of all the Ack - * messages received by the ACE_RMCast_Membership class - */ - virtual int ack (ACE_RMCast::Ack &); - - /// Detect when new members join the group and Ack_Join them - /** - * When a new receiver joins the group this module sends an Ack_Join - * message with the next sequence number that the receiver should - * expect. - * The sequence number is obtained from the current list of cached - * messages. - */ - virtual int join (ACE_RMCast::Join &); - - /// A receiver is leaving - /** - * Normally the ACE_RMCast_Membership module could do this, but, - * because this module processes the Join messages, it seems more - * natural to process the Leave messages too. - */ - virtual int leave (ACE_RMCast::Leave &); - -protected: - - /// The retransmission buffer - Messages messages_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Retransmission.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_RETRANSMISSION_H */ diff --git a/ace/RMCast/RMCast_Retransmission.i b/ace/RMCast/RMCast_Retransmission.i deleted file mode 100644 index e67b41120ce..00000000000 --- a/ace/RMCast/RMCast_Retransmission.i +++ /dev/null @@ -1,6 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Retransmission::ACE_RMCast_Retransmission (void) -{ -} diff --git a/ace/RMCast/RMCast_Sequencer.cpp b/ace/RMCast/RMCast_Sequencer.cpp deleted file mode 100644 index 7ee857ca762..00000000000 --- a/ace/RMCast/RMCast_Sequencer.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Sequencer.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Sequencer.i" -#endif /* ! __ACE_INLINE__ */ - -#include "ace/Guard_T.h" - -ACE_RCSID(RMCast, RMCast_Sequencer, "$Id$") - -ACE_RMCast_Sequencer::~ACE_RMCast_Sequencer (void) -{ -} - -int -ACE_RMCast_Sequencer::data (ACE_RMCast::Data &data) -{ - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - data.sequence_number = this->sequence_number_generator_++; - } - return this->ACE_RMCast_Module::data (data); -} diff --git a/ace/RMCast/RMCast_Sequencer.h b/ace/RMCast/RMCast_Sequencer.h deleted file mode 100644 index 28f83a1d4b3..00000000000 --- a/ace/RMCast/RMCast_Sequencer.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace/RMCast -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_SEQUENCER_H -#define ACE_RMCAST_SEQUENCER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "ace/Synch_Traits.h" -#include "ace/Thread_Mutex.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Assign sequence numbers to outgoing messages -/** - * On the sender side we must assign sequence numbers to the messages - * <B>before</B> they are put in the retransmission queue. - */ -class ACE_RMCast_Export ACE_RMCast_Sequencer : public ACE_RMCast_Module -{ -public: - /// Constructor - ACE_RMCast_Sequencer (void); - - /// Destructor - virtual ~ACE_RMCast_Sequencer (void); - - virtual int data (ACE_RMCast::Data &); - -protected: - /// Create the sequence numbers - ACE_UINT32 sequence_number_generator_; - - /// Synchronization - ACE_SYNCH_MUTEX mutex_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Sequencer.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_SEQUENCER_H */ diff --git a/ace/RMCast/RMCast_Sequencer.i b/ace/RMCast/RMCast_Sequencer.i deleted file mode 100644 index e7b7ff0f492..00000000000 --- a/ace/RMCast/RMCast_Sequencer.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Sequencer::ACE_RMCast_Sequencer (void) - : sequence_number_generator_ (0) -{ -} diff --git a/ace/RMCast/RMCast_Singleton_Factory.cpp b/ace/RMCast/RMCast_Singleton_Factory.cpp deleted file mode 100644 index 5e5bd9f0930..00000000000 --- a/ace/RMCast/RMCast_Singleton_Factory.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// $Id$ - -#include "RMCast_Singleton_Factory.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Singleton_Factory.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Singleton_Factory, "$Id$") - -ACE_RMCast_Singleton_Factory::~ACE_RMCast_Singleton_Factory (void) -{ -} - -ACE_RMCast_Module* -ACE_RMCast_Singleton_Factory::create (void) -{ - return this->singleton_; -} - -void -ACE_RMCast_Singleton_Factory::destroy (ACE_RMCast_Module *) -{ -} diff --git a/ace/RMCast/RMCast_Singleton_Factory.h b/ace/RMCast/RMCast_Singleton_Factory.h deleted file mode 100644 index 6ab5819bf30..00000000000 --- a/ace/RMCast/RMCast_Singleton_Factory.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Singleton_Factory.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_SINGLETON_FACTORY_H -#define ACE_RMCAST_SINGLETON_FACTORY_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module_Factory.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Implement an ACE_RMCast_Module_Factory that "creates" a single -/// object. -/** - * Many applications (and even some internal components), will use a - * single ACE_RMCast_Module to process all the events, for example, a - * receiver may decide to use the same ACE_RMCast_Module to process - * all incoming events, instead of using one per remote sender. - */ -class ACE_RMCast_Export ACE_RMCast_Singleton_Factory : public ACE_RMCast_Module_Factory -{ -public: - /// Constructor - /** - * @param singleton This object is returned by any call to - * create(). - */ - ACE_RMCast_Singleton_Factory (ACE_RMCast_Module *singleton); - - //! Destructor - virtual ~ACE_RMCast_Singleton_Factory (void); - - virtual ACE_RMCast_Module *create (void); - virtual void destroy (ACE_RMCast_Module *); - -private: - /// The singleton object - ACE_RMCast_Module *singleton_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Singleton_Factory.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_SINGLETON_FACTORY_H */ diff --git a/ace/RMCast/RMCast_Singleton_Factory.i b/ace/RMCast/RMCast_Singleton_Factory.i deleted file mode 100644 index a45837dfa93..00000000000 --- a/ace/RMCast/RMCast_Singleton_Factory.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Singleton_Factory:: - ACE_RMCast_Singleton_Factory (ACE_RMCast_Module *singleton) - : singleton_ (singleton) -{ -} diff --git a/ace/RMCast/RMCast_UDP_Event_Handler.cpp b/ace/RMCast/RMCast_UDP_Event_Handler.cpp deleted file mode 100644 index 6f7ae18f19e..00000000000 --- a/ace/RMCast/RMCast_UDP_Event_Handler.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_UDP_Event_Handler.h" -#include "RMCast_IO_UDP.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_UDP_Event_Handler.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_UDP_Event_Handler, "$Id$") - -ACE_RMCast_UDP_Event_Handler::~ACE_RMCast_UDP_Event_Handler (void) -{ -} - -ACE_HANDLE -ACE_RMCast_UDP_Event_Handler::get_handle (void) const -{ - return this->io_udp_->get_handle (); -} - -int -ACE_RMCast_UDP_Event_Handler::handle_input (ACE_HANDLE h) -{ - return this->io_udp_->handle_input (h); -} - -int -ACE_RMCast_UDP_Event_Handler::handle_timeout (const ACE_Time_Value &, - const void *) -{ - // @@ return this->io_udp_->handle_timeout (); - return 0; -} diff --git a/ace/RMCast/RMCast_UDP_Event_Handler.h b/ace/RMCast/RMCast_UDP_Event_Handler.h deleted file mode 100644 index e8873ed67fd..00000000000 --- a/ace/RMCast/RMCast_UDP_Event_Handler.h +++ /dev/null @@ -1,59 +0,0 @@ -// $Id$ - -#ifndef ACE_RMCAST_UDP_EVENT_HANDLER_H -#define ACE_RMCAST_UDP_EVENT_HANDLER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Export.h" -#include "ace/Event_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_IO_UDP; -class ACE_INET_Addr; - -//! Implement an Adapter for the ACE_RMCast_IO_UDP class -/*! - * Applications may wish to use the ACE_Reactor to demultiplex I/O - * events for an ACE_RMCast_IO_UDP object. However other application - * may choose to make ACE_RMCast_IO_UDP active, or they may dedicate - * their own threads for its events. - * To avoid couplin ACE_RMCast_IO_UDP with the Reactor we don't make - * it derived from ACE_Event_Handler or any other class in the Reactor - * framework, instead, this simple Adapter can forward the Reactor - * messages to an ACE_RMCast_IO_UDP object. - */ -class ACE_RMCast_Export ACE_RMCast_UDP_Event_Handler : public ACE_Event_Handler -{ -public: - //! Constructor, save io_udp as the Adaptee in the Adapter pattern. - ACE_RMCast_UDP_Event_Handler (ACE_RMCast_IO_UDP *io_udp); - - //! Destructor - /*! - * Notice that this class does not own the ACE_RMCast_IO_UDP - * adaptee, so it does not destroy it. - */ - ~ACE_RMCast_UDP_Event_Handler (void); - - //@{ - //! Documented in ACE_Event_Handler class - virtual ACE_HANDLE get_handle (void) const; - virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); - virtual int handle_timeout (const ACE_Time_Value ¤t_time, - const void *act = 0); - //@} - -private: - //! The adaptee - ACE_RMCast_IO_UDP *io_udp_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_UDP_Event_Handler.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_UDP_EVENT_HANDLER_H */ diff --git a/ace/RMCast/RMCast_UDP_Event_Handler.i b/ace/RMCast/RMCast_UDP_Event_Handler.i deleted file mode 100644 index 99b4c0ac7e5..00000000000 --- a/ace/RMCast/RMCast_UDP_Event_Handler.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_UDP_Event_Handler:: -ACE_RMCast_UDP_Event_Handler (ACE_RMCast_IO_UDP *io) - : io_udp_ (io) -{ -} diff --git a/ace/RMCast/RMCast_UDP_Proxy.cpp b/ace/RMCast/RMCast_UDP_Proxy.cpp deleted file mode 100644 index cb669397756..00000000000 --- a/ace/RMCast/RMCast_UDP_Proxy.cpp +++ /dev/null @@ -1,190 +0,0 @@ -// $Id$ - -#include "RMCast_UDP_Proxy.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_UDP_Proxy.i" -#endif /* ! __ACE_INLINE__ */ - -#include "RMCast_Module.h" -#include "RMCast_IO_UDP.h" -#include "ace/Message_Block.h" -#include "ace/OS_Memory.h" -#include "ace/OS_NS_string.h" -#include "ace/os_include/arpa/os_inet.h" - -ACE_RCSID(RMCast, RMCast_UDP_Proxy, "$Id$") - -ACE_RMCast_UDP_Proxy::ACE_RMCast_UDP_Proxy (ACE_RMCast_IO_UDP *io_udp, - const ACE_INET_Addr &addr) - : io_udp_ (io_udp) - , peer_addr_ (addr) -{ -} - -ACE_RMCast_UDP_Proxy::~ACE_RMCast_UDP_Proxy (void) -{ -} - -int -ACE_RMCast_UDP_Proxy::receive_message (char *buffer, size_t size) -{ - int type = buffer[0]; - - // @@ What should we do with invalid messages like this? - // - if (type < 0 || type >= ACE_RMCast::RMCAST_MT_LAST) - return 0; - - if (type == ACE_RMCast::RMCAST_MT_POLL) - { - ACE_RMCast::Poll poll; - poll.source = this; - return this->poll (poll); - } - - else if (type == ACE_RMCast::RMCAST_MT_ACK_JOIN) - { - ACE_RMCast::Ack_Join ack_join; - ack_join.source = this; - - const size_t header_size = 1 + sizeof(ACE_UINT32); - if (size < header_size) - { - // The message is too small - return 0; - } - - ACE_UINT32 tmp; - - ACE_OS::memcpy (&tmp, buffer + 1, - sizeof(tmp)); - ack_join.next_sequence_number = ACE_NTOHL (tmp); - return this->ack_join (ack_join); - } - - else if (type == ACE_RMCast::RMCAST_MT_ACK_LEAVE) - { - ACE_RMCast::Ack_Leave ack_leave; - ack_leave.source = this; - return this->ack_leave (ack_leave); - } - - else if (type == ACE_RMCast::RMCAST_MT_DATA) - { - ACE_RMCast::Data data; - data.source = this; - const size_t header_size = 1 + 3 * sizeof(ACE_UINT32); - if (size < header_size) - { - // The message is too small - return 0; - } - - ACE_UINT32 tmp; - - ACE_OS::memcpy (&tmp, buffer + 1, - sizeof(tmp)); - data.sequence_number = ACE_NTOHL (tmp); - - ACE_OS::memcpy (&tmp, buffer + 1 + sizeof(tmp), - sizeof(tmp)); - data.total_size = ACE_NTOHL (tmp); - - ACE_OS::memcpy (&tmp, buffer + 1 + 2 * sizeof(tmp), - sizeof(tmp)); - data.fragment_offset = ACE_NTOHL (tmp); - - // Pass it up the module... - ACE_Message_Block *mb; - ACE_NEW_RETURN (mb, ACE_Message_Block, -1); - mb->size (size - header_size); - mb->copy (buffer + header_size, size - header_size); - - data.payload = mb; - return this->data (data); - } - - else if (type == ACE_RMCast::RMCAST_MT_JOIN) - { - ACE_RMCast::Join join; - join.source = this; - return this->join (join); - } - - else if (type == ACE_RMCast::RMCAST_MT_LEAVE) - { - ACE_RMCast::Leave leave; - leave.source = this; - return this->leave (leave); - } - - else if (type == ACE_RMCast::RMCAST_MT_ACK) - { - ACE_RMCast::Ack ack; - ack.source = this; - - const size_t header_size = 1 + sizeof(ACE_UINT32); - if (size < header_size) - { - // The message is too small - return 0; - } - - ACE_UINT32 tmp; - - ACE_OS::memcpy (&tmp, buffer + 1, - sizeof(tmp)); - ack.next_expected = ACE_NTOHL (tmp); - ACE_OS::memcpy (&tmp, buffer + 1 + sizeof(ACE_UINT32), - sizeof(tmp)); - ack.highest_received = ACE_NTOHL (tmp); - - return this->ack (ack); - } - - return 0; -} - -int -ACE_RMCast_UDP_Proxy::reply_data (ACE_RMCast::Data &data) -{ - return this->io_udp_->send_data (data, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_poll (ACE_RMCast::Poll &poll) -{ - return this->io_udp_->send_poll (poll, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - (void) this->ACE_RMCast_Proxy::reply_ack_join (ack_join); - return this->io_udp_->send_ack_join (ack_join, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_ack_leave (ACE_RMCast::Ack_Leave &ack_leave) -{ - return this->io_udp_->send_ack_leave (ack_leave, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_ack (ACE_RMCast::Ack &ack) -{ - return this->io_udp_->send_ack (ack, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_join (ACE_RMCast::Join &join) -{ - return this->io_udp_->send_join (join, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_leave (ACE_RMCast::Leave &leave) -{ - return this->io_udp_->send_leave (leave, this->peer_addr_); -} diff --git a/ace/RMCast/RMCast_UDP_Proxy.h b/ace/RMCast/RMCast_UDP_Proxy.h deleted file mode 100644 index 01db65f66d1..00000000000 --- a/ace/RMCast/RMCast_UDP_Proxy.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_UDP_Proxy.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_UDP_PROXY_H -#define ACE_RMCAST_UDP_PROXY_H -#include /**/ "ace/pre.h" - -#include "RMCast_Proxy.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/INET_Addr.h" - -class ACE_RMCast_IO_UDP; - -/// Define the proxy implementation for UDP based communication -/** - * Proxy objects are transport specific, they are responsible for - * storing the remote peer addressing information. - * This class implements the UDP version of a proxy. - */ -class ACE_RMCast_Export ACE_RMCast_UDP_Proxy : public ACE_RMCast_Proxy -{ -public: - /// Constructor - /** - * The \param io_udp argument is kept to send the replys through the - * right socket. - * The \param peer_addr is the address used byu the peer to receive - * responses. - */ - ACE_RMCast_UDP_Proxy (ACE_RMCast_IO_UDP *io_udp, - const ACE_INET_Addr &peer_addr); - - /// Destructor - virtual ~ACE_RMCast_UDP_Proxy (void); - - /// Receive a message, parse and send it upstream in the right - /// format. - int receive_message (char *buffer, size_t size); - - /// Make the peer address available - const ACE_INET_Addr &peer_addr (void) const; - - //@{ - /** - * Implement the ACE_RMCast_Proxy methods, in this case we use the - * @var io_udp_ object to send the data, using the address of our - * remote peer. - */ - virtual int reply_data (ACE_RMCast::Data &); - virtual int reply_poll (ACE_RMCast::Poll &); - virtual int reply_ack_join (ACE_RMCast::Ack_Join &); - virtual int reply_ack_leave (ACE_RMCast::Ack_Leave &); - virtual int reply_ack (ACE_RMCast::Ack &); - virtual int reply_join (ACE_RMCast::Join &); - virtual int reply_leave (ACE_RMCast::Leave &); - //@} - -private: - /// The IO facade - ACE_RMCast_IO_UDP *io_udp_; - - /// The remote peer's address - ACE_INET_Addr peer_addr_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_UDP_Proxy.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_UDP_PROXY_H */ diff --git a/ace/RMCast/RMCast_UDP_Proxy.i b/ace/RMCast/RMCast_UDP_Proxy.i deleted file mode 100644 index b7a85e78ce2..00000000000 --- a/ace/RMCast/RMCast_UDP_Proxy.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE const ACE_INET_Addr& -ACE_RMCast_UDP_Proxy::peer_addr (void) const -{ - return this->peer_addr_; -} diff --git a/ace/RMCast/RMCast_UDP_Reliable_Receiver.cpp b/ace/RMCast/RMCast_UDP_Reliable_Receiver.cpp deleted file mode 100644 index 8c41e9bb663..00000000000 --- a/ace/RMCast/RMCast_UDP_Reliable_Receiver.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// $Id$ - -#include "RMCast_UDP_Reliable_Receiver.h" -#include "RMCast_UDP_Event_Handler.h" -#include "ace/Reactor.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_UDP_Reliable_Receiver.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_UDP_Reliable_Receiver, "$Id$") - -ACE_RMCast_UDP_Reliable_Receiver::ACE_RMCast_UDP_Reliable_Receiver (ACE_RMCast_Module *user_module) - : user_factory_ (user_module) - , factory_ (&user_factory_) - , io_udp_ (&factory_) -{ -} - -ACE_RMCast_UDP_Reliable_Receiver::~ACE_RMCast_UDP_Reliable_Receiver (void) -{ -} - -void -ACE_RMCast_UDP_Reliable_Receiver::reactive_incoming_messages (ACE_Reactor *reactor) -{ - ACE_RMCast_UDP_Event_Handler *eh; - ACE_NEW (eh, ACE_RMCast_UDP_Event_Handler (&this->io_udp_)); - - /// @@ TODO Make sure it is removed from the Reactor at some point - (void) reactor->register_handler (eh, ACE_Event_Handler::READ_MASK); -} diff --git a/ace/RMCast/RMCast_UDP_Reliable_Receiver.h b/ace/RMCast/RMCast_UDP_Reliable_Receiver.h deleted file mode 100644 index 56797861b4b..00000000000 --- a/ace/RMCast/RMCast_UDP_Reliable_Receiver.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_UDP_RELIABLE_RECEIVER_H -#define ACE_RMCAST_UDP_RELIABLE_RECEIVER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Singleton_Factory.h" -#include "RMCast_Reliable_Factory.h" -#include "RMCast_IO_UDP.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_Reactor; - -class ACE_RMCast_Export ACE_RMCast_UDP_Reliable_Receiver : public ACE_RMCast_Module -{ -public: - /// Constructor - ACE_RMCast_UDP_Reliable_Receiver (ACE_RMCast_Module *user_control); - - /// Destructor - virtual ~ACE_RMCast_UDP_Reliable_Receiver (void); - - /// Open the UDP I/O module. - int init (const ACE_INET_Addr &mcast_group); - - /// Use the reactor to handle incoming messages - void reactive_incoming_messages (ACE_Reactor *reactor); - -private: - /// All the proxys give their messages to user module - ACE_RMCast_Singleton_Factory user_factory_; - - /// This factory creates the per-proxy stack - ACE_RMCast_Reliable_Factory factory_; - - /// Handle all the UDP I/O - ACE_RMCast_IO_UDP io_udp_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_UDP_Reliable_Receiver.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_UDP_RELIABLE_RECEIVER_H */ diff --git a/ace/RMCast/RMCast_UDP_Reliable_Receiver.i b/ace/RMCast/RMCast_UDP_Reliable_Receiver.i deleted file mode 100644 index 01b2ebe2cad..00000000000 --- a/ace/RMCast/RMCast_UDP_Reliable_Receiver.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE int -ACE_RMCast_UDP_Reliable_Receiver::init (const ACE_INET_Addr &mcast_group) -{ - return this->io_udp_.subscribe (mcast_group); -} diff --git a/ace/RMCast/RMCast_UDP_Reliable_Sender.cpp b/ace/RMCast/RMCast_UDP_Reliable_Sender.cpp deleted file mode 100644 index 641fb3403ac..00000000000 --- a/ace/RMCast/RMCast_UDP_Reliable_Sender.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// $Id$ - -#include "RMCast_UDP_Reliable_Sender.h" -#include "RMCast_UDP_Event_Handler.h" -#include "RMCast_Resend_Handler.h" -#include "ace/Reactor.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_UDP_Reliable_Sender.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_UDP_Reliable_Sender, "$Id$") - -ACE_RMCast_UDP_Reliable_Sender::ACE_RMCast_UDP_Reliable_Sender (ACE_RMCast_Module *user_control) - : user_control_ (user_control) - - // We use a singleton factory, all proxys send their messages to the - // retransmission module. There should be only control messages - // coming back, so this is OK. - , factory_ (&membership_) - , io_udp_ (&factory_) -{ - // Control messages are received by the membership module and passed - // up to the both the retransmission and user modules, we use a fork - // module to do that - this->membership_.next (&this->fork_); - - this->fork_.next (&this->retransmission_); - this->fork_.secondary (user_control); - - // Messages are passed down to the sequencer module - this->next (&this->sequencer_); - - // then to the retransmission module - this->sequencer_.next (&this->retransmission_); - - // Then fork the messages, at this point control messages are sent - // back to the user, other messages continue down to the - // fragmentation layer. - this->retransmission_.next (&this->fragment_); - - // The fragmentation layer delegates all messages to the UDP I/O - // module, that sends every message back to the application. - this->fragment_.next (&this->io_udp_); -} - -ACE_RMCast_UDP_Reliable_Sender::~ACE_RMCast_UDP_Reliable_Sender (void) -{ -} - -void -ACE_RMCast_UDP_Reliable_Sender::reactive_incoming_messages (ACE_Reactor *reactor) -{ - ACE_RMCast_UDP_Event_Handler *eh; - ACE_NEW (eh, ACE_RMCast_UDP_Event_Handler (&this->io_udp_)); - - /// @@ TODO Make sure it is removed from the Reactor at some point - (void) reactor->register_handler (eh, ACE_Event_Handler::READ_MASK); -} - -void -ACE_RMCast_UDP_Reliable_Sender::reactive_resends (ACE_Reactor *reactor, - const ACE_Time_Value &period) -{ - ACE_RMCast_Resend_Handler *eh; - ACE_NEW (eh, ACE_RMCast_Resend_Handler (&this->retransmission_)); - - /// @@ TODO make sure it is removed from the Reactor at some point - (void) reactor->schedule_timer (eh, 0, period, period); -} diff --git a/ace/RMCast/RMCast_UDP_Reliable_Sender.h b/ace/RMCast/RMCast_UDP_Reliable_Sender.h deleted file mode 100644 index 9b1fa01143b..00000000000 --- a/ace/RMCast/RMCast_UDP_Reliable_Sender.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_UDP_RELIABLE_SENDER_H -#define ACE_RMCAST_UDP_RELIABLE_SENDER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Singleton_Factory.h" -#include "RMCast_IO_UDP.h" -#include "RMCast_Sequencer.h" -#include "RMCast_Retransmission.h" -#include "RMCast_Membership.h" -#include "RMCast_Fragment.h" -#include "RMCast_Fork.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_Reactor; - -class ACE_RMCast_Export ACE_RMCast_UDP_Reliable_Sender : public ACE_RMCast_Module -{ -public: - /// Constructor - ACE_RMCast_UDP_Reliable_Sender (ACE_RMCast_Module *user_control); - - /// Destructor - virtual ~ACE_RMCast_UDP_Reliable_Sender (void); - - /// Open the UDP I/O module. - int init (const ACE_INET_Addr &mcast_group); - - /// Use the reactor to handle incoming messages - void reactive_incoming_messages (ACE_Reactor *reactor); - - /// Use the reactor to periodically resend messages - void reactive_resends (ACE_Reactor *reactor, - const ACE_Time_Value &period); - - /// Check if there is still some messages to send, return 0 if not. - int has_data (void); - - /// Check if there are any members still connected - int has_members (void); - -private: - /// The application-level control module - ACE_RMCast_Module *user_control_; - - /// Assign sequence numbers - ACE_RMCast_Sequencer sequencer_; - - /// The retransmission module - ACE_RMCast_Retransmission retransmission_; - - /// All the proxys give their messages to the retransmission module - ACE_RMCast_Singleton_Factory factory_; - - /// Handle all the UDP I/O - ACE_RMCast_IO_UDP io_udp_; - - /// The membership module - ACE_RMCast_Membership membership_; - - /// The fragmentation module - ACE_RMCast_Fragment fragment_; - - /// Redirect control messages to the user supplied module - ACE_RMCast_Fork fork_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_UDP_Reliable_Sender.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_UDP_RELIABLE_SENDER_H */ diff --git a/ace/RMCast/RMCast_UDP_Reliable_Sender.i b/ace/RMCast/RMCast_UDP_Reliable_Sender.i deleted file mode 100644 index 93868a86ede..00000000000 --- a/ace/RMCast/RMCast_UDP_Reliable_Sender.i +++ /dev/null @@ -1,19 +0,0 @@ -// $Id$ - -ACE_INLINE int -ACE_RMCast_UDP_Reliable_Sender::init (const ACE_INET_Addr &mcast_group) -{ - return this->io_udp_.init (mcast_group, ACE_Addr::sap_any); -} - -ACE_INLINE int -ACE_RMCast_UDP_Reliable_Sender::has_data (void) -{ - return this->retransmission_.has_data (); -} - -ACE_INLINE int -ACE_RMCast_UDP_Reliable_Sender::has_members (void) -{ - return this->membership_.has_members (); -} diff --git a/ace/RMCast/RMCast_Worker.cpp b/ace/RMCast/RMCast_Worker.cpp deleted file mode 100644 index 6f24892eace..00000000000 --- a/ace/RMCast/RMCast_Worker.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// $Id$ - -#ifndef ACE_RMCAST_WORKER_CPP -#define ACE_RMCAST_WORKER_CPP - -#include "RMCast_Worker.h" - -ACE_RCSID(RMCast, RMCast_Worker, "$Id$") - -template<class KEY, class ITEM> -ACE_RMCast_Worker<KEY,ITEM>::~ACE_RMCast_Worker (void) -{ -} - -#endif /* ACE_RMCAST_WORKER_CPP */ diff --git a/ace/RMCast/RMCast_Worker.h b/ace/RMCast/RMCast_Worker.h deleted file mode 100644 index 6431b192904..00000000000 --- a/ace/RMCast/RMCast_Worker.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// - -#ifndef ACE_RMCAST_WORKER_H -#define ACE_RMCAST_WORKER_H - -#include "ace/config-all.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -template<class KEY, class ITEM> -class ACE_RMCast_Worker -{ -public: - virtual ~ACE_RMCast_Worker (void); - - virtual int work (KEY const & key, - ITEM const & item) = 0; -}; - -#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "RMCast_Worker.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - -#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) -#pragma implementation ("RMCast_Worker.cpp") -#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ - -#endif /* ACE_RMCAST_WORKER_H */ diff --git a/ace/RMCast/Retransmit.cpp b/ace/RMCast/Retransmit.cpp new file mode 100644 index 00000000000..e04cec2f689 --- /dev/null +++ b/ace/RMCast/Retransmit.cpp @@ -0,0 +1,132 @@ +// file : ace/RMCast/Retransmit.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/OS.h> + +#include <ace/RMCast/Retransmit.h> + +namespace ACE_RMCast +{ + ACE_Time_Value const tick (0, 50000); + + Retransmit:: + Retransmit () + { + } + + void Retransmit:: + out_start (Out_Element* out) + { + Element::out_start (out); + + tracker_mgr_.spawn (track_thunk, this); + } + + void Retransmit:: + out_stop () + { + tracker_mgr_.cancel_all (1); + tracker_mgr_.wait (); + + Element::out_stop (); + } + + void Retransmit:: + send (Message_ptr m) + { + if (Data const* data = static_cast<Data const*> (m->find (Data::id))) + { + u64 sn (static_cast<SN const*> (m->find (SN::id))->num ()); + + Lock l (mutex_); + + queue_.bind (sn, Descr (new Data (*data))); + } + + out_->send (m); + } + + void Retransmit:: + recv (Message_ptr m) + { + if (NAK const* nak = static_cast<NAK const*> (m->find (NAK::id))) + { + Address to (static_cast<To const*> (m->find (To::id))->address ()); + + if (nak->address () == to) + { + Lock l (mutex_); + + for (NAK::iterator j (const_cast<NAK*> (nak)->begin ()); + !j.done (); + j.advance ()) + { + u64* psn; + j.next (psn); + + + Queue::ENTRY* pair; + + if (queue_.find (*psn, pair) == 0) + { + //cerr << 5 << "PRTM " << to << " " << pair->ext_id_ << endl; + + Message_ptr m (new Message); + + m->add (Profile_ptr (new SN (pair->ext_id_))); + m->add (pair->int_id_.data ()); + + pair->int_id_.reset (); + + out_->send (m); + } + else + { + //@@ TODO: message aging + // + //cerr << 4 << "message " << *psn << " not available" << endl; + } + } + } + } + else + { + in_->recv (m); + } + } + + ACE_THR_FUNC_RETURN Retransmit:: + track_thunk (void* obj) + { + reinterpret_cast<Retransmit*> (obj)->track (); + return 0; + } + + void Retransmit:: + track () + { + while (true) + { + { + Lock l (mutex_); + + for (Queue::iterator i (queue_); !i.done ();) + { + if ((*i).int_id_.inc () >= 60) + { + u64 sn ((*i).ext_id_); + i.advance (); + queue_.unbind (sn); + } + else + { + i.advance (); + } + } + } + + ACE_OS::sleep (tick); + } + } +} diff --git a/ace/RMCast/Retransmit.h b/ace/RMCast/Retransmit.h new file mode 100644 index 00000000000..6348ba66009 --- /dev/null +++ b/ace/RMCast/Retransmit.h @@ -0,0 +1,97 @@ +// file : ace/RMCast/Retransmit.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_RETRANSMIT_H +#define ACE_RMCAST_RETRANSMIT_H + +#include <ace/Hash_Map_Manager.h> + +#include <ace/Thread_Manager.h> + +#include <ace/RMCast/Stack.h> +#include <ace/RMCast/Protocol.h> +#include <ace/RMCast/Bits.h> + +namespace ACE_RMCast +{ + class Retransmit : public Element + { + public: + Retransmit (); + + virtual void + out_start (Out_Element* out); + + virtual void + out_stop (); + + public: + virtual void + send (Message_ptr m); + + virtual void + recv (Message_ptr m); + + private: + struct Descr + { + // Shouldn't be available but ACE_Hash_Map needs it. + // + Descr () + : data_ (), count_ (0) + { + } + + Descr (Data_ptr d) + : data_ (d), count_ (0) + { + } + + unsigned long + inc () + { + return ++count_; + } + + void + reset () + { + count_ = 0; + } + + // It would be logical to return data_ptr but ACE ref_auto_ptr + // hasn't learned how to convert between pointers yet. + // + Profile_ptr + data () const + { + return Profile_ptr (new Data (*data_)); + } + + private: + Data_ptr data_; + unsigned long count_; + }; + + typedef + ACE_Hash_Map_Manager<u64, Descr, ACE_Null_Mutex> + Queue; + + private: + void + track (); + + static ACE_THR_FUNC_RETURN + track_thunk (void* obj); + + private: + Queue queue_; + Mutex mutex_; + + ACE_Thread_Manager tracker_mgr_; + }; +} + + +#endif // ACE_RMCAST_RETRANSMIT_H diff --git a/ace/RMCast/Simulator.cpp b/ace/RMCast/Simulator.cpp new file mode 100644 index 00000000000..4b08f37f3da --- /dev/null +++ b/ace/RMCast/Simulator.cpp @@ -0,0 +1,40 @@ +// file : ace/RMCast/Simulator.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/RMCast/Simulator.h> + +namespace ACE_RMCast +{ + Simulator:: + Simulator () + { + srand (time (0)); + } + + void Simulator:: + send (Message_ptr m) + { + // Note: Simulator may work in unpredictable ways mainly due + // to the "reliable loopback" mechanism. + // + out_->send (m); + return; + + int r (rand ()); + + if ((r % 3) == 0) return; + + Lock l (mutex_); + + if (hold_.get ()) + { + out_->send (m); + out_->send (hold_); + } + else + { + hold_ = m; + } + } +} diff --git a/ace/RMCast/Simulator.h b/ace/RMCast/Simulator.h new file mode 100644 index 00000000000..9e19f26bb8b --- /dev/null +++ b/ace/RMCast/Simulator.h @@ -0,0 +1,30 @@ +// file : ace/RMCast/Simulator.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_SIMULATOR_H +#define ACE_RMCAST_SIMULATOR_H + +#include <ace/RMCast/Stack.h> +#include <ace/RMCast/Protocol.h> +#include <ace/RMCast/Bits.h> + +namespace ACE_RMCast +{ + class Simulator : public Element + { + public: + Simulator (); + + public: + virtual void + send (Message_ptr m); + + private: + Message_ptr hold_; + Mutex mutex_; + }; +} + + +#endif // ACE_RMCAST_SIMULATOR_H diff --git a/ace/RMCast/Socket.cpp b/ace/RMCast/Socket.cpp new file mode 100644 index 00000000000..640a1a7d694 --- /dev/null +++ b/ace/RMCast/Socket.cpp @@ -0,0 +1,112 @@ +// file : ace/RMCast/Socket.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/OS.h> + +#include <ace/RMCast/Socket.h> + +namespace ACE_RMCast +{ + Socket:: + Socket (Address const& a, bool loop) + : loop_ (loop), sn_ (1), cond_ (mutex_) + { + acknowledge_ = auto_ptr<Acknowledge> (new Acknowledge ()); + retransmit_ = auto_ptr<Retransmit> (new Retransmit ()); + simulator_ = auto_ptr<Simulator> (new Simulator ()); + link_ = auto_ptr<Link> (new Link (a)); + + // Start IN stack from top to bottom. + // + in_start (0); + acknowledge_->in_start (this); + retransmit_->in_start (acknowledge_.get ()); + simulator_->in_start (retransmit_.get ()); + link_->in_start (simulator_.get ()); + + // Start OUT stack from bottom up. + // + link_->out_start (0); + simulator_->out_start (link_.get ()); + retransmit_->out_start (simulator_.get ()); + acknowledge_->out_start (retransmit_.get ()); + out_start (acknowledge_.get ()); + } + + Socket:: + ~Socket () + { + // Stop OUT stack from top to bottom. + // + out_stop (); + acknowledge_->out_stop (); + retransmit_->out_stop (); + simulator_->out_stop (); + link_->out_stop (); + + // Stop IN stack from bottom up. + // + link_->in_stop (); + simulator_->in_stop (); + retransmit_->in_stop (); + acknowledge_->in_stop (); + in_stop (); + } + + + void Socket:: + send (void const* buf, size_t s) + { + Message_ptr m (new Message); + + m->add (Profile_ptr (new SN (sn_++))); + m->add (Profile_ptr (new Data (buf, s))); + + send (m); + } + + size_t Socket:: + recv (void* buf, size_t s) + { + Lock l (mutex_); + + while (queue_.is_empty ()) cond_.wait (); + + Message_ptr m; + if (queue_.dequeue_head (m) == -1) abort (); + + Data const* d (static_cast<Data const*>(m->find (Data::id))); + + size_t r (d->size () < s ? d->size () : s); + + ACE_OS::memcpy (buf, d->buf (), r); + + return r; + } + + void Socket:: + recv (Message_ptr m) + { + if (m->find (Data::id) != 0) + { + if (!loop_) + { + Address to (static_cast<To const*> (m->find (To::id))->address ()); + + Address from ( + static_cast<From const*> (m->find (From::id))->address ()); + + if (to == from) return; + } + + Lock l (mutex_); + + bool signal (queue_.is_empty ()); + + queue_.enqueue_tail (m); + + if (signal) cond_.signal (); + } + } +} diff --git a/ace/RMCast/Socket.h b/ace/RMCast/Socket.h new file mode 100644 index 00000000000..62f72b9597e --- /dev/null +++ b/ace/RMCast/Socket.h @@ -0,0 +1,59 @@ +// file : ace/RMCast/Socket.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_SOCKET_H +#define ACE_RMCAST_SOCKET_H + +#include <ace/Unbounded_Queue.h> + +#include <ace/RMCast/Stack.h> +#include <ace/RMCast/Protocol.h> +#include <ace/RMCast/Bits.h> + +#include <ace/RMCast/Link.h> +#include <ace/RMCast/Simulator.h> +#include <ace/RMCast/Retransmit.h> +#include <ace/RMCast/Acknowledge.h> + +namespace ACE_RMCast +{ + class Socket : protected Element + { + public: + ~Socket (); + + Socket (Address const& a, bool loop = true); + + public: + virtual void + send (void const* buf, size_t s); + + virtual size_t + recv (void* buf, size_t s); + + private: + using Element::send; + + virtual void + recv (Message_ptr m); + + private: + bool loop_; + + u64 sn_; //@@ lock? + + Mutex mutex_; + Condition cond_; + + ACE_Unbounded_Queue<Message_ptr> queue_; + + auto_ptr<Acknowledge> acknowledge_; + auto_ptr<Retransmit> retransmit_; + auto_ptr<Simulator> simulator_; + auto_ptr<Link> link_; + }; +} + + +#endif // ACE_RMCAST_SOCKET_H diff --git a/ace/RMCast/Stack.cpp b/ace/RMCast/Stack.cpp new file mode 100644 index 00000000000..729e289cf0e --- /dev/null +++ b/ace/RMCast/Stack.cpp @@ -0,0 +1,9 @@ +// file : ace/RMCast/Stack.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/RMCast/Stack.h> + +namespace ACE_RMCast +{ +} diff --git a/ace/RMCast/Stack.h b/ace/RMCast/Stack.h new file mode 100644 index 00000000000..e371370977d --- /dev/null +++ b/ace/RMCast/Stack.h @@ -0,0 +1,87 @@ +// file : ace/RMCast/Stack.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_STACK_H +#define ACE_RMCAST_STACK_H + +#include <ace/RMCast/Protocol.h> + +namespace ACE_RMCast +{ + struct Out_Element + { + virtual + ~Out_Element () + { + } + + Out_Element () + : out_ (0) + { + } + + virtual void + out_start (Out_Element* out) + { + out_ = out; + } + + virtual void + send (Message_ptr m) + { + if (out_) out_->send (m); + } + + virtual void + out_stop () + { + out_ = 0; + } + + protected: + Out_Element* out_; + }; + + + struct In_Element + { + virtual + ~In_Element () + { + } + + In_Element () + : in_ (0) + { + } + + virtual void + in_start (In_Element* in) + { + in_ = in; + } + + virtual void + recv (Message_ptr m) + { + if (in_) in_->recv (m); + } + + virtual void + in_stop () + { + in_ = 0; + } + + protected: + In_Element* in_; + }; + + struct Element : In_Element, Out_Element + { + }; + +} + +#endif // ACE_RMCAST_STACK_H diff --git a/examples/RMCast/Makefile.am b/examples/RMCast/Makefile.am deleted file mode 100644 index 514702c29ec..00000000000 --- a/examples/RMCast/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -## Process this file with automake to create Makefile.in -## -## $Id$ -## -## This file was generated by MPC. Any changes made directly to -## this file will be lost the next time it is generated. -## -## MPC Command: -## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu - -SUBDIRS = \ - Send_File - diff --git a/examples/RMCast/Send_File/Makefile.am b/examples/RMCast/Send_File/Makefile.am deleted file mode 100644 index 8eb5d564aa9..00000000000 --- a/examples/RMCast/Send_File/Makefile.am +++ /dev/null @@ -1,55 +0,0 @@ -## Process this file with automake to create Makefile.in -## -## $Id$ -## -## This file was generated by MPC. Any changes made directly to -## this file will be lost the next time it is generated. -## -## MPC Command: -## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu - -ACE_BUILDDIR = $(top_builddir) -ACE_ROOT = $(top_srcdir) - -noinst_PROGRAMS = -## Makefile.RMCast_Send_File_Receiver.am - -if BUILD_RMCAST -noinst_PROGRAMS += receiver - -receiver_CPPFLAGS = \ - -I$(ACE_ROOT) \ - -I$(ACE_BUILDDIR) - -receiver_SOURCES = \ - Receiver.cpp - -receiver_LDADD = \ - $(top_builddir)/ace/RMCast/libACE_RMCast.la $(top_builddir)/ace/libACE.la - -endif BUILD_RMCAST - -## Makefile.RMCast_Send_File_Sender.am - -if BUILD_RMCAST -noinst_PROGRAMS += sender - -sender_CPPFLAGS = \ - -I$(ACE_ROOT) \ - -I$(ACE_BUILDDIR) - -sender_SOURCES = \ - Sender.cpp - -sender_LDADD = \ - $(top_builddir)/ace/RMCast/libACE_RMCast.la $(top_builddir)/ace/libACE.la - -endif BUILD_RMCAST - -## Clean up template repositories, etc. -clean-local: - -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* - -rm -f gcctemp.c gcctemp so_locations *.ics - -rm -rf cxx_repository ptrepository ti_files - -rm -rf templateregistry ir.out - -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/examples/RMCast/Send_File/Receiver.cpp b/examples/RMCast/Send_File/Receiver.cpp deleted file mode 100644 index 80ac7be26bd..00000000000 --- a/examples/RMCast/Send_File/Receiver.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// $Id$ - -#include "ace/OS_main.h" -#include "ace/OS_NS_fcntl.h" -#include "ace/RMCast/RMCast_UDP_Reliable_Receiver.h" -#include "ace/INET_Addr.h" -#include "ace/FILE_IO.h" -#include "ace/Message_Block.h" -#include "ace/Reactor.h" - -ACE_RCSID(tests, RMCast_Examples_Receiver, "$Id$") - -class File_Module : public ACE_RMCast_Module -{ -public: - File_Module (void); - - /// Return 1 if all the data has been received - int status (void) const; - - /// Initialize the module - int init (const ACE_TCHAR *filename); - - int close (void); - int data (ACE_RMCast::Data &data); - int ack_join (ACE_RMCast::Ack_Join &ack_join); - int ack_leave (ACE_RMCast::Ack_Leave &ack_leave); - -private: - /// Set to 1 when the last block is received - int status_; - - /// Used to dump the received data into a file - ACE_FILE_IO file_io_; -}; - -int -ACE_TMAIN (int argc, ACE_TCHAR *argv[]) -{ - if (argc != 3) - { - ACE_ERROR_RETURN ((LM_ERROR, - "Usage: %s <filename> <mcastgroup:port>\n", - argv[0]), - 1); - } - - const ACE_TCHAR *filename = argv[1]; - - File_Module file_module; - if (file_module.init (filename) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - "Cannot init file module\n"), - 1); - } - - ACE_RMCast_UDP_Reliable_Receiver receiver (&file_module); - - ACE_INET_Addr mcast_group; - if (mcast_group.set (argv[2]) != 0) - { - ACE_ERROR_RETURN ((LM_ERROR, - "Cannot setup multicast group <%s>\n", - argv[2]), - 1); - } - - if (receiver.init (mcast_group) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - "Cannot init UDP I/O at <%s:%d> %p\n", - mcast_group.get_host_name (), - mcast_group.get_port_number (), - ""), - 1); - } - - // Use the Reactor to demultiplex all the messages - ACE_Reactor *reactor = ACE_Reactor::instance (); - receiver.reactive_incoming_messages (reactor); - - // Wait until all the messages are successfully delivered - do - { - // Try for 50 milliseconds... - ACE_Time_Value tv (5, 0); // 0, 50000); - int r = reactor->handle_events (&tv); - if (r == -1) - break; - } - while (file_module.status () != 2); - - ACE_DEBUG ((LM_DEBUG, "event loop completed\n")); - - return 0; -} - -// **************************************************************** - -File_Module::File_Module (void) - : status_ (0) -{ -} - -int -File_Module::status (void) const -{ - return this->status_; -} - -int -File_Module::init (const ACE_TCHAR * filename) -{ - ACE_HANDLE handle = ACE_OS::open (filename, - O_WRONLY|O_BINARY|O_CREAT, - ACE_DEFAULT_FILE_PERMS); - if (handle == ACE_INVALID_HANDLE) - ACE_ERROR_RETURN ((LM_ERROR, - "Cannot open file <%s> %p\n", filename, ""), - -1); - this->file_io_.set_handle (handle); - return 0; -} - -int -File_Module::close (void) -{ - ACE_DEBUG ((LM_DEBUG, "File_Module closed\n")); - (void) this->file_io_.close (); - return 0; -} - -int -File_Module::data (ACE_RMCast::Data &data) -{ - if (this->status_ == 1) - return -1; - - size_t length = data.payload->length () - 1; - (void) this->file_io_.send (data.payload->rd_ptr () + 1, length); - - if (*(data.payload->rd_ptr ()) == 'E') - { - this->status_ = 1; - return -1; - } - - return 0; -} - -int -File_Module::ack_join (ACE_RMCast::Ack_Join &) -{ - ACE_DEBUG ((LM_DEBUG, - "File_Module::ack_join\n")); - return 0; -} - -int -File_Module::ack_leave (ACE_RMCast::Ack_Leave &) -{ - ACE_DEBUG ((LM_DEBUG, - "File_Module::ack_leave\n")); - this->status_ = 2; - return 0; -} diff --git a/examples/RMCast/Send_File/Sender.cpp b/examples/RMCast/Send_File/Sender.cpp deleted file mode 100644 index ec6e3e43642..00000000000 --- a/examples/RMCast/Send_File/Sender.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// $Id$ - -#include "ace/OS_main.h" -#include "ace/OS_NS_unistd.h" -#include "ace/OS_NS_fcntl.h" -#include "ace/RMCast/RMCast_UDP_Reliable_Sender.h" -#include "ace/INET_Addr.h" -#include "ace/FILE_IO.h" -#include "ace/Message_Block.h" -#include "ace/Reactor.h" - -ACE_RCSID(tests, RMCast_Examples_Sender, "$Id$") - -int -ACE_TMAIN (int argc, ACE_TCHAR *argv[]) -{ - if (argc != 3) - { - ACE_ERROR_RETURN ((LM_ERROR, - "Usage: %s <filename> <mcastgroup:port>\n", - argv[0]), - 1); - } - - const ACE_TCHAR *filename = argv[1]; - if (ACE_OS::access (filename, R_OK) != 0) - { - ACE_ERROR_RETURN ((LM_ERROR, - "Cannot read file <%s>\n", filename), - 1); - } - - ACE_INET_Addr mcast_group; - if (mcast_group.set (argv[2]) != 0) - { - ACE_ERROR_RETURN ((LM_ERROR, - "Cannot setup multicast group <%s>\n", - argv[2]), - 1); - } - - - ACE_HANDLE handle = ACE_OS::open (filename, O_RDONLY|O_BINARY); - if (handle == ACE_INVALID_HANDLE) - { - ACE_ERROR_RETURN ((LM_ERROR, - "Cannot open file <%s> %p\n", filename, ""), - 1); - } - ACE_FILE_IO file_io; - file_io.set_handle (handle); - - // We don't provide a module to receive the control messages, in - // this example we simply ignore them. - ACE_RMCast_UDP_Reliable_Sender sender (0); - - if (sender.init (mcast_group) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - "Cannot init UDP I/O at <%s:%d> %p\n", - mcast_group.get_host_name (), - mcast_group.get_port_number (), - ""), - 1); - } - - // Use the Reactor to demultiplex all the messages - ACE_Reactor *reactor = ACE_Reactor::instance (); - - sender.reactive_incoming_messages (reactor); - { - // Resend the messages every 20 milliseconds.. - ACE_Time_Value tv (2, 0); - sender.reactive_resends (reactor, tv); - } - - for (;;) - { - ACE_Message_Block payload (BUFSIZ + 1); - - ssize_t r = file_io.recv (payload.rd_ptr () + 1, BUFSIZ); - if (r <= 0) - break; - - payload.wr_ptr (r + 1); - *(payload.rd_ptr ()) = 'N'; // Normal - if (r < BUFSIZ) - { - *(payload.rd_ptr ()) = 'E'; // EOF - } - - ACE_RMCast::Data data; - data.payload = &payload; - if (sender.data (data) != 0) - break; - - if (r < BUFSIZ) - { - // Last buffer, terminate loop - break; - } - - // Handle incoming events, without blocking... - ACE_Time_Value tv (4, 0); - reactor->handle_events (&tv); - } - - // Wait until all the messages are successfully delivered - do - { - // Try for 50 milliseconds... - ACE_Time_Value tv (5, 0); - int r = reactor->handle_events (&tv); - if (r == -1) - break; - } - while (sender.has_data () || sender.has_members ()); - - return 0; -} diff --git a/examples/RMCast/Send_Msg/Protocol.h b/examples/RMCast/Send_Msg/Protocol.h new file mode 100644 index 00000000000..c3edf43b1fb --- /dev/null +++ b/examples/RMCast/Send_Msg/Protocol.h @@ -0,0 +1,18 @@ +// file : Protocol.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef PROTOCOL_H +#define PROTOCOL_H + +unsigned short const payload_size = 256; +unsigned long const message_count = 10000; + +struct Message +{ + unsigned long sn; + + unsigned short payload[payload_size]; +}; + +#endif // PROTOCOL_H diff --git a/examples/RMCast/Send_Msg/README b/examples/RMCast/Send_Msg/README new file mode 100644 index 00000000000..b02056bf0cf --- /dev/null +++ b/examples/RMCast/Send_Msg/README @@ -0,0 +1,18 @@ +In this example SENDER sends a number (defined in Protocol.h, 10000 +by default) of messages to the multicast group. Each message has +an application-level sequence number. RECEIVER tries to receive them +and checks for damaged, lost, and reordered messages. Since reliable +multicast is used there should be no damaged or reordered messages. +There could be some number of lost messages at the beginning, +howevere (standard race condition). + +To run the example start a one or more RECEIVERS, e.g., + +$ ./receiver 224.1.0.1:10000 + +Then start one SENDER: + +$ ./sender 224.1.0.1:10000 + +-- +Boris Kolpackov <boris@kolpackov.net> diff --git a/examples/RMCast/Send_Msg/Receiver.cpp b/examples/RMCast/Send_Msg/Receiver.cpp new file mode 100644 index 00000000000..72d202716cd --- /dev/null +++ b/examples/RMCast/Send_Msg/Receiver.cpp @@ -0,0 +1,119 @@ +// file : Receiver.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <vector> +#include <iostream> +#include <cstring> // memcmp + +#include <ace/RMCast/Socket.h> + +#include "Protocol.h" + +using std::cout; +using std::cerr; +using std::endl; + +typedef +std::vector<unsigned char> +Status_List; + +class args {}; + +int +main (int argc, char* argv[]) +{ + try + { + if (argc < 2) throw args (); + + ACE_RMCast::Address addr (argv[1]); + + ACE_RMCast::Socket socket (addr); + + + Message expected_msg; + expected_msg.sn = 0; + + for (unsigned short i = 0; i < payload_size; i++) + { + expected_msg.payload[i] = i; + } + + Status_List received (message_count, 0); + Status_List damaged (message_count, 0); + Status_List duplicate (message_count, 0); + + Message msg; + + while (true) + { + socket.recv (&msg, sizeof (msg)); + + if (received[msg.sn] == 1) + { + duplicate[msg.sn] = 1; + } + else + { + received[msg.sn] = 1; + + if (std::memcmp (expected_msg.payload, msg.payload, payload_size) != 0) + { + damaged[msg.sn] = 1; + } + } + + if (msg.sn + 1 == message_count) break; + } + + unsigned long lost_count (0), damaged_count (0), duplicate_count (0); + + for (Status_List::iterator i (received.begin ()), end (received.end ()); + i != end; + ++i) if (*i == 0) ++lost_count; + + for (Status_List::iterator i (damaged.begin ()), end (damaged.end ()); + i != end; + ++i) if (*i == 1) ++damaged_count; + + for (Status_List::iterator i (duplicate.begin ()), end (duplicate.end ()); + i != end; + ++i) if (*i == 1) ++duplicate_count; + + cout << "lost : " << lost_count << endl + << "damaged : " << damaged_count << endl + << "duplicate : " << duplicate_count << endl << endl; + + cout << "lost message dump:" << endl; + + unsigned long total = 0; + + for (Status_List::iterator + begin (received.begin ()), i (begin), end (received.end ()); + i != end;) + { + if (*i == 0) + { + unsigned long count = 1; + + for (Status_List::iterator j = i + 1; + j < end && *j == 0; + j++, count++); + + cout << '\t' << i - begin << " : " << count << endl; + + i += count; + total += count; + } + else ++i; + } + + if (total != lost_count) cerr << "trouble" << endl; + + } + catch (args const&) + { + cerr << "usage: " << argv[0] << " <IPv4 Multicast Address>" << endl; + } +} diff --git a/examples/RMCast/Send_File/RMCast_Send_File.mpc b/examples/RMCast/Send_Msg/Send_Msg.mpc index 897e1611b71..897e1611b71 100644 --- a/examples/RMCast/Send_File/RMCast_Send_File.mpc +++ b/examples/RMCast/Send_Msg/Send_Msg.mpc diff --git a/examples/RMCast/Send_Msg/Sender.cpp b/examples/RMCast/Send_Msg/Sender.cpp new file mode 100644 index 00000000000..e784b6362c7 --- /dev/null +++ b/examples/RMCast/Send_Msg/Sender.cpp @@ -0,0 +1,54 @@ +// file : Sender.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + + +#include <ace/OS.h> +#include <ace/RMCast/Socket.h> + +#include <iostream> + +#include "Protocol.h" + +using std::cerr; +using std::endl; + +class args {}; + +int +main (int argc, char* argv[]) +{ + try + { + if (argc < 2) throw args (); + + ACE_RMCast::Address addr (argv[1]); + + ACE_RMCast::Socket socket (addr); + + Message msg; + msg.sn = 0; + + for (unsigned short i = 0; i < payload_size; i++) + { + msg.payload[i] = i; + } + + for (; msg.sn < message_count; msg.sn++) + { + socket.send (&msg, sizeof (msg)); + } + + // Keep running in case retransmissions are needed. + // + ACE_OS::sleep (ACE_Time_Value (50, 0)); + + return 0; + } + catch (args const&) + { + cerr << "usage: " << argv[0] << " <IPv4 Multicast Address>" << endl; + } + + return 1; +} diff --git a/protocols/ace/RMCast/Acknowledge.cpp b/protocols/ace/RMCast/Acknowledge.cpp new file mode 100644 index 00000000000..e0d7ce6f376 --- /dev/null +++ b/protocols/ace/RMCast/Acknowledge.cpp @@ -0,0 +1,315 @@ +// file : ace/RMCast/Acknowledge.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/OS.h> + +#include <ace/RMCast/Acknowledge.h> + +namespace ACE_RMCast +{ + ACE_Time_Value const tick (0, 5000); + unsigned long const nak_timeout = 20; // # of ticks. + unsigned long const nrtm_timeout = 50; // # of ticks. + + Acknowledge:: + Acknowledge () + : nrtm_timer_ (nrtm_timeout) + { + } + + void Acknowledge:: + in_start (In_Element* in) + { + Element::in_start (in); + } + + void Acknowledge:: + out_start (Out_Element* out) + { + Element::out_start (out); + + tracker_mgr_.spawn (track_thunk, this); + } + + void Acknowledge:: + out_stop () + { + tracker_mgr_.cancel_all (1); + tracker_mgr_.wait (); + + Element::out_stop (); + } + + void Acknowledge:: + collapse (Queue& q) + { + // I would normally use iterators in the logic below but ACE_Map_Manager + // iterates over entries in no particular order so it is pretty much + // unusable here. Instead we will do slow and cumbersome find's. + // + + u64 sn (q.sn () + 1); + + for (;; ++sn) + { + Queue::ENTRY* e; + + if (q.find (sn, e) == -1 || e->int_id_.lost ()) break; + + Message_ptr m (e->int_id_.msg ()); + q.unbind (sn); + + in_->recv (m); + } + + q.sn (sn - 1); + } + + void Acknowledge:: + track () + { + while (true) + { + Messages msgs; + + { + Lock l (mutex_); + + if (hold_.current_size () != 0) + { + for (Map::iterator i (hold_.begin ()), e (hold_.end ()); + i != e; + ++i) + { + Queue& q ((*i).int_id_); + + if (q.current_size () == 0) continue; + + track_queue ((*i).ext_id_, q, msgs); + } + } + + if (--nrtm_timer_ == 0) + { + nrtm_timer_ = nrtm_timeout; + + // Send NRTM. + // + Profile_ptr nrtm (create_nrtm ()); + + if (nrtm.get ()) + { + Message_ptr m (new Message); + m->add (nrtm); + msgs.push_back (m); + + } + } + } + + // Send stuff off. + // + for (Messages::Iterator i (msgs); !i.done (); i.advance ()) + { + Message_ptr* ppm; + i.next (ppm); + send (*ppm); + } + + ACE_OS::sleep (tick); + } + } + + void Acknowledge:: + track_queue (Address const& addr, Queue& q, Messages& msgs) + { + NAK_ptr nak (new NAK (addr)); + + // Track existing losses. + // + for (Queue::iterator i (q.begin ()), e (q.end ()); i != e; ++i) + { + u64 sn ((*i).ext_id_); + Descr& d ((*i).int_id_); + + if (d.lost ()) + { + d.timer (d.timer () - 1); + + if (d.timer () == 0) + { + //@@ Need exp fallback. + // + d.nak_count (d.nak_count () + 1); + d.timer ((d.nak_count () + 1) * nak_timeout); + + nak->add (sn); + + //cerr << 6 << "NAK # " << d.nak_count () << ": " + // << addr << " " << sn << endl; + } + } + } + + // Send NAK. + // + if (nak->count ()) + { + // cerr << 5 << "NAK: " << addr << " " << nak->count () << " sns" + // << endl; + + Message_ptr m (new Message); + + m->add (Profile_ptr (nak.release ())); + + msgs.push_back (m); + } + + // Detect and record new losses. + // + for (u64 sn (q.sn () + 1), end (q.max_sn ()); sn < end; ++sn) + { + if (q.find (sn) == -1) + { + q.bind (sn, Descr (1)); + } + } + } + + void Acknowledge:: + recv (Message_ptr m) + { + // Handle NRTM. There could be some nasty interaction with code + // that handles data below (like missing message and NAK). This + // is why I hold the lock at the beginning (which may be not very + // efficient). + // + Lock l (mutex_); + + if (NRTM const* nrtm = static_cast<NRTM const*> (m->find (NRTM::id))) + { + for (Map::iterator i (hold_.begin ()), e (hold_.end ()); i != e; ++i) + { + u64 sn (nrtm->find ((*i).ext_id_)); + + if (sn != 0) + { + Queue& q ((*i).int_id_); + + u64 old (q.max_sn ()); + + if (old < sn) + { + // Mark as lost. + // + q.bind (sn, Descr (1)); + } + } + } + } + + if (m->find (Data::id)) + { + Address from ( + static_cast<From const*> (m->find (From::id))->address ()); + + u64 sn (static_cast<SN const*> (m->find (SN::id))->num ()); + + Map::ENTRY* e; + + if (hold_.find (from, e) == -1) + { + // First message from this source. + // + hold_.bind (from, Queue (sn)); + hold_.find (from, e); + + in_->recv (m); + } + else + { + Queue& q (e->int_id_); + + if (sn <= q.sn ()) + { + // Duplicate. + // + //cerr << 6 << "DUP " << from << " " << q.sn () << " >= " << sn + // << endl; + } + else if (sn == q.sn () + 1) + { + // Next message. + // + + q.rebind (sn, Descr (m)); + collapse (q); + } + else + { + // Some messages are missing. Insert this one into the queue. + // + q.rebind (sn, Descr (m)); + } + } + } + else + { + l.release (); + + // Just forward it up. + // + in_->recv (m); + } + } + + void Acknowledge:: + send (Message_ptr m) + { + if (m->find (Data::id) != 0) + { + Lock l (mutex_); + + Profile_ptr nrtm (create_nrtm ()); + + if (nrtm.get ()) m->add (nrtm); + + nrtm_timer_ = nrtm_timeout; // Reset timer. + } + + out_->send (m); + } + + Profile_ptr Acknowledge:: + create_nrtm () + { + // Prepare NRTM. + // + NRTM_ptr nrtm (new NRTM ()); + + // Gather the information. + // + { + for (Map::iterator i (hold_.begin ()), e (hold_.end ()); i != e; ++i) + { + Address addr ((*i).ext_id_); + Queue& q ((*i).int_id_); + + //@@ Should look for the highest known number. + // + nrtm->insert (addr, q.sn ()); + } + } + + if (nrtm->empty ()) return 0; + else return Profile_ptr (nrtm.release ()); + } + + ACE_THR_FUNC_RETURN Acknowledge:: + track_thunk (void* obj) + { + reinterpret_cast<Acknowledge*> (obj)->track (); + return 0; + } +} diff --git a/protocols/ace/RMCast/Acknowledge.h b/protocols/ace/RMCast/Acknowledge.h new file mode 100644 index 00000000000..4289ec729db --- /dev/null +++ b/protocols/ace/RMCast/Acknowledge.h @@ -0,0 +1,234 @@ +// file : ace/RMCast/Acknowledge.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_ACKNOWLEDGE_H +#define ACE_RMCAST_ACKNOWLEDGE_H + +#include <ace/Hash_Map_Manager.h> +#include <ace/Thread_Manager.h> + +#include <ace/RMCast/Stack.h> +#include <ace/RMCast/Protocol.h> +#include <ace/RMCast/Bits.h> + +namespace ACE_RMCast +{ + class Acknowledge : public Element + { + public: + Acknowledge (); + + virtual void + in_start (In_Element* in); + + virtual void + out_start (Out_Element* out); + + virtual void + out_stop (); + + public: + virtual void + recv (Message_ptr m); + + virtual void + send (Message_ptr m); + + private: + struct Descr + { + //@@ There should be no default c-tor. + // + Descr () + : nak_count_ (0), timer_ (1) + { + } + + Descr (unsigned long timer) + : nak_count_ (0), timer_ (timer) + { + } + + Descr (Message_ptr m) + : m_ (m) + { + } + + public: + bool + lost () const + { + return m_.get () == 0; + } + + public: + Message_ptr + msg () + { + return m_; + } + + void + msg (Message_ptr m) + { + m_ = m; + } + + public: + unsigned long + nak_count () const + { + return nak_count_; + } + + void + nak_count (unsigned long v) + { + nak_count_ = v; + } + + unsigned long + timer () const + { + return timer_; + } + + void + timer (unsigned long v) + { + timer_ = v; + } + + private: + Message_ptr m_; + + unsigned long nak_count_; + unsigned long timer_; + }; + + struct Queue : ACE_Hash_Map_Manager<u64, Descr, ACE_Null_Mutex> + { + typedef ACE_Hash_Map_Manager<u64, Descr, ACE_Null_Mutex> Base; + + // Should never be here but required by ACE_Hash_Blah_Blah. + // + Queue () + : Base (), sn_ (0), max_sn_ (0) + { + } + + Queue (u64 sn) + : Base (), sn_ (sn), max_sn_ (sn) + { + } + + Queue (Queue const& q) + : Base (), sn_ (q.sn_), max_sn_ (sn_) + { + for (Queue::const_iterator i (q), e (q, 1); i != e; ++i) + { + bind ((*i).ext_id_, (*i).int_id_); + } + } + + public: + int + bind (u64 sn, Descr const& d) + { + int r (Base::bind (sn, d)); + + if (r == 0 && sn > max_sn_) max_sn_ = sn; + + return r; + } + + int + rebind (u64 sn, Descr const& d) + { + int r (Base::rebind (sn, d)); + + if (r == 0 && sn > max_sn_) max_sn_ = sn; + + return r; + } + + int + unbind (u64 sn) + { + int r (Base::unbind (sn)); + + if (r == 0 && sn == max_sn_) + { + for (--max_sn_; max_sn_ >= sn_; --max_sn_) + { + if (find (max_sn_) == 0) break; + } + } + + return r; + } + + public: + u64 + sn () const + { + return sn_; + } + + void + sn (u64 sn) + { + sn_ = sn; + } + + u64 + max_sn () const + { + if (current_size () == 0) return sn_; + + return max_sn_; + } + + private: + u64 sn_, max_sn_; + }; + + typedef + ACE_Hash_Map_Manager_Ex<Address, + Queue, + AddressHasher, + ACE_Equal_To<Address>, + ACE_Null_Mutex> + Map; + + private: + void + collapse (Queue& q); + + void + track (); + + void + track_queue (Address const& addr, Queue& q, Messages& msgs); + + Profile_ptr + create_nrtm (); + + static ACE_THR_FUNC_RETURN + track_thunk (void* obj); + + private: + Map hold_; + Mutex mutex_; + + unsigned long nrtm_timer_; + + ACE_Thread_Manager tracker_mgr_; + }; + + + +} + +#endif // ACE_RMCAST_ACKNOWLEDGE_H diff --git a/protocols/ace/RMCast/Agent.tar.bz2 b/protocols/ace/RMCast/Agent.tar.bz2 Binary files differnew file mode 100644 index 00000000000..173776420d9 --- /dev/null +++ b/protocols/ace/RMCast/Agent.tar.bz2 diff --git a/protocols/ace/RMCast/Bits.h b/protocols/ace/RMCast/Bits.h new file mode 100644 index 00000000000..0c1090910ce --- /dev/null +++ b/protocols/ace/RMCast/Bits.h @@ -0,0 +1,28 @@ +// file : ace/RMCast/Bits.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_BITS_H +#define ACE_RMCAST_BITS_H + +#include <ace/Synch.h> +#include <ace/Auto_Ptr.h> + +//#include <iostream> + +namespace ACE_RMCast +{ + typedef ACE_Thread_Mutex Mutex; + typedef ACE_Guard<Mutex> Lock; + typedef ACE_Condition<Mutex> Condition; + + using ::auto_ptr; // ACE auto_ptr. + + // tmp + // + //using std::cerr; + //using std::endl; +} + + +#endif // ACE_RMCAST_BITS_H diff --git a/protocols/ace/RMCast/Link.cpp b/protocols/ace/RMCast/Link.cpp new file mode 100644 index 00000000000..e6898cfd76c --- /dev/null +++ b/protocols/ace/RMCast/Link.cpp @@ -0,0 +1,271 @@ +// file : ace/RMCast/Link.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/RMCast/Link.h> + +namespace ACE_RMCast +{ + Link:: + Link (Address const& addr) + : addr_ (addr), + ssock_ (Address ((unsigned short) (0), INADDR_ANY), + AF_INET, + IPPROTO_UDP, + 1) + + { + srand (time (0)); + + + rsock_.set_option (IP_MULTICAST_LOOP, 0); + + // Set recv/send buffers. + // + { + int r (131070); + int s (sizeof (r)); + + static_cast<ACE_SOCK&> (rsock_).set_option ( + SOL_SOCKET, SO_RCVBUF, &r, s); + + static_cast<ACE_SOCK&> (ssock_).set_option ( + SOL_SOCKET, SO_RCVBUF, &r, s); + + rsock_.get_option (SOL_SOCKET, SO_RCVBUF, &r, &s); + //cerr << 5 << "recv buffer size: " << r << endl; + + ssock_.get_option (SOL_SOCKET, SO_RCVBUF, &r, &s); + //cerr << 5 << "send buffer size: " << r << endl; + + } + + // Bind address and port. + // + if (ACE_OS::connect (ssock_.get_handle (), + reinterpret_cast<sockaddr*> (addr_.get_addr ()), + addr_.get_addr_size ()) == -1) + { + perror ("connect: "); + abort (); + } + + + ssock_.get_local_addr (self_); + + //cerr << 5 << "self: " << self_ << endl; + } + + void Link:: + in_start (In_Element* in) + { + Element::in_start (in); + + rsock_.join (addr_); + + // Start receiving thread. + // + recv_mgr_.spawn (recv_thunk, this); + } + + void Link:: + out_start (Out_Element* out) + { + Element::out_start (out); + } + + void Link:: + in_stop () + { + // Stop receiving thread. + // + recv_mgr_.cancel_all (1); + recv_mgr_.wait (); + + Element::in_stop (); + } + + void Link:: + send (Message_ptr m) + { + bool const sim = false; + + // Simulate message loss and reordering. + // + if (sim) + { + if ((rand () % 5) != 0) + { + Lock l (mutex_); + + if (hold_.get ()) + { + send_ (m); + send_ (hold_); + hold_ = 0; + } + else + { + hold_ = m; + + // Make a copy in M so that the reliable loop below + // won't add FROM and TO to HOLD_. + // + m = Message_ptr (new Message (*hold_)); + } + } + } + else + send_ (m); + + // Reliable loop. + // + m->add (Profile_ptr (new From (self_))); + m->add (Profile_ptr (new To (self_))); + + in_->recv (m); + } + + void Link:: + send_ (Message_ptr m) + { + ostream os (m->size (), 1); // Always little-endian. + + os << *m; + + ssock_.send (os.buffer (), os.length (), addr_); + + /* + if (m->find (nrtm::id)) + { + write (1, os.buffer (), os.length ()); + exit (1); + } + */ + } + + void Link:: + recv () + { + // I could have used ACE_Data_Block but it does not support + // resizing... + // + size_t size (0), capacity (8192); + char* data (reinterpret_cast<char*> (operator new (capacity))); + + auto_ptr<char> holder (data); // This is wicked. + + while (true) + { + //@@ Should I lock here? + // + + Address addr; + + //@@ CDR-specific. + // + size = rsock_.recv (data, 4, addr, MSG_PEEK); + + if (size != 4 || addr == self_) + { + // Discard bad messages and ones from ourselvs since + // we are using reliable loopback. + // + rsock_.recv (data, 0, addr); + continue; + } + + u32 msg_size; + { + istream is (data, size, 1); // Always little-endian. + is >> msg_size; + } + + if (msg_size <= 4) + { + // Bad message. + // + rsock_.recv (data, 0, addr); + continue; + } + + if (capacity < msg_size) + { + capacity = msg_size; + holder = auto_ptr<char> (0); + data = reinterpret_cast<char*> (operator new (capacity)); + holder = auto_ptr<char> (data); + } + + size = rsock_.recv (data, capacity, addr); + + if (msg_size != size) + { + // Bad message. + // + continue; + } + + //cerr << 6 << "from: " << addr << endl; + + Message_ptr m (new Message ()); + + m->add (Profile_ptr (new From (addr))); + m->add (Profile_ptr (new To (self_))); + + istream is (data, size, 1); // Always little-endian. + + is >> msg_size; + + while (true) + { + u16 id, size; + + if (!((is >> id) && (is >> size))) break; + + //cerr << 6 << "reading profile with id " << id << " " + // << size << " bytes long" << endl; + + Profile::Header hdr (id, size); + + switch (hdr.id ()) + { + case SN::id: + { + m->add (Profile_ptr (new SN (hdr, is))); + break; + } + case Data::id: + { + m->add (Profile_ptr (new Data (hdr, is))); + break; + } + case NAK::id: + { + m->add (Profile_ptr (new NAK (hdr, is))); + break; + } + case NRTM::id: + { + m->add (Profile_ptr (new NRTM (hdr, is))); + break; + } + default: + { + //cerr << 0 << "unknown profile id " << hdr.id () << endl; + abort (); + } + } + } + + in_->recv (m); + } + } + + ACE_THR_FUNC_RETURN Link:: + recv_thunk (void* obj) + { + reinterpret_cast<Link*> (obj)->recv (); + return 0; + } +} diff --git a/protocols/ace/RMCast/Link.h b/protocols/ace/RMCast/Link.h new file mode 100644 index 00000000000..e6e66bbbd80 --- /dev/null +++ b/protocols/ace/RMCast/Link.h @@ -0,0 +1,62 @@ +// file : ace/RMCast/Link.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_LINK_H +#define ACE_RMCAST_LINK_H + +#include <ace/SOCK_Dgram.h> +#include <ace/SOCK_Dgram_Mcast.h> + +#include <ace/Thread_Manager.h> + +#include <ace/RMCast/Stack.h> +#include <ace/RMCast/Protocol.h> + +namespace ACE_RMCast +{ + class Link : public Element + { + public: + Link (Address const& addr); + + virtual void + in_start (In_Element* in); + + virtual void + out_start (Out_Element* out); + + virtual void + in_stop (); + + public: + virtual void + send (Message_ptr m); + + private: + virtual void + send_ (Message_ptr m); + + private: + void + recv (); + + static ACE_THR_FUNC_RETURN + recv_thunk (void* obj); + + private: + Address addr_, self_; + ACE_SOCK_Dgram_Mcast rsock_; + ACE_SOCK_Dgram ssock_; + + ACE_Thread_Manager recv_mgr_; + + // Simulator. + // + Message_ptr hold_; + Mutex mutex_; + }; +} + + +#endif // ACE_RMCAST_LINK_H diff --git a/protocols/ace/RMCast/Makefile.am b/protocols/ace/RMCast/Makefile.am deleted file mode 100644 index 78f36853be0..00000000000 --- a/protocols/ace/RMCast/Makefile.am +++ /dev/null @@ -1,127 +0,0 @@ -## Process this file with automake to create Makefile.in -## -## $Id$ -## -## This file was generated by MPC. Any changes made directly to -## this file will be lost the next time it is generated. -## -## MPC Command: -## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu - -includedir = @includedir@/ace/RMCast -pkgconfigdatadir = ${prefix}/lib/pkgconfig - -ACE_BUILDDIR = $(top_builddir) -ACE_ROOT = $(top_srcdir) - -nobase_include_HEADERS = -lib_LTLIBRARIES = -## Makefile.RMCast.am - -if BUILD_RMCAST -lib_LTLIBRARIES += libACE_RMCast.la - -libACE_RMCast_la_CPPFLAGS = \ - -I$(ACE_ROOT) \ - -I$(ACE_BUILDDIR) \ - -DACE_RMCAST_BUILD_DLL - -libACE_RMCast_la_SOURCES = \ - RMCast.cpp \ - RMCast_Ack_Worker.cpp \ - RMCast_Copy_On_Write.cpp \ - RMCast_Fork.cpp \ - RMCast_Fragment.cpp \ - RMCast_IO_UDP.cpp \ - RMCast_Membership.cpp \ - RMCast_Module.cpp \ - RMCast_Module_Factory.cpp \ - RMCast_Partial_Message.cpp \ - RMCast_Proxy.cpp \ - RMCast_Reassembly.cpp \ - RMCast_Receiver_Module.cpp \ - RMCast_Reliable_Factory.cpp \ - RMCast_Reordering.cpp \ - RMCast_Resend_Handler.cpp \ - RMCast_Resend_Worker.cpp \ - RMCast_Retransmission.cpp \ - RMCast_Sequencer.cpp \ - RMCast_Singleton_Factory.cpp \ - RMCast_UDP_Event_Handler.cpp \ - RMCast_UDP_Proxy.cpp \ - RMCast_UDP_Reliable_Receiver.cpp \ - RMCast_UDP_Reliable_Sender.cpp \ - RMCast_Worker.cpp - -libACE_RMCast_la_LDFLAGS = \ - -version-number @ACE_MAJOR@:@ACE_MINOR@:@ACE_BETA@ - -libACE_RMCast_la_LIBADD = \ - $(top_builddir)/ace/libACE.la - -nobase_include_HEADERS += \ - RMCast.h \ - RMCast_Ack_Worker.h \ - RMCast_Copy_On_Write.h \ - RMCast_Export.h \ - RMCast_Fork.h \ - RMCast_Fragment.h \ - RMCast_IO_UDP.h \ - RMCast_Membership.h \ - RMCast_Module.h \ - RMCast_Module_Factory.h \ - RMCast_Partial_Message.h \ - RMCast_Proxy.h \ - RMCast_Reassembly.h \ - RMCast_Receiver_Module.h \ - RMCast_Reliable_Factory.h \ - RMCast_Reordering.h \ - RMCast_Resend_Handler.h \ - RMCast_Resend_Worker.h \ - RMCast_Retransmission.h \ - RMCast_Sequencer.h \ - RMCast_Singleton_Factory.h \ - RMCast_UDP_Event_Handler.h \ - RMCast_UDP_Proxy.h \ - RMCast_UDP_Reliable_Receiver.h \ - RMCast_UDP_Reliable_Sender.h \ - RMCast_Worker.h \ - RMCast_Ack_Worker.i \ - RMCast_Copy_On_Write.i \ - RMCast_Fork.i \ - RMCast_Fragment.i \ - RMCast_IO_UDP.i \ - RMCast_Membership.i \ - RMCast_Module.i \ - RMCast_Partial_Message.i \ - RMCast_Proxy.i \ - RMCast_Receiver_Module.i \ - RMCast_Reliable_Factory.i \ - RMCast_Reordering.i \ - RMCast_Resend_Handler.i \ - RMCast_Resend_Worker.i \ - RMCast_Retransmission.i \ - RMCast_Sequencer.i \ - RMCast_Singleton_Factory.i \ - RMCast_UDP_Event_Handler.i \ - RMCast_UDP_Proxy.i \ - RMCast_UDP_Reliable_Receiver.i \ - RMCast_UDP_Reliable_Sender.i - -pkgconfigdata_DATA = ACE_RMCast.pc - -ACE_RMCast.pc: ${top_builddir}/config.status ACE_RMCast.pc.in - ${top_builddir}/config.status --file $@:${srcdir}/ACE_RMCast.pc.in - -endif BUILD_RMCAST - -EXTRA_DIST = \ - RMCast.rc - -## Clean up template repositories, etc. -clean-local: - -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* - -rm -f gcctemp.c gcctemp so_locations *.ics - -rm -rf cxx_repository ptrepository ti_files - -rm -rf templateregistry ir.out - -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/protocols/ace/RMCast/Protocol.cpp b/protocols/ace/RMCast/Protocol.cpp new file mode 100644 index 00000000000..4082d6bd139 --- /dev/null +++ b/protocols/ace/RMCast/Protocol.cpp @@ -0,0 +1,9 @@ +// file : ace/RMCast/Protocol.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/RMCast/Protocol.h> + +namespace ACE_RMCast +{ +} diff --git a/protocols/ace/RMCast/Protocol.h b/protocols/ace/RMCast/Protocol.h new file mode 100644 index 00000000000..f9f2956920f --- /dev/null +++ b/protocols/ace/RMCast/Protocol.h @@ -0,0 +1,715 @@ +// file : ace/RMCast/Protocol.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_PROTOCOL_H +#define ACE_RMCAST_PROTOCOL_H + +#include <ace/Refcounted_Auto_Ptr.h> + +#include <ace/Vector_T.h> +#include <ace/Hash_Map_Manager.h> + +#include <ace/OS.h> +#include <ace/CDR_Stream.h> +#include <ace/INET_Addr.h> + +#include <ace/RMCast/Bits.h> + +namespace ACE_RMCast +{ + // Basic types. + // + typedef ACE_CDR::UShort u16; + typedef ACE_CDR::ULong u32; + typedef ACE_CDR::ULongLong u64; + + typedef ACE_INET_Addr Address; + + struct AddressHasher + { + unsigned long + operator() (Address const& a) const + { + unsigned long port (a.get_port_number ()); + unsigned long ip (a.get_ip_address ()); + + port <<= sizeof (sizeof (unsigned long) - sizeof (unsigned short)); + + return port ^ ip; + } + }; + + //@@ Provide stream<< (Address const&) + // + + typedef ACE_OutputCDR ostream; + typedef ACE_InputCDR istream; + + struct Profile; + + typedef + ACE_Refcounted_Auto_Ptr<Profile, ACE_Null_Mutex> + Profile_ptr; + + struct Profile + { + public: + class Header + { + public: + Header (u16 id, u16 size) + : id_ (id), size_ (size) + { + } + + Header (istream& is) + { + is >> id_ >> size_; + } + + public: + u16 + id () const + { + return id_; + } + + u16 + size () const + { + return size_; + } + + protected: + void + size (u16 s) + { + size_ = s; + } + + friend class Profile; + + private: + u16 id_; + u16 size_; + }; + + public: + virtual + ~Profile () + { + } + + protected: + Profile (u16 id, u16 size, u16 boundary) + : header_ (id, size), boundary_ (boundary) + { + } + + Profile (Header const& h, u16 boundary) + : header_ (h), boundary_ (boundary) + { + } + public: + u16 + id () const + { + return header_.id (); + } + + u16 + size () const + { + return header_.size (); + } + + u16 + boundary () const + { + return boundary_; + } + + protected: + void + size (u16 s) + { + header_.size (s); + } + + public: + virtual void + serialize_body (ostream&) const = 0; + + friend + ostream& + operator<< (ostream& os, Profile const& p); + + private: + Header header_; + u16 boundary_; + }; + + inline + ostream& + operator<< (ostream& os, Profile::Header const& hdr) + { + os << hdr.id (); + os << hdr.size (); + + return os; + } + + inline + ostream& + operator<< (ostream& os, Profile const& p) + { + os << p.header_; + p.serialize_body (os); + + return os; + } + + // + // + // + + class Message; + + typedef + ACE_Refcounted_Auto_Ptr<Message, ACE_Null_Mutex> + Message_ptr; + + class Message + { + public: + Message () + : profiles_ (4) + { + } + + Message (Message const& m) + : profiles_ (4) + { + for (Profiles::const_iterator i (m.profiles_); !i.done (); i.advance ()) + { + // Shallow copy of profiles. + // + profiles_.bind ((*i).ext_id_, (*i).int_id_); + } + } + + public: + struct duplicate {}; + + void + add (Profile_ptr p) + { + u16 id (p->id ()); + + if (profiles_.find (id) == 0) + { + throw duplicate (); + } + + profiles_.bind (id, p); + } + + Profile const* + find (u16 id) const + { + Profiles::ENTRY* e; + + if (profiles_.find (id, e) == -1) return 0; + + return e->int_id_.get (); + } + + public: + size_t + size () const + { + size_t s (4); // 4 is for size (u32) + + for (Profiles::const_iterator i (profiles_); !i.done (); i.advance ()) + { + //@@ This is so broken: in CDR the padding depends on + // what comes after. + // + s += s % 2; // Padding to the boundary of 2. + s += 4; // Profile header: u16 + u16 + s += s % (*i).int_id_->boundary (); // Padding to the b. of profile body. + s += (*i).int_id_->size (); // Profile body. + } + + return s; + } + + friend + ostream& + operator<< (ostream& os, Message const& m) + { + u32 s (m.size ()); + + os << s; + + for (Profiles::const_iterator i (m.profiles_); !i.done (); i.advance ()) + { + os << *((*i).int_id_); + } + + return os; + } + + typedef + ACE_Hash_Map_Manager<u16, Profile_ptr, ACE_Null_Mutex> + Profiles; + + Profiles profiles_; + }; + + typedef + ACE_Vector<Message_ptr> + Messages; + + + // + // + // + struct From; + + typedef + ACE_Refcounted_Auto_Ptr<From, ACE_Null_Mutex> + From_ptr; + + struct From : Profile + { + static u16 const id = 0x0001; + + public: + From (Header const& h, istream& is) + : Profile (h, 4) + { + u32 addr; + u16 port; + + is >> addr; + is >> port; + + address_ = Address (port, addr); + } + + // 6 is CDR-specific. + // + From (Address const& addr) + : Profile (id, 6, 4), address_ (addr) + { + } + + public: + Address const& + address () const + { + return address_; + } + + public: + virtual void + serialize_body (ostream& os) const + { + u32 addr (address_.get_ip_address ()); + u16 port (address_.get_port_number ()); + + os << addr; + os << port; + } + + private: + Address address_; + }; + + + // + // + // + struct To; + + typedef + ACE_Refcounted_Auto_Ptr<To, ACE_Null_Mutex> + To_ptr; + + struct To : Profile + { + static u16 const id = 0x0002; + + public: + To (Header const& h, istream& is) + : Profile (h, 4) + { + u32 addr; + u16 port; + + is >> addr; + is >> port; + + address_ = Address (port, addr); + } + + // 6 is CDR-specific. + // + To (Address const& addr) + : Profile (id, 6, 4), address_ (addr) + { + } + + public: + Address const& + address () const + { + return address_; + } + + public: + virtual void + serialize_body (ostream& os) const + { + u32 addr (address_.get_ip_address ()); + u16 port (address_.get_port_number ()); + + os << addr; + os << port; + } + + private: + Address address_; + }; + + // + // + // + struct Data; + + typedef + ACE_Refcounted_Auto_Ptr<Data, ACE_Null_Mutex> + Data_ptr; + + struct Data : Profile + { + static u16 const id = 0x0003; + + public: + Data (Header const& h, istream& is) + : Profile (h, 1), buf_ (0), size_ (h.size ()) + { + if (size_) + { + buf_ = reinterpret_cast<char*> (operator new (size_)); + is.read_char_array (buf_, size_); + } + + } + + Data (void const* buf, size_t s) + : Profile (id, s, 1), buf_ (0), size_ (s) + { + if (size_) + { + buf_ = reinterpret_cast<char*> (operator new (size_)); + ACE_OS::memcpy (buf_, buf, size_); + } + } + + public: + char const* + buf () const + { + return buf_; + } + + size_t + size () const + { + return size_; + } + + public: + virtual void + serialize_body (ostream& os) const + { + os.write_char_array (buf_, size_); + } + + private: + char* buf_; + size_t size_; + }; + + // + // + // + struct SN; + + typedef + ACE_Refcounted_Auto_Ptr<SN, ACE_Null_Mutex> + SN_ptr; + + struct SN : Profile + { + static u16 const id = 0x0004; + + public: + SN (Header const& h, istream& is) + : Profile (h, 8) + { + is >> n_; + } + + // 8 is CDR-specific. + // + SN (u64 n) + : Profile (id, 8, 8), n_ (n) + { + } + + public: + u64 + num () const + { + return n_; + } + + public: + virtual void + serialize_body (ostream& os) const + { + os << n_; + } + + private: + u64 n_; + }; + + + // + // + // + struct NAK; + + typedef + ACE_Refcounted_Auto_Ptr<NAK, ACE_Null_Mutex> + NAK_ptr; + + struct NAK : Profile + { + static u16 const id = 0x0005; + + typedef + ACE_Vector<u64> + SerialNumbers; + + typedef + SerialNumbers::Iterator + iterator; + + public: + NAK (Header const& h, istream& is) + : Profile (h, 8) + { + //@@ All the numbers are CDR-specific. + // + // 8 = u32 + u16 + 2(padding to u64) + // + for (long i (0); i < ((h.size () - 8) / 8); ++i) + { + u64 sn; + is >> sn; + sns_.push_back (sn); + } + + u32 addr; + u16 port; + + is >> port; + is >> addr; + + address_ = Address (port, addr); + } + + // 8 is CDR-specific. + // + NAK (Address const& src) + : Profile (id, 8, 8), address_ (src) + { + } + + public: + void + add (u64 sn) + { + sns_.push_back (sn); + size (size () + 8); //@@ 8 is CDR-specific + } + + public: + Address const& + address () const + { + return address_; + } + + + iterator + begin () /* const */ + { + return iterator (sns_); + } + + /* + iterator + end () const + { + return sns_.end (); + } + */ + + size_t + count () const + { + return sns_.size (); + } + + public: + virtual void + serialize_body (ostream& os) const + { + NAK& this_ (const_cast<NAK&> (*this)); // Don't put in ROM. + + // Stone age iteration. + // + for (iterator i (this_.begin ()); !i.done (); i.advance ()) + { + u64* psn; + i.next (psn); + os << *psn; + } + + + u32 addr (address_.get_ip_address ()); + u16 port (address_.get_port_number ()); + + os << port; + os << addr; + } + + private: + Address address_; + SerialNumbers sns_; + }; + + // + // + // + struct NRTM; + + typedef + ACE_Refcounted_Auto_Ptr<NRTM, ACE_Null_Mutex> + NRTM_ptr; + + struct NRTM : Profile + { + static u16 const id = 0x0006; + + public: + NRTM (Header const& h, istream& is) + : Profile (h, 8), map_ (10) + { + //@@ 16 is CDR-specific. + // + // 16 = u32 + u16 + 2(padding to u64) + u64 + for (u16 i (0); i < (h.size () / 16); ++i) + { + u32 addr; + u16 port; + u64 sn; + + is >> sn; + is >> port; + is >> addr; + + map_.bind (Address (port, addr), sn); + } + } + + NRTM () + : Profile (id, 0, 8), map_ (10) + { + } + + public: + void + insert (Address const& addr, u64 sn) + { + map_.bind (addr, sn); + + size (size () + 16); //@@ 16 is CDR-specific. + } + + u64 + find (Address const& addr) const + { + u64 sn; + + if (map_.find (addr, sn) == -1) return 0; + + return sn; + } + + bool + empty () const + { + return map_.current_size () == 0; + } + + public: + virtual void + serialize_body (ostream& os) const + { + for (Map::const_iterator i (map_), e (map_, 1); i != e; ++i) + { + u32 addr ((*i).ext_id_.get_ip_address ()); + u16 port ((*i).ext_id_.get_port_number ()); + u64 sn ((*i).int_id_); + + os << sn; + os << port; + os << addr; + } + } + + private: + typedef + ACE_Hash_Map_Manager_Ex<Address, + u64, + AddressHasher, + ACE_Equal_To<Address>, + ACE_Null_Mutex> + Map; + + Map map_; + }; + +} + +/* +inline +std::ostream& +operator<< (std::ostream& os, RMCast::Address const& a) +{ + char buf[64]; + a.addr_to_string (buf, 64, 1); + return os << buf; +} +*/ + + +#endif // ACE_RMCAST_PROTOCOL_H diff --git a/protocols/ace/RMCast/README b/protocols/ace/RMCast/README index ed6b22bf1c6..d8cfbc040c7 100644 --- a/protocols/ace/RMCast/README +++ b/protocols/ace/RMCast/README @@ -1,57 +1,22 @@ -# $Id$ - - This directory will contain a simple, small-scale reliable -multicast framework for ACE. The framework is based on the ASX -components of the ACE library: the protocol is implemented as a stack -of interchangeable "modules", each one in charge of a very small task. -For example, one module implements fragmentation and reassembly, other -modules implement retransmission, send ACK and NAK messages, and -maintain receiver membership. - - The modules are replaced to achieve different levels of -reliability. For example, the retransmission module can be either the -"Best_Effort", "Semi_Reliable" or "Reliable" implementation. In the -first case no retransmissions are performed, but lost messages are -detected and reported to the receiver. The "Semi_Reliable" case -messages are held for a pre-specified amount of time, and -re-transmited if requested, but it is possible to loose some messages -if multiple re-transmissions fail. As in the "Best_Effort" case the -lost messages are detected and flagged to the application. Finally -in the "Reliable" mode the senders are flowed controlled until enough -messages are successfully transmitted. - - In general the stack looks like this: - - -SENDER: - ----------------------------------------------------------------- -Buffering : Save lost messages -Retransmission : Retransmit ----------------------------------------------------------------- -Fragmentation : Fragment messages in smaller chunks -Reassembly : and ensure that the IOVMAX limit is not - : reached ----------------------------------------------------------------- -Transport : Encapsulate the specific transport media - : such as TCP/IP, ATM, or shared memory - : Demuxes incoming data to the right chain - : Change control messages and data messages - : to the right dynamic types. ----------------------------------------------------------------- - -RECEIVER: - ----------------------------------------------------------------- -Lost detection : Detect lost messages and send control - : messages back ----------------------------------------------------------------- -Reassembly : Reassemble messages, fragment control -Fragmentation : data ----------------------------------------------------------------- -Transport : Group membership, ACT reception, - : handle keep-alive messages... ----------------------------------------------------------------- - - -@@ TODO: Piggybacking... +RMCast is a reliable source-ordered multicast protocol implementation +for message-oriented multi-sender group communication built on top of +IPv4 multicast. It uses sequence numbers for re-ordering, duplicate +suppression and loss detection. Negative acknowledgments (NAK) with +retransmissions are used to recover from losses. + +One new and interesting idea implemented in this protocol is history +transmission (dubbed negative retransmission). In a nutshell, each +sender, along with normal payload, transmits a list of other sender's +IDs along with sequence numbers of last messages received from those +senders by this member. This, in some sense, builds a pyramid of +information: each subsequent message carries some information for a +number of previous messages (from other senders). This helps other +receivers detect losses. + +The protocol does not track group membership. Messages are retained +for retransmission for a predefined amount of time. The "last message +or lost message" dilemma is solved by periodic history transmissions +in cases when there is no useful traffic (idle network). + +-- +Boris Kolpackov <boris@kolpackov.net> diff --git a/protocols/ace/RMCast/RMCast.cpp b/protocols/ace/RMCast/RMCast.cpp deleted file mode 100644 index eb9887f8883..00000000000 --- a/protocols/ace/RMCast/RMCast.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// $Id$ - -#include "RMCast.h" - -ACE_RCSID(RMCast, RMCast, "$Id$") diff --git a/protocols/ace/RMCast/RMCast.h b/protocols/ace/RMCast/RMCast.h deleted file mode 100644 index 2339daa6f8e..00000000000 --- a/protocols/ace/RMCast/RMCast.h +++ /dev/null @@ -1,253 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_H -#define ACE_RMCAST_H -#include /**/ "ace/pre.h" - -#include "RMCast_Export.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/Basic_Types.h" - -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: - - //! 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 - RMCAST_MT_POLL, - RMCAST_MT_ACK_JOIN, - RMCAST_MT_ACK_LEAVE, - RMCAST_MT_DATA, - // Receiver initiated - RMCAST_MT_JOIN, - RMCAST_MT_LEAVE, - RMCAST_MT_ACK, - RMCAST_MT_LAST - }; - - //! 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 - }; - - - // 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 - // - If we are using authentic group communication we may - // piggyback the ACK / NAK messages - - ACE_Message_Block *payload; - - //! Pass the proxy source between layers - ACE_RMCast_Proxy *source; - }; - - /*! - <CODE> - +---------+----------------------+<BR> - | 8 bits | RMCAST_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 | RMCAST_MT_ACK_JOIN |<BR> - +---------+----------------------+<BR> - | 32 bits | next_sequence_number |<BR> - +---------+----------------------+<BR> - </CODE> - */ - struct Ack_Join - { - ACE_UINT32 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: - * - \param next_expected: is the sequence number of the next message - * expected, i.e. (next_expected-1) is the last message received - * without any losses before it. - * - \param highest_received: is the highest sequence number among - * all the messages successfully received. - * In other words, all messages lost (if any) are in the range: - * [next_expected,highest_received) - * - * <CODE> - * +---------+----------------------+<BR> - * | 8 bits | RMCAST_MT_ACK |<BR> - * +---------+----------------------+<BR> - * | 32 bits | next_expected |<BR> - * +---------+----------------------+<BR> - * | 32 bits | highest_received |<BR> - * +---------+----------------------+<BR> - * </CODE> - */ - struct Ack - { - //! The last message received without any losses before it. - ACE_UINT32 next_expected; - - //! 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 | RMCAST_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 | RMCAST_MT_LEAVE |<BR> - +---------+----------------------+<BR> - </CODE> - */ - struct Leave - { - //! Pass the proxy source between layers - ACE_RMCast_Proxy *source; - }; -}; - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_H */ diff --git a/protocols/ace/RMCast/RMCast.mpc b/protocols/ace/RMCast/RMCast.mpc new file mode 100644 index 00000000000..5ba1bd21b2d --- /dev/null +++ b/protocols/ace/RMCast/RMCast.mpc @@ -0,0 +1,7 @@ +// -*- MPC -*- +// $Id$ + +project(RMCast) : acelib, core { + sharedname = ACE_RMCast + dynamicflags = ACE_RMCAST_BUILD_DLL +} diff --git a/protocols/ace/RMCast/RMCast.rc b/protocols/ace/RMCast/RMCast.rc deleted file mode 100644 index 142de8a5625..00000000000 --- a/protocols/ace/RMCast/RMCast.rc +++ /dev/null @@ -1,30 +0,0 @@ -#include "..\Version.h" - -1 VERSIONINFO - FILEVERSION ACE_MAJOR_VERSION,ACE_MINOR_VERSION,ACE_BETA_VERSION,0 - PRODUCTVERSION ACE_MAJOR_VERSION,ACE_MINOR_VERSION,ACE_BETA_VERSION,0 - FILEFLAGSMASK 0x3fL - FILEFLAGS 0x0L - FILEOS 0x4L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904B0" - BEGIN - VALUE "FileDescription", "RMCast\0" - VALUE "FileVersion", ACE_VERSION "\0" - VALUE "InternalName", "RMCastDLL\0" - VALUE "LegalCopyright", "\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "RMCast.DLL\0" - VALUE "ProductName", "ACE\0" - VALUE "ProductVersion", ACE_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/protocols/ace/RMCast/RMCast_Ack_Worker.cpp b/protocols/ace/RMCast/RMCast_Ack_Worker.cpp deleted file mode 100644 index d454e013056..00000000000 --- a/protocols/ace/RMCast/RMCast_Ack_Worker.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Ack_Worker.h" -#include "ace/Message_Block.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Ack_Worker.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Ack_Worker, "$Id$") - -int -ACE_RMCast_Ack_Worker::work (ACE_UINT32 const & key, - ACE_RMCast::Data const &item) -{ - if (key >= this->ack_.next_expected) - return 0; - // ACE_DEBUG ((LM_DEBUG, - // " Retransmission::ack - message %d erased\n", - // key)); - ACE_Message_Block::release (item.payload); - return this->messages_->unbind_i (this->ace_mon_, key); -} diff --git a/protocols/ace/RMCast/RMCast_Ack_Worker.h b/protocols/ace/RMCast/RMCast_Ack_Worker.h deleted file mode 100644 index b4d81e4e972..00000000000 --- a/protocols/ace/RMCast/RMCast_Ack_Worker.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_ACK_WORKER_H -#define ACE_RMCAST_ACK_WORKER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Retransmission.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Process an Ack message in the ACE_RMCast_Retransmission module -/** - * The retransmission module uses internal iterators, thus it needs to - * create helper Worker classes to process some messages. - */ -class ACE_RMCast_Ack_Worker - : public ACE_RMCast_Worker<ACE_UINT32,ACE_RMCast::Data> -{ -public: - ACE_RMCast_Ack_Worker (ACE_RMCast::Ack &ack, - ACE_RMCast_Retransmission::Messages::Write_Guard &g, - ACE_RMCast_Retransmission::Messages *messages); - - virtual int work (ACE_UINT32 const & key, - ACE_RMCast::Data const &item); - -private: - ACE_RMCast_Ack_Worker (const ACE_RMCast_Ack_Worker&); - ACE_RMCast_Ack_Worker& operator= (const ACE_RMCast_Ack_Worker&); - -private: - ACE_RMCast::Ack &ack_; - - ACE_RMCast_Retransmission::Messages::Write_Guard &ace_mon_; - - ACE_RMCast_Retransmission::Messages *messages_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Ack_Worker.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_ACK_WORKER_H */ diff --git a/protocols/ace/RMCast/RMCast_Ack_Worker.i b/protocols/ace/RMCast/RMCast_Ack_Worker.i deleted file mode 100644 index 54d94d21167..00000000000 --- a/protocols/ace/RMCast/RMCast_Ack_Worker.i +++ /dev/null @@ -1,12 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Ack_Worker:: -ACE_RMCast_Ack_Worker (ACE_RMCast::Ack &ack, - ACE_RMCast_Retransmission::Messages::Write_Guard &g, - ACE_RMCast_Retransmission::Messages *messages) - : ack_ (ack) - , ace_mon_ (g) - , messages_ (messages) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Copy_On_Write.cpp b/protocols/ace/RMCast/RMCast_Copy_On_Write.cpp deleted file mode 100644 index 39bf16f88a2..00000000000 --- a/protocols/ace/RMCast/RMCast_Copy_On_Write.cpp +++ /dev/null @@ -1,199 +0,0 @@ -// $Id$ - -#ifndef ACE_RMCAST_COPY_ON_WRITE_CPP -#define ACE_RMCAST_COPY_ON_WRITE_CPP - -#include "RMCast_Copy_On_Write.h" - -#if ! defined (__ACE_INLINE__) -#include "RMCast_Copy_On_Write.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Copy_On_Write, "$Id$") - -template<class COLLECTION, class ITERATOR> void -ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR>::_incr_refcnt (void) -{ - // LOCKING: no locking is required, the caller grabs the mutex. - this->refcount_++; -} - -template<class COLLECTION, class ITERATOR> void -ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR>::_decr_refcnt (void) -{ - // LOCKING: no locking is required, the caller grabs the mutex. - { - this->refcount_--; - if (this->refcount_ != 0) - return; - } - //@@ TODO: If this wrapper is going to be completely general some - // kind of functor has to be provided to remove the elements in the - // collection, in case the are no self-managed - - delete this; -} - -// **************************************************************** - -template<class KEY, class ITEM, class COLLECTION, class ITERATOR> -ACE_RMCast_Copy_On_Write<KEY,ITEM,COLLECTION,ITERATOR>:: - ACE_RMCast_Copy_On_Write (void) - : ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR> () -{ -} - -template<class KEY, class ITEM, class COLLECTION, class ITERATOR> -ACE_RMCast_Copy_On_Write<KEY,ITEM,COLLECTION,ITERATOR>:: - ~ACE_RMCast_Copy_On_Write (void) -{ - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_); - - while (this->pending_writes_ != 0) - this->cond_.wait (); - - this->collection_->_decr_refcnt (); - this->collection_ = 0; -} - -template<class KEY, class ITEM, class COLLECTION, class ITERATOR> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,COLLECTION,ITERATOR>:: - for_each (ACE_RMCast_Worker<KEY,ITEM> *worker) -{ - Read_Guard ace_mon (*this); - - ITERATOR end = ace_mon.collection->collection.end (); - for (ITERATOR i = ace_mon.collection->collection.begin (); i != end; ++i) - { - int r = worker->work ((*i).key (), (*i).item ()); - if (r == 1) - return 0; // Abort loop, but no error - if (r == -1) - return -1; - } - return 0; -} - -template<class KEY, class ITEM, class C, class ITERATOR> KEY -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,ITERATOR>::first_key (void) -{ - Read_Guard ace_mon (*this); - ITERATOR end = ace_mon.collection->collection.end (); - ITERATOR begin = ace_mon.collection->collection.begin (); - if (begin == end) - { - return KEY (); - } - return (*begin).key (); -} - -template<class KEY, class ITEM, class C, class ITERATOR> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,ITERATOR>::empty (void) -{ - Read_Guard ace_mon (*this); - ITERATOR end = ace_mon.collection->collection.end (); - ITERATOR begin = ace_mon.collection->collection.begin (); - - return end == begin; -} - -template<class KEY, class ITEM, class C, class I> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,I>::bind (KEY const & k, - ITEM const & i) -{ - Write_Guard ace_mon (*this); - - return this->bind_i (ace_mon, k, i); -} - -template<class KEY, class ITEM, class C, class I> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,I>::unbind (KEY const & k) -{ - Write_Guard ace_mon (*this); - - return this->unbind_i (ace_mon, k); -} - -template<class KEY, class ITEM, class C, class I> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,I>::bind_i (Write_Guard &ace_mon, - KEY const & k, - ITEM const & i) -{ - return ace_mon.copy->collection.bind (k, i); -} - -template<class KEY, class ITEM, class C, class I> int -ACE_RMCast_Copy_On_Write<KEY,ITEM,C,I>::unbind_i (Write_Guard &ace_mon, - KEY const & k) -{ - return ace_mon.copy->collection.unbind (k); -} - -// **************************************************************** - -template<class COLLECTION, class ITERATOR> -ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR>::ACE_RMCast_Copy_On_Write_Container (void) - : pending_writes_ (0) - , writing_ (0) - , cond_ (mutex_) -{ - ACE_NEW (this->collection_, Collection); -} - -// **************************************************************** - -template<class COLLECTION, class ITERATOR> -ACE_RMCast_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR>:: - ACE_RMCast_Copy_On_Write_Write_Guard (Container &container) - : copy (0) - , mutex (container.mutex_) - , cond (container.cond_) - , pending_writes (container.pending_writes_) - , writing_flag (container.writing_) - , collection (container.collection_) -{ - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex); - - this->pending_writes++; - - while (this->writing_flag != 0) - this->cond.wait (); - - this->writing_flag = 1; - } - - // Copy outside the mutex, because it may take a long time. - // Nobody can change it, because it is protected by the - // writing_flag. - - // First initialize it (with the correct reference count - ACE_NEW (this->copy, Collection); - // Copy the contents - this->copy->collection = this->collection->collection; -} - -template<class COLLECTION, class ITERATOR> -ACE_RMCast_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR>:: - ~ACE_RMCast_Copy_On_Write_Write_Guard (void) -{ - Collection *tmp = 0; - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex); - - tmp = this->collection; - this->collection = this->copy; - this->writing_flag = 0; - this->pending_writes--; - - this->cond.signal (); - } - // Delete outside the mutex, because it may take a long time. - // @@ Is this right? What happens if several readers are still - // using the old copy? - tmp->_decr_refcnt (); -} - -// **************************************************************** - -#endif /* ACE_RMCAST_COPY_ON_WRITE_CPP */ diff --git a/protocols/ace/RMCast/RMCast_Copy_On_Write.h b/protocols/ace/RMCast/RMCast_Copy_On_Write.h deleted file mode 100644 index bad0318638e..00000000000 --- a/protocols/ace/RMCast/RMCast_Copy_On_Write.h +++ /dev/null @@ -1,214 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_COPY_ON_WRITE_H -#define ACE_RMCAST_COPY_ON_WRITE_H -#include /**/ "ace/pre.h" - -#include "RMCast_Worker.h" -#include "ace/Synch_Traits.h" -#include "ace/Basic_Types.h" -#include "ace/Condition_Thread_Mutex.h" - -//! A wrapper to implement reference counted collections -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Collection -{ -public: - //! Constructor - ACE_RMCast_Copy_On_Write_Collection (void); - - //! Increment the reference count - void _incr_refcnt (void); - - //! Decrement the reference count - void _decr_refcnt (void); - - //! The actual collection - COLLECTION collection; - -private: - //! The reference count - ACE_UINT32 refcount_; -}; - -// **************************************************************** - -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Read_Guard; - -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Write_Guard; - -//! Base class for the Copy_On_Write collection, used to simplify the -//! declaration of the Write_Guard -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Container -{ -public: - //! Constructor - ACE_RMCast_Copy_On_Write_Container (void); - - //! Let the Write_Guard access the internal fields. - friend class ACE_RMCast_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR>; - - //! Let the Read_Guard access the internal fields. - friend class ACE_RMCast_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR>; - - //! A shorter name for the actual collection type - typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection; - -protected: - //! Number of pending writes - int pending_writes_; - - //! If non-zero then a thread is changing the collection. - /*! - * Many threads can use the collection simulatenously, but only one - * change it. - */ - int writing_; - - //! A mutex to serialize access to the collection pointer. - ACE_SYNCH_MUTEX mutex_; - - //! A condition variable to wait to synchronize multiple writers. - ACE_SYNCH_CONDITION cond_; - - //! The collection, with reference counting added - Collection *collection_; -}; - -// **************************************************************** - -//! Implement a read guard for a reference counted collection -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Read_Guard -{ -public: - typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection; - typedef ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR> Container; - - //! Constructor - ACE_RMCast_Copy_On_Write_Read_Guard (Container &container); - - //! Destructor - ~ACE_RMCast_Copy_On_Write_Read_Guard (void); - - //! A reference to the collection - Collection *collection; - -private: - //! Synchronization - ACE_SYNCH_MUTEX &mutex_; -}; - -// **************************************************************** - -//! Implement the write guard for a reference counted collecion -/*! - * This helper class atomically increments the reference count of a - * ACE_RMCast_Copy_On_Write_Collection and reads the current - * collection in the Copy_On_Write class. - */ -template<class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write_Write_Guard -{ -public: - typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection; - typedef ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR> Container; - - //! Constructor - ACE_RMCast_Copy_On_Write_Write_Guard (Container &container); - - //! Destructor - ~ACE_RMCast_Copy_On_Write_Write_Guard (void); - - //! The collection - Collection *copy; - -private: - //! Keep a reference to the mutex - ACE_SYNCH_MUTEX &mutex; - - //! Keep a reference to the condition variable - ACE_SYNCH_CONDITION &cond; - - //! Use a reference to update the pending writes count - int &pending_writes; - - //! Use a reference to update the writing flag - int &writing_flag; - - //! Use this reference to update the collection once the - //! modifications are finished. - Collection *&collection; -}; - - -// **************************************************************** - -//! Implement a copy on write wrapper for a map-like collection -/* - * - * <B>WARNING: </B> This class may be moved away in the future, I'm - * investigating how it could be converted into a reusable component - * in ACE. I won't make promises on when will that happen, but I - * won't promise that it will stay here either. - * - */ -template<class KEY, class ITEM, class COLLECTION, class ITERATOR> -class ACE_RMCast_Copy_On_Write : public ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR> -{ -public: - //! The Read_Guard trait - typedef ACE_RMCast_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR> Read_Guard; - - //! The Write_Guard trait - typedef ACE_RMCast_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR> Write_Guard; - - //! The underlying collection type - typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection; - - //! Constructor - ACE_RMCast_Copy_On_Write (void); - - //! Destructor - ~ACE_RMCast_Copy_On_Write (void); - - //! Iterate over all the elements invoking worker on each one. - int for_each (ACE_RMCast_Worker<KEY,ITEM> *worker); - - //! Get the first key - KEY first_key (void); - - /// Return non-zero if the collection is empty - int empty (void); - - //! Add a new element - int bind (KEY const & key, ITEM const & item); - - //! Remove an element - int unbind (KEY const & key); - - //! Bind assuming the Write_Guard is held - int bind_i (Write_Guard &guard, KEY const & key, ITEM const & item); - - //! Unbind assuming the Write_Guard is held - int unbind_i (Write_Guard &guard, KEY const & key); -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Copy_On_Write.i" -#endif /* __ACE_INLINE__ */ - -#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "RMCast_Copy_On_Write.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - -#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) -#pragma implementation ("RMCast_Copy_On_Write.cpp") -#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_COPY_ON_WRITE_H */ diff --git a/protocols/ace/RMCast/RMCast_Copy_On_Write.i b/protocols/ace/RMCast/RMCast_Copy_On_Write.i deleted file mode 100644 index c83483c0729..00000000000 --- a/protocols/ace/RMCast/RMCast_Copy_On_Write.i +++ /dev/null @@ -1,38 +0,0 @@ -// -*- C++ -*- -// $Id$ - -#include "ace/Guard_T.h" -#include "ace/Null_Mutex.h" - -template<class COLLECTION, class ITERATOR> ACE_INLINE -ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR>:: - ACE_RMCast_Copy_On_Write_Collection (void) - : refcount_ (1) -{ -} - -// **************************************************************** - -template<class COLLECTION, class ITERATOR> ACE_INLINE -ACE_RMCast_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR>:: - ACE_RMCast_Copy_On_Write_Read_Guard (Container &container) - : collection (0) - , mutex_ (container.mutex_) -{ - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_); - this->collection = container.collection_; - this->collection->_incr_refcnt (); -} - -template<class COLLECTION, class ITERATOR> ACE_INLINE -ACE_RMCast_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR>:: - ~ACE_RMCast_Copy_On_Write_Read_Guard (void) -{ - if (this->collection != 0) - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_); - this->collection->_decr_refcnt (); - } -} - -// **************************************************************** diff --git a/protocols/ace/RMCast/RMCast_Fork.cpp b/protocols/ace/RMCast/RMCast_Fork.cpp deleted file mode 100644 index 92c81b9d33e..00000000000 --- a/protocols/ace/RMCast/RMCast_Fork.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// $Id$ - -#include "RMCast_Fork.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Fork.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Fork, "$Id$") - -ACE_RMCast_Fork::~ACE_RMCast_Fork (void) -{ -} - -int -ACE_RMCast_Fork::open (void) -{ - int r = this->ACE_RMCast_Module::open (); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->open (); - return 0; -} - -int -ACE_RMCast_Fork::close (void) -{ - int r = this->ACE_RMCast_Module::close (); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->close (); - return 0; -} - -int -ACE_RMCast_Fork::data (ACE_RMCast::Data &data) -{ - int r = this->ACE_RMCast_Module::data (data); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->data (data); - return 0; -} - -int -ACE_RMCast_Fork::poll (ACE_RMCast::Poll &poll) -{ - int r = this->ACE_RMCast_Module::poll (poll); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->poll (poll); - return 0; -} - -int -ACE_RMCast_Fork::ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - int r = this->ACE_RMCast_Module::ack_join (ack_join); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->ack_join (ack_join); - return 0; -} - -int -ACE_RMCast_Fork::ack_leave (ACE_RMCast::Ack_Leave &ack_leave) -{ - int r = this->ACE_RMCast_Module::ack_leave (ack_leave); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->ack_leave (ack_leave); - return 0; -} - -int -ACE_RMCast_Fork::ack (ACE_RMCast::Ack &ack) -{ - int r = this->ACE_RMCast_Module::ack (ack); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->ack (ack); - return 0; -} - -int -ACE_RMCast_Fork::join (ACE_RMCast::Join &join) -{ - int r = this->ACE_RMCast_Module::join (join); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->join (join); - return 0; -} - -int -ACE_RMCast_Fork::leave (ACE_RMCast::Leave &leave) -{ - int r = this->ACE_RMCast_Module::leave (leave); - if (r != 0) - return r; - if (this->secondary () != 0) - return this->secondary ()->leave (leave); - return 0; -} diff --git a/protocols/ace/RMCast/RMCast_Fork.h b/protocols/ace/RMCast/RMCast_Fork.h deleted file mode 100644 index 498ee2d6d63..00000000000 --- a/protocols/ace/RMCast/RMCast_Fork.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_FORK_H -#define ACE_RMCAST_FORK_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Fork messages to multiple destinations -/** - * In some instances the messages must be sent to multiple - * destinations, this module is a generic component to duplicate such - * messages. - */ -class ACE_RMCast_Export ACE_RMCast_Fork : public ACE_RMCast_Module -{ -public: - //! Constructor - ACE_RMCast_Fork (void); - - //! Destructor - virtual ~ACE_RMCast_Fork (void); - - /// Set the control module, all incoming control messages go to it - void secondary (ACE_RMCast_Module *module); - - /// Return the current control module - ACE_RMCast_Module *secondary (void) const; - - virtual int open (void); - virtual int close (void); - virtual int data (ACE_RMCast::Data &); - virtual int poll (ACE_RMCast::Poll &); - virtual int ack_join (ACE_RMCast::Ack_Join &); - virtual int ack_leave (ACE_RMCast::Ack_Leave &); - virtual int ack (ACE_RMCast::Ack &); - virtual int join (ACE_RMCast::Join &); - virtual int leave (ACE_RMCast::Leave &); - -private: - /// The control module - ACE_RMCast_Module *secondary_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Fork.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_FORK_H */ diff --git a/protocols/ace/RMCast/RMCast_Fork.i b/protocols/ace/RMCast/RMCast_Fork.i deleted file mode 100644 index bbcd4f23ae1..00000000000 --- a/protocols/ace/RMCast/RMCast_Fork.i +++ /dev/null @@ -1,21 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Fork::ACE_RMCast_Fork (void) - : ACE_RMCast_Module () - , secondary_ (0) -{ -} - -ACE_INLINE void -ACE_RMCast_Fork::secondary (ACE_RMCast_Module *module) -{ - this->secondary_ = module; -} - - -ACE_INLINE ACE_RMCast_Module * -ACE_RMCast_Fork::secondary (void) const -{ - return this->secondary_; -} diff --git a/protocols/ace/RMCast/RMCast_Fragment.cpp b/protocols/ace/RMCast/RMCast_Fragment.cpp deleted file mode 100644 index 2c8cae86d7e..00000000000 --- a/protocols/ace/RMCast/RMCast_Fragment.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// $Id$ - -#include "RMCast_Fragment.h" -#include "ace/Message_Block.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#if !defined (__ACE_INLINE__) -#include "RMCast_Fragment.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Fragment, "$Id$") - -ACE_RMCast_Fragment:: -ACE_RMCast_Fragment (void) - : ACE_RMCast_Module () - , max_fragment_size_ (ACE_RMCAST_DEFAULT_FRAGMENT_SIZE) -{ -} - -ACE_RMCast_Fragment::~ACE_RMCast_Fragment (void) -{ -} - -int -ACE_RMCast_Fragment::data (ACE_RMCast::Data &received_data) -{ - if (this->next () == 0) - return 0; - - // The Data object sent downstream - ACE_RMCast::Data data = received_data; - - ACE_Message_Block *mb = data.payload; - - // @@ We should keep the total size precomputed - data.total_size = static_cast<ACE_UINT32> (mb->total_length ()); - - // We must leave room for the header -#if defined (ACE_HAS_BROKEN_DGRAM_SENDV) - const int ACE_RMCAST_WRITEV_MAX = ACE_IOV_MAX - 2; -#else - const int ACE_RMCAST_WRITEV_MAX = ACE_IOV_MAX - 1; -#endif /* ACE_HAS_BROKEN_DGRAM_SENDV */ - - // Assume the header will be included on each fragment, so readuce - // the maximum amount of memory allowed on each fragment.... - const size_t fragment_header_size = 1 + 3 * sizeof(ACE_UINT32); - - const size_t max_fragment_payload = - this->max_fragment_size_ - fragment_header_size; - - // Iterate over all the message blocks in the chain. If there is - // enough data to send an MTU then it is sent immediately. - // The last fragment is sent with whatever data remains. - // A single fragment can expand multiple message blocks, put - // together in an <iovec> array, it is also possible that a single - // message block requires multiple fragments... so the code below is - // as simple as possible, but not any simpler ;-) - - - // The first piece of each fragment is a header that contains: - // - A sequence number for reassembly, this is unrelated to - // the sequence number for re-transmission. - // NOTE: yes, this increases the bandwidth requires by 4 bytes on - // each message, I don't think this is a big deal. - // - A fragment offset for reassembly. - // - The total size of the message, so the reassembly layer knows - // when a complete message has been received. - - // Complete the initialization of the <data> structure - - data.fragment_offset = 0; - - // The underlying transport layer can only tolerate so many elements - // in a chain, so we must count them and send a fragment if we are - // going over the limit. - - ACE_Message_Block blocks[ACE_RMCAST_WRITEV_MAX]; - - - // How many elements of the <blocks> array are in use... - int iovcnt = 0; - - // The size of the current message, adding the size of all its - // message blocks. - size_t fragment_size = 0; - - for (ACE_Message_Block* b = mb; b != 0; b = b->cont ()) - { - ACE_Message_Block *current_block = &blocks[iovcnt]; - - // Add the block to the vector... - - current_block->data_block (b->data_block ()->duplicate ()); - current_block->rd_ptr (b->rd_ptr ()); - current_block->wr_ptr (b->wr_ptr ()); - current_block->cont (0); - - // Set the continuation field - if (iovcnt != 0) - blocks[iovcnt-1].cont (current_block); - - size_t current_block_length = current_block->length (); - - // Recompute the state of the fragment - fragment_size += current_block_length; - iovcnt++; - - while (fragment_size >= max_fragment_payload) - { - // We have filled a fragment. It is possible that we need - // to split the last message block in multiple fragments, - // thus the loop above... - - // First adjust the last message block to exactly fit in the - // fragment: - size_t last_sent_mb_len = - max_fragment_payload - (fragment_size - current_block_length); - - // Send only enough data of the last message block to fill - // the fragment... - current_block->wr_ptr (current_block->rd_ptr () - + last_sent_mb_len); - - data.payload = blocks; - if (this->next ()->data (data) == -1) - return -1; - - // adjust the offset - data.fragment_offset += static_cast<ACE_UINT32> (max_fragment_payload); - - // Now compute how much data is left in the last message - // block, to check if we should continue sending it... - current_block_length -= last_sent_mb_len; - if (current_block_length == 0) - { - // No more data from this message block, just continue - // the outer loop... - iovcnt = 0; - fragment_size = 0; - blocks[0].cont (0); - break; // while - } - - // There is some data left, we try to send it in a single - // fragment, if it is still too big the beginning of this - // loop will adjust things. - - // We must put the data in the right place in the array.. - char *rd_ptr = current_block->rd_ptr () + last_sent_mb_len; - char *wr_ptr = rd_ptr + current_block_length; - blocks[0].data_block (current_block->replace_data_block (0)); - - // And determine what segment of the data will be sent.. - blocks[0].rd_ptr (rd_ptr); - blocks[0].wr_ptr (wr_ptr); - blocks[0].cont (0); - - // Adjust the state of the fragment - fragment_size = current_block_length; - iovcnt = 1; - - // Notice that if <fragment_size> is too big the start of - // this loop will continue the fragmentation. - } - - // It is also possible to fill up the iovec array before the - // fragment is completed, in this case we must send whatever we - // have: - if (iovcnt == ACE_RMCAST_WRITEV_MAX) - { - if (this->next ()->data (data) == -1) - return -1; - - iovcnt = 0; - fragment_size = 0; - blocks[0].cont (0); - } - } - - if (iovcnt == 0) - return 0; - - return this->next ()->data (data); -} diff --git a/protocols/ace/RMCast/RMCast_Fragment.h b/protocols/ace/RMCast/RMCast_Fragment.h deleted file mode 100644 index f180087ce3e..00000000000 --- a/protocols/ace/RMCast/RMCast_Fragment.h +++ /dev/null @@ -1,61 +0,0 @@ -// $Id$ - -#ifndef ACE_RMCAST_FRAGMENT_H -#define ACE_RMCAST_FRAGMENT_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -//! Default fragment size -#ifndef ACE_RMCAST_DEFAULT_FRAGMENT_SIZE -# define ACE_RMCAST_DEFAULT_FRAGMENT_SIZE 1024 -#endif /* ACE_RMCAST_DEFAULT_FRAGMENT_SIZE */ - -//! Fragmentation module -/*! - * Some transports cannot send very big messages, for example UDP - * imposes a limit of 64K, and in practice the limit is even more - * strict than that. - * This class decomposes a message into multiple fragments, using an - * application defined maximum size. - */ -class ACE_RMCast_Export ACE_RMCast_Fragment : public ACE_RMCast_Module -{ -public: - //! Constructor - ACE_RMCast_Fragment (void); - - //! Destructor - virtual ~ACE_RMCast_Fragment (void); - - //! Accessor for the max_fragment size. - /*! There is no modifier, the maximum fragment size is obtained - * using feedback from the lower layers (transport?) - * @@TODO We have not implemented the feedback mechanisms yet! - */ - size_t max_fragment_size (void) const; - - /*! - * Only data messages need fragmentation, the control messages are - * all small enough for all the transports that I know about. - * Well, actually for CAN-Bus (Controller Area Network), they may be - * too big, because the max payload there is 8 bytes, but we don't - * play with those in ACE. - */ - virtual int data (ACE_RMCast::Data &data); - -private: - //! Current fragment size limit - size_t max_fragment_size_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Fragment.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_FRAGMENT_H */ diff --git a/protocols/ace/RMCast/RMCast_Fragment.i b/protocols/ace/RMCast/RMCast_Fragment.i deleted file mode 100644 index 8e628093b8c..00000000000 --- a/protocols/ace/RMCast/RMCast_Fragment.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE size_t -ACE_RMCast_Fragment::max_fragment_size (void) const -{ - return this->max_fragment_size_; -} diff --git a/protocols/ace/RMCast/RMCast_IO_UDP.cpp b/protocols/ace/RMCast/RMCast_IO_UDP.cpp deleted file mode 100644 index 60940ad9465..00000000000 --- a/protocols/ace/RMCast/RMCast_IO_UDP.cpp +++ /dev/null @@ -1,461 +0,0 @@ -// $Id$ - -#include "RMCast_IO_UDP.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_IO_UDP.i" -#endif /* ! __ACE_INLINE__ */ - -#include "RMCast_UDP_Proxy.h" -#include "RMCast_Module_Factory.h" - -#include "ace/Handle_Set.h" -#include "ace/Reactor.h" -#include "ace/Message_Block.h" -#include "ace/OS_NS_string.h" -#include "ace/OS_NS_sys_select.h" -#include "ace/os_include/arpa/os_inet.h" -#include "ace/OS_NS_unistd.h" - -ACE_RCSID(RMCast, RMCast_IO_UDP, "RMCast_IO_UDP.cpp,v 1.12 2000/12/20 22:00:33 oci Exp") - -ACE_RMCast_IO_UDP::~ACE_RMCast_IO_UDP (void) -{ -} - -int -ACE_RMCast_IO_UDP::init (const ACE_INET_Addr &mcast_group, - const ACE_Addr &local, - int protocol_family, - int protocol, - int reuse_addr) -{ - this->mcast_group_ = mcast_group; - - ACE_SOCK_Dgram &dgram = this->dgram_; - return dgram.open (local, protocol_family, protocol, reuse_addr); -} - -int -ACE_RMCast_IO_UDP::subscribe (const ACE_INET_Addr &mcast_addr, - int reuse_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol) -{ - this->mcast_group_ = mcast_addr; - return this->dgram_.subscribe (mcast_addr, - reuse_addr, - net_if, - protocol_family, - protocol); -} - -int -ACE_RMCast_IO_UDP::handle_events (ACE_Time_Value *tv) -{ - ACE_HANDLE h = this->dgram_.get_handle (); - if (h == ACE_INVALID_HANDLE) - return -1; - - ACE_Handle_Set handle_set; - handle_set.set_bit (h); - - ACE_Countdown_Time countdown (tv); - - int r = ACE_OS::select (int(size_t(h)) + 1, - handle_set, 0, 0, - tv); - if (r == -1) - { - if (errno == EINTR) - return 0; - else - return -1; - } - else if (r == 0) - { - return 0; - } - - return this->handle_input (h); -} - -int -ACE_RMCast_IO_UDP::handle_input (ACE_HANDLE) -{ - char buffer[ACE_MAX_UDP_PACKET_SIZE]; - - ACE_INET_Addr from_address; - ssize_t r = - this->dgram_.recv (buffer, sizeof(buffer), from_address); - - if (r == -1) - { - // @@ LOG?? - ACE_ERROR ((LM_ERROR, - "RMCast_IO_UDP::handle_input () - error in recv %p\n", - ACE_TEXT (""))); - return -1; - } - - // ACE_HEX_DUMP ((LM_DEBUG, buffer, 16, "Receiver::handle_input")); - - // @@ Locking! - - int type = buffer[0]; - - if (type < 0 || type >= ACE_RMCast::RMCAST_MT_LAST) - { - // @@ Log: invalid message type!! - // @@ TODO: should we return -1? The socket is still valid, it - // makes little sense to destroy it just because one remote - // sender is sending invalid messages. Maybe we should - // strategize this too, and report the problem to the - // application, this could indicate a misconfiguration or - // something worse... - - // In any case the proxy should be destroyed, its peer is making - // something really wrong. - ACE_RMCast_UDP_Proxy *proxy; - if (this->map_.unbind (from_address, proxy) == 0) - { - this->factory_->destroy (proxy->next ()); - delete proxy; - } - return 0; - } - - ACE_RMCast_UDP_Proxy *proxy; - if (this->map_.find (from_address, proxy) != 0) - { - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::handle_input - new proxy from <%s:%d>\n", - // from_address.get_host_addr (), - // from_address.get_port_number ())); - - // @@ We should validate the message *before* creating the - // object, all we need is some sort of validation strategy, a - // different one for the receiver and another one for the - // sender. - -#if 0 - if (type == ACE_RMCast::RMCAST_MT_ACK - || type == ACE_RMCast::RMCAST_MT_JOIN - || type == ACE_RMCast::RMCAST_MT_LEAVE - || type == ACE_RMCast::RMCAST_MT_ACK_LEAVE) - { - // All these message types indicate a problem, the should be - // generated by receivers, not received by them. - return 0; - } -#endif /* 0 */ - ACE_RMCast_Module *module = this->factory_->create (); - if (module == 0) - { - // @@ LOG?? - // Try to continue working, maybe the module can be created - // later. - return 0; - } - // This is necessary to satisfy the xgcc for Lynx on Solaris - // by including the code directly causes : - // RMCast_IO_UDP.cpp:202: error: internal error--unrecognizable insn: - // (insn 1510 1507 524 (set (mem:SI (plus:SI (reg:SI 28 r28) - // (const_int 65536))) - // (reg:SI 0 r0)) -1 (insn_list 528 (insn_list 1507 (nil))) - // (nil)) - // /usr/lynx/home2/jose/98r2/src/gcc/toplev.c:1489: Internal compiler error in function fatal_insn - // to be thrown at the end of the function. - if ((proxy = allocate_and_bind_proxy(module,from_address)) == 0) - return 0; - } - - // Have the proxy process the message and do the right thing. - if (proxy->receive_message (buffer, r) != 0) - { - (void) this->map_.unbind (from_address); - this->factory_->destroy (proxy->next ()); - delete proxy; - } - - return 0; -} - -ACE_HANDLE -ACE_RMCast_IO_UDP::get_handle (void) const -{ - return this->dgram_.get_handle (); -} - -int -ACE_RMCast_IO_UDP::data (ACE_RMCast::Data &data) -{ - return this->send_data (data, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::poll (ACE_RMCast::Poll &poll) -{ - return this->send_poll (poll, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - return this->send_ack_join (ack_join, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::ack_leave (ACE_RMCast::Ack_Leave &ack_leave) -{ - return this->send_ack_leave (ack_leave, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::ack (ACE_RMCast::Ack &ack) -{ - return this->send_ack (ack, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::join (ACE_RMCast::Join &join) -{ - return this->send_join (join, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::leave (ACE_RMCast::Leave &leave) -{ - return this->send_leave (leave, this->mcast_group_); -} - -int -ACE_RMCast_IO_UDP::send_data (ACE_RMCast::Data &data, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_data - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // The first message block contains the header - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - ACE_UINT32 tmp; - char header[1 + 3 * sizeof(ACE_UINT32)]; - header[0] = ACE_RMCast::RMCAST_MT_DATA; - - tmp = ACE_HTONL (data.sequence_number); - ACE_OS::memcpy (header + 1, - &tmp, sizeof(ACE_UINT32)); - tmp = ACE_HTONL (data.total_size); - ACE_OS::memcpy (header + 1 + sizeof(ACE_UINT32), - &tmp, sizeof(ACE_UINT32)); - tmp = ACE_HTONL (data.fragment_offset); - ACE_OS::memcpy (header + 1 + 2 * sizeof(ACE_UINT32), - &tmp, sizeof(ACE_UINT32)); - - iovec iov[ACE_IOV_MAX]; - int iovcnt = 1; - - iov[0].iov_base = header; - iov[0].iov_len = sizeof(header); - - ACE_Message_Block *mb = data.payload; - - for (const ACE_Message_Block *i = mb; i != 0; i = i->cont ()) - { - iov[iovcnt].iov_base = i->rd_ptr (); - iov[iovcnt].iov_len = static_cast<u_long> (i->length ()); - iovcnt++; - if (iovcnt >= IOV_MAX) - return -1; - } - - // @@ This pacing stuff here reduced the number of packet lost in - // loopback tests, but it should be taken out for real applications - // (or at least made configurable!) - ACE_Time_Value tv (0, 10000); - ACE_OS::sleep (tv); - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (iov, iovcnt, to) == -1) - return -1; - -#if 0 - ACE_HEX_DUMP ((LM_DEBUG, - (char*)iov[0].iov_base, - iov[0].iov_len, - "Sending")); -#endif - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_poll (ACE_RMCast::Poll &, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_poll - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_POLL; - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1, to) == -1) - return -1; - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_ack_join (ACE_RMCast::Ack_Join &ack_join, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_ack_join - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_ACK_JOIN; - - ACE_UINT32 tmp = ACE_HTONL (ack_join.next_sequence_number); - ACE_OS::memcpy (header + 1, - &tmp, sizeof(ACE_UINT32)); - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1 + sizeof(ACE_UINT32), to) == -1) - return -1; - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_ack_leave (ACE_RMCast::Ack_Leave &, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_ack_leave - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_ACK_LEAVE; - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1, to) == -1) - return -1; - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_ack (ACE_RMCast::Ack &ack, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_ack - pushing (%d:%d) out to <%s:%d>\n", - // ack.next_expected, - // ack.highest_received, - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_ACK; - - ACE_UINT32 tmp = ACE_HTONL (ack.next_expected); - ACE_OS::memcpy (header + 1, - &tmp, sizeof(ACE_UINT32)); - tmp = ACE_HTONL (ack.highest_received); - ACE_OS::memcpy (header + 1 + sizeof(ACE_UINT32), - &tmp, sizeof(ACE_UINT32)); - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1 + 2*sizeof(ACE_UINT32), to) == -1) - return -1; - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_join (ACE_RMCast::Join &, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_join - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_JOIN; - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1, to) == -1) - return -1; - - return 0; -} - -int -ACE_RMCast_IO_UDP::send_leave (ACE_RMCast::Leave &, - const ACE_INET_Addr &to) -{ - //ACE_DEBUG ((LM_DEBUG, - // "IO_UDP::send_leave - pushing out to <%s:%d>\n", - // to.get_host_addr (), - // to.get_port_number ())); - - // @@ TODO: We could keep the header pre-initialized, and only - // update the portions that do change... - char header[16]; - header[0] = ACE_RMCast::RMCAST_MT_LEAVE; - - // ACE_SOCK_MCast_Dgram disallows sending, but it actually works. - ACE_SOCK_Dgram &dgram = this->dgram_; - - if (dgram.send (header, 1, to) == -1) - return -1; - - return 0; -} - - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - -template class ACE_Hash_Map_Manager<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Null_Mutex>; -template class ACE_Hash_Map_Manager_Ex<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Hash<ACE_INET_Addr>,ACE_Equal_To<ACE_INET_Addr>,ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator_Ex<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Hash<ACE_INET_Addr>,ACE_Equal_To<ACE_INET_Addr>,ACE_Null_Mutex>; -template class ACE_Hash_Map_Reverse_Iterator_Ex<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Hash<ACE_INET_Addr>,ACE_Equal_To<ACE_INET_Addr>,ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator_Base_Ex<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Hash<ACE_INET_Addr>,ACE_Equal_To<ACE_INET_Addr>,ACE_Null_Mutex>; -template class ACE_Hash_Map_Entry<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*>; -template class ACE_Equal_To<ACE_INET_Addr>; -template class ACE_Hash<ACE_INET_Addr>; - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/protocols/ace/RMCast/RMCast_IO_UDP.h b/protocols/ace/RMCast/RMCast_IO_UDP.h deleted file mode 100644 index 9cad38a0506..00000000000 --- a/protocols/ace/RMCast/RMCast_IO_UDP.h +++ /dev/null @@ -1,138 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = DESCRIPTION -// Encapsulate the I/O layer for a UDP based receiver -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_IO_UDP_H -#define ACE_RMCAST_IO_UDP_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "ace/SOCK_Dgram_Mcast.h" -#include "ace/Hash_Map_Manager.h" -#include "ace/INET_Addr.h" -#include "ace/Null_Mutex.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_UDP_Proxy; -class ACE_RMCast_Module_Factory; -class ACE_Time_Value; - -class ACE_RMCast_Export ACE_RMCast_IO_UDP : public ACE_RMCast_Module -{ -public: - //! Constructor - /*! - * The <factory> argument is used to create the modules for each - * proxy that process incoming messages. The class does *not* assume - * ownership of <factory>, the caller owns it. But it does assume - * ownership of the modules returned by the factory, and it may ask - * the factory to release them eventually. - */ - ACE_RMCast_IO_UDP (ACE_RMCast_Module_Factory *factory); - - //! Destructor - ~ACE_RMCast_IO_UDP (void); - - /// Open the internal socket, but only to send multicast data. - /** - * It is not clear to me if this is a valid configuration. Maybe it - * would be a problem to expose two separate, incompatible - * interfaces (check the subscribe() method). However, the - * alternative would be to implement almost identical class for - * outgoing and incoming UDP I/O - */ - int init (const ACE_INET_Addr &mcast_group, - const ACE_Addr &local, - int protocol_family = PF_INET, - int protocol = 0, - int reuse_addr = 0); - - //! Join a new multicast group - /*! - * Start receiving data for the <mcast_addr> multicast group. - * Please read the documentation of ACE_SOCK_Dgram_Mcast for more - * details. - */ - int subscribe (const ACE_INET_Addr &mcast_addr, - int reuse_addr = 1, - const ACE_TCHAR *net_if = 0, - int protocol_family = PF_INET, - int protocol = 0); - - // The class can be used with a Reactor or using blocking I/O - // depending on what method of the following two is called. - - //! Wait for events for the period <tv>. If <tv> is zero it blocks - //! forever. - int handle_events (ACE_Time_Value *tv = 0); - - //! There is data to read, read it and process it. - int handle_input (ACE_HANDLE h); - - //! Obtain the handle for the underlying socket - ACE_HANDLE get_handle (void) const; - - //@{ - //! Send the message to the ACE_INET_Addr argument. - /*! - * These methods are used in the implementation of the - * ACE_RMCast_UDP_Proxy objects and the implementation of the - * inherited ACE_RMCast_Module methods in this class. - */ - int send_data (ACE_RMCast::Data &, const ACE_INET_Addr &); - int send_poll (ACE_RMCast::Poll &, const ACE_INET_Addr &); - int send_ack_join (ACE_RMCast::Ack_Join &, const ACE_INET_Addr &); - int send_ack_leave (ACE_RMCast::Ack_Leave &, const ACE_INET_Addr &); - int send_ack (ACE_RMCast::Ack &, const ACE_INET_Addr &); - int send_join (ACE_RMCast::Join &, const ACE_INET_Addr &); - int send_leave (ACE_RMCast::Leave &, const ACE_INET_Addr &); - //@} - - // Please read the documentation in ACE_RMCast_Module for more details - virtual int data (ACE_RMCast::Data &); - virtual int poll (ACE_RMCast::Poll &); - virtual int ack_join (ACE_RMCast::Ack_Join &); - virtual int ack_leave (ACE_RMCast::Ack_Leave &); - virtual int ack (ACE_RMCast::Ack &); - virtual int join (ACE_RMCast::Join &); - virtual int leave (ACE_RMCast::Leave &); - -private: - - // This is necessary to satisfy the stupid xgcc for Lynx on Solaris - // The compiler barfs up lisp code errors - ACE_RMCast_UDP_Proxy *allocate_and_bind_proxy (ACE_RMCast_Module *module, - const ACE_INET_Addr &); - - //! The factory used to create the modules attached to each proxy - ACE_RMCast_Module_Factory *factory_; - - //! The multicast group we subscribe and send to - ACE_INET_Addr mcast_group_; - - //! The socket used to receive and send data - ACE_SOCK_Dgram_Mcast dgram_; - - //! Use a Hash_Map to maintain the collection of proxies - typedef ACE_Hash_Map_Manager<ACE_INET_Addr,ACE_RMCast_UDP_Proxy*,ACE_Null_Mutex> Map; - //! The collection of proxies - Map map_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_IO_UDP.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_IO_UDP_H */ diff --git a/protocols/ace/RMCast/RMCast_IO_UDP.i b/protocols/ace/RMCast/RMCast_IO_UDP.i deleted file mode 100644 index 5468ae292af..00000000000 --- a/protocols/ace/RMCast/RMCast_IO_UDP.i +++ /dev/null @@ -1,37 +0,0 @@ -// $Id$ - -#include "RMCast_UDP_Proxy.h" -#include "RMCast_Module_Factory.h" -#include "ace/OS_Memory.h" - -ACE_INLINE -ACE_RMCast_IO_UDP:: - ACE_RMCast_IO_UDP (ACE_RMCast_Module_Factory *factory) - : factory_ (factory), - dgram_ (ACE_SOCK_Dgram_Mcast::OPT_BINDADDR_NO) -{ -} - -// Workaround failure in gcc for lynx hosted on solaris -// see ACE_RMCast_IO_UDP::handle_input() for more details -ACE_INLINE ACE_RMCast_UDP_Proxy * -ACE_RMCast_IO_UDP::allocate_and_bind_proxy (ACE_RMCast_Module *module, - const ACE_INET_Addr& from_address) -{ - ACE_RMCast_UDP_Proxy *proxy; - ACE_NEW_RETURN (proxy, - ACE_RMCast_UDP_Proxy(this, - from_address), - 0); - proxy->next (module); - - if (this->map_.bind (from_address, proxy) != 0) - { - // @@ LOG?? - return 0; - } - - return proxy; -} - - diff --git a/protocols/ace/RMCast/RMCast_Membership.cpp b/protocols/ace/RMCast/RMCast_Membership.cpp deleted file mode 100644 index 7511c72f7fe..00000000000 --- a/protocols/ace/RMCast/RMCast_Membership.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Membership.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Membership.i" -#endif /* ! __ACE_INLINE__ */ - -#include "RMCast_Proxy.h" -#include "ace/Guard_T.h" - -ACE_RCSID(RMCast, RMCast_Membership, "$Id$") - -ACE_RMCast_Membership::~ACE_RMCast_Membership (void) -{ -} - -int -ACE_RMCast_Membership::has_members (void) -{ - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - - Proxy_Iterator end = this->proxies_.end (); - Proxy_Iterator i = this->proxies_.begin (); - return (i != end); -} - -int -ACE_RMCast_Membership::ack (ACE_RMCast::Ack &ack) -{ - //ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack (%d:%d)\n", - // ack.next_expected, ack.highest_received)); - - ACE_RMCast::Ack next_ack; - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - if (ack.next_expected < this->next_expected_) - { - // @@ This violates an invariant of the class, shouldn't - // happen... - //ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[2]\n")); - return 0; - } - else if (ack.next_expected == this->next_expected_) - { - // Nothing new, just continue.... - //ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[3]\n")); - return 0; - } - - int r = this->compute_ack_i (ack.source, next_ack); - if (r < 0) - return r; - if (r == 1) - return 0; - } - - //ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[4] (%d:%d)\n", - // next_ack.next_expected, next_ack.highest_received)); - - return this->ACE_RMCast_Module::ack (next_ack); -} - -int -ACE_RMCast_Membership::join (ACE_RMCast::Join &join) -{ - if (join.source == 0) - return 0; - - { - // ACE_DEBUG ((LM_DEBUG, - // "RMCast_Membership::join - %d\n", - // long(join.source))); - - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - if (this->proxies_.insert (join.source) == -1) - return -1; - } - (void) this->generate_ack (join.source); - - return this->ACE_RMCast_Module::join (join); -} - -int -ACE_RMCast_Membership::leave (ACE_RMCast::Leave &leave) -{ - if (leave.source == 0) - return 0; - - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - (void) this->proxies_.remove (leave.source); - } - (void) this->generate_ack (leave.source); - - return this->ACE_RMCast_Module::leave (leave); -} - -int -ACE_RMCast_Membership::generate_ack (ACE_RMCast_Proxy *proxy) -{ - ACE_RMCast::Ack next_ack; - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - int r = this->compute_ack_i (proxy, next_ack); - if (r < 0) - return r; - if (r == 1) - return 0; - } - - //ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[6] (%d:%d)\n", - // next_ack.next_expected, next_ack.highest_received)); - - return this->ACE_RMCast_Module::ack (next_ack); -} - -int -ACE_RMCast_Membership::compute_ack_i (ACE_RMCast_Proxy *source, - ACE_RMCast::Ack &next_ack) -{ - Proxy_Iterator end = this->proxies_.end (); - Proxy_Iterator i = this->proxies_.begin (); - if (i == end) - return 1; - - //ACE_DEBUG ((LM_DEBUG, - // "RMCast_Membership::generate_ack[1] - %d -> (%d:%d)\n", - // long(*i), - // (*i)->next_expected (), - // (*i)->highest_received ())); - - ACE_UINT32 next_expected = (*i)->next_expected (); - ACE_UINT32 highest_received = (*i)->highest_received (); - ++i; - - for (; i != end; ++i) - { - // ACE_DEBUG ((LM_DEBUG, - // "RMCast_Membership::generate_ack[2] - %d -> (%d:%d)\n", - // long(*i), - // (*i)->next_expected (), - // (*i)->highest_received ())); - - ACE_UINT32 s = (*i)->next_expected (); - if (s < next_expected) - next_expected = s; - ACE_UINT32 r = (*i)->highest_received (); - if (r > highest_received) - highest_received = r; - } -#if 0 - // @@TODO: this is an important feature, disabled until it is - // fully debugged - if (this->next_expected_ >= next_expected - || this->highest_received_ >= highest_received) - { - // No change.... - ACE_DEBUG ((LM_DEBUG, - "RMCast_Membership::generate_ack[3]\n")); - return 1; - } -#endif /* 0 */ - this->next_expected_ = next_expected; - this->highest_received_ = highest_received; - next_ack.source = source; - next_ack.next_expected = this->next_expected_; - next_ack.highest_received = this->highest_received_; - - //ACE_DEBUG ((LM_DEBUG, - // "RMCast_Membership::generate_ack[4] - (%d:%d)\n", - // next_ack.next_expected, - // next_ack.highest_received)); - - return 0; -} - -#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_Membership.h b/protocols/ace/RMCast/RMCast_Membership.h deleted file mode 100644 index d6bbbe503f9..00000000000 --- a/protocols/ace/RMCast/RMCast_Membership.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Membership.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_MEMBERSHIP_H -#define ACE_RMCAST_MEMBERSHIP_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "ace/Containers.h" -#include "ace/Synch_Traits.h" -#include "ace/Thread_Mutex.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_Proxy; - -/// Track peer membership -/** - * Reliable senders of events need to know exactly how many peers are - * receiving the events, and how many events has each peer received so - * far. - * This class uses the Join, Leave and Ack messages to build that - * information, it also summarizes the Ack events and propagate only - * the global info to the upper layer. - */ -class ACE_RMCast_Export ACE_RMCast_Membership : public ACE_RMCast_Module -{ -public: - /// Constructor - ACE_RMCast_Membership (void); - - /// Destructor - virtual ~ACE_RMCast_Membership (void); - - /// Return 1 if there are still members in the group - int has_members (void); - - /// Receive an process an Ack message - /** - * After receiving the Ack message we find out what is the lowest - * sequence number received in order among all the acks received by - * the proxies in the collection. We also find out what is the - * highest sequence number received by any proxy. - * We only propagate that information back to the upper layer, and - * then only if there are any news since the last Ack. - */ - virtual int ack (ACE_RMCast::Ack &); - - /// Add a new member to the collection, using the <source> field in - /// the Join message - virtual int join (ACE_RMCast::Join &); - - /// Remove a member from the collection, using the <source> field in - /// the Join message - virtual int leave (ACE_RMCast::Leave &); - -private: - /// Generate an Ack message, normally due to changes in the - /// collection, such as new proxys joining or leaving - int generate_ack (ACE_RMCast_Proxy *proxy); - - /// Compute an Ack message to propagate to the upper layers. - int compute_ack_i (ACE_RMCast_Proxy *source, - ACE_RMCast::Ack &next_ack); - -protected: - /// Use an unbounded set to maintain the collection of proxies. - typedef ACE_Unbounded_Set<ACE_RMCast_Proxy*> Proxy_Collection; - typedef ACE_Unbounded_Set_Iterator<ACE_RMCast_Proxy*> Proxy_Iterator; - - /// The collection of proxies - Proxy_Collection proxies_; - - /// The smallest value of next_expected for all the proxies - ACE_UINT32 next_expected_; - - /// The highest value of highest_received for all the proxies - ACE_UINT32 highest_received_; - - /// Synchronization - ACE_SYNCH_MUTEX mutex_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Membership.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_MEMBERSHIP_H */ diff --git a/protocols/ace/RMCast/RMCast_Membership.i b/protocols/ace/RMCast/RMCast_Membership.i deleted file mode 100644 index b513c2d5141..00000000000 --- a/protocols/ace/RMCast/RMCast_Membership.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Membership::ACE_RMCast_Membership (void) - : next_expected_ (0) - , highest_received_ (0) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Module.cpp b/protocols/ace/RMCast/RMCast_Module.cpp deleted file mode 100644 index d2b954ee03b..00000000000 --- a/protocols/ace/RMCast/RMCast_Module.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Module.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Module.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Module, "$Id$") - -ACE_RMCast_Module::~ACE_RMCast_Module (void) -{ -} - -int -ACE_RMCast_Module::next (ACE_RMCast_Module *next) -{ - if (this->next_ != 0 && next != 0) - return 1; - this->next_ = next; - return 0; -} - -ACE_RMCast_Module * -ACE_RMCast_Module::next (void) const -{ - return this->next_; -} - -int -ACE_RMCast_Module::open (void) -{ - if (this->next () != 0) - return this->next ()->open (); - return 0; -} - -int -ACE_RMCast_Module::close (void) -{ - if (this->next () != 0) - return this->next ()->close (); - return 0; -} - -int -ACE_RMCast_Module::data (ACE_RMCast::Data &data) -{ - if (this->next () != 0) - return this->next ()->data (data); - return 0; -} - -int -ACE_RMCast_Module::poll (ACE_RMCast::Poll &poll) -{ - if (this->next () != 0) - return this->next ()->poll (poll); - return 0; -} - -int -ACE_RMCast_Module::ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - if (this->next () != 0) - return this->next ()->ack_join (ack_join); - return 0; -} - -int -ACE_RMCast_Module::ack_leave (ACE_RMCast::Ack_Leave &ack_leave) -{ - if (this->next () != 0) - return this->next ()->ack_leave (ack_leave); - return 0; -} - -int -ACE_RMCast_Module::ack (ACE_RMCast::Ack &ack) -{ - if (this->next () != 0) - return this->next ()->ack (ack); - return 0; -} - -int -ACE_RMCast_Module::join (ACE_RMCast::Join &join) -{ - if (this->next () != 0) - return this->next ()->join (join); - return 0; -} - -int -ACE_RMCast_Module::leave (ACE_RMCast::Leave &leave) -{ - if (this->next () != 0) - return this->next ()->leave (leave); - return 0; -} diff --git a/protocols/ace/RMCast/RMCast_Module.h b/protocols/ace/RMCast/RMCast_Module.h deleted file mode 100644 index 8497b367776..00000000000 --- a/protocols/ace/RMCast/RMCast_Module.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Module.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_MODULE_H -#define ACE_RMCAST_MODULE_H -#include /**/ "ace/pre.h" - -#include "RMCast.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -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 -{ -public: - //! Constructor - ACE_RMCast_Module (void); - - //! Destructor - virtual ~ACE_RMCast_Module (void); - - //! Modifier for the next element in the stack - virtual int next (ACE_RMCast_Module *next); - - //! Accesor for the next element in the stack - virtual ACE_RMCast_Module* next (void) const; - - //! Initialize the module, setting up the next module - virtual int open (void); - - //! Close the module. - virtual int close (void); - - //! Push data through the stack - virtual int data (ACE_RMCast::Data &); - - //! Push a polling request through the stack - virtual int poll (ACE_RMCast::Poll &); - - //! Push a message to ack a join request through the stack - virtual int ack_join (ACE_RMCast::Ack_Join &); - - //! Push a message to ack a leave request through the stack - virtual int ack_leave (ACE_RMCast::Ack_Leave &); - - //! Push an ack mesage through the stack - virtual int ack (ACE_RMCast::Ack &); - - //! Push a join message through the stack - virtual int join (ACE_RMCast::Join &); - - //! Push a leave message through the stack - virtual int leave (ACE_RMCast::Leave &); - -private: - //! The next element in the stack - ACE_RMCast_Module *next_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Module.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_MODULE_H */ diff --git a/protocols/ace/RMCast/RMCast_Module.i b/protocols/ace/RMCast/RMCast_Module.i deleted file mode 100644 index af299d706e3..00000000000 --- a/protocols/ace/RMCast/RMCast_Module.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Module::ACE_RMCast_Module (void) - : next_ (0) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Module_Factory.cpp b/protocols/ace/RMCast/RMCast_Module_Factory.cpp deleted file mode 100644 index a693c0f0bf5..00000000000 --- a/protocols/ace/RMCast/RMCast_Module_Factory.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// $Id$ - -#include "RMCast_Module_Factory.h" - -ACE_RCSID(RMCast, RMCast_Module_Factory, "$Id$") - -ACE_RMCast_Module_Factory::~ACE_RMCast_Module_Factory (void) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Module_Factory.h b/protocols/ace/RMCast/RMCast_Module_Factory.h deleted file mode 100644 index eada18f8aca..00000000000 --- a/protocols/ace/RMCast/RMCast_Module_Factory.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Module_Factory.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_MODULE_FACTORY_H -#define ACE_RMCAST_MODULE_FACTORY_H -#include /**/ "ace/pre.h" - -#include "RMCast.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_Module; -class ACE_RMCast_IO_UDP; - -//! Create Module stacks -/*! - * Different application will probably require different - * configurations in their Module stack, some will just want best - * effort semantics. Others will use Reliable communication with a - * maximum retransmission time. Furthermore, applications may want to - * receive messages in send order, or just as soon as they are - * received. - * Obviously most applications will want to change want happens once a - * message is completely received. - * - * To achieve all this flexibility the IO layer uses this factory to - * create the full stack of Modules corresponding to a single - * consumer. - * To keep the complexity under control the intention is to create - * helper Factories, such as Reliable_Module_Factory where - * applications only need to customize a few features. - */ -class ACE_RMCast_Export ACE_RMCast_Module_Factory -{ -public: - //! Destructor - virtual ~ACE_RMCast_Module_Factory (void); - - //! Create a new proxy - virtual ACE_RMCast_Module *create (void) = 0; - - //! Destroy a proxy - /*! - * Some factories may allocate modules from a pool, or return the - * same module for all proxies. Consequently, only the factory - * knows how to destroy them. - */ - virtual void destroy (ACE_RMCast_Module *) = 0; -}; - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_MODULE_FACTORY_H */ diff --git a/protocols/ace/RMCast/RMCast_Partial_Message.cpp b/protocols/ace/RMCast/RMCast_Partial_Message.cpp deleted file mode 100644 index 5b5101a23dd..00000000000 --- a/protocols/ace/RMCast/RMCast_Partial_Message.cpp +++ /dev/null @@ -1,216 +0,0 @@ -// $Id$ - -#include "RMCast_Partial_Message.h" -#include "ace/OS_NS_string.h" - -#if !defined (__ACE_INLINE__) -#include "RMCast_Partial_Message.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Partial_Message, "$Id$") - -ACE_RMCast_Partial_Message:: -ACE_RMCast_Partial_Message (ACE_UINT32 message_size) - : max_hole_count_ (ACE_RMCAST_DEFAULT_HOLE_COUNT), - hole_count_ (1) -{ - ACE_NEW (this->hole_list_, - ACE_RMCast_Partial_Message::Hole[this->max_hole_count_]); - this->hole_list_[0].start = 0; - this->hole_list_[0].end = message_size; - - this->message_body_.size (message_size); - this->message_body_.wr_ptr (message_size); -} - -ACE_RMCast_Partial_Message:: -~ACE_RMCast_Partial_Message (void) -{ - delete[] this->hole_list_; -} - -int -ACE_RMCast_Partial_Message::fragment_received (ACE_UINT32 message_size, - ACE_UINT32 offset, - ACE_Message_Block *mb) -{ - if (this->message_body_.length () != message_size) - { - // ACE_DEBUG ((LM_DEBUG, - // "Partial_Message::fragment_received - " - // "invalid message length\n")); - return -1; - } - - // Just copy the data... - char *rd_ptr = this->message_body_.rd_ptr () + offset; - size_t total_length = 0; - { - for (const ACE_Message_Block *i = mb; i != 0; i = i->cont ()) - { - if (rd_ptr + i->length () > this->message_body_.wr_ptr ()) - { - // ACE_DEBUG ((LM_DEBUG, - // "Partial_Message::fragment_received - " - // "invalid payload length\n")); - return -1; - } - ACE_OS::memcpy (rd_ptr, i->rd_ptr (), i->length ()); - rd_ptr += i->length (); - total_length += i->length (); - } - } - - // The algorithm works like this: - // - // For each hole we determine if there is an intersection between - // the hole and the incoming fragment. If there is none we do - // nothing (actually since the holes are ordered we can stop the - // iteration if the - - ACE_UINT32 start = offset; - ACE_UINT32 end = static_cast<ACE_UINT32> (offset + total_length); - - while (start != end && this->hole_count_ != 0) - { - for (size_t i = 0; i < this->hole_count_; ++i) - { - Hole& hole = this->hole_list_[i]; - - // First check if the new data insersects the hole... - if (end <= hole.start) - return 0; - if (start >= hole.end) - { - if (i == this->hole_count_ - 1) - return 0; - else - continue; - } - - // The hole and the new fragment intersect, we have to - // update the hole list. - // - // There are only three cases for the <start> value: - // start < hole.start - // start == hole.start - // hole.start < start < hole.end - // - // But the code for both start == hole.start and start < - // hole.start is identical.... - - if (start <= hole.start) - { - if (end < hole.end) - { - // NOTE: hole.start < end, because of previous test - - // In this case we shrink the hole, but it is not - // removed! - hole.start = end; - return 0; - } - else // end >= hole.end - { - start = hole.end; - // We remove the hole, and continue the iteration... - if (this->remove_hole (i) == -1) - return -1; - break; - } - } - else // hole.start < start < hole.end - { - if (end >= hole.end) - { - // Just adjust the size of the hole... - ACE_UINT32 tmp = hole.end; - hole.end = start; - start = tmp; - break; - } - else // if (end < hole.end) - { - // Nasty, we need to insert a new hole... - if (this->insert_hole (i, end, hole.end) == -1) - return -1; - // and change the old hole... - // NOTE: we have to refetch it because the array may - // have been reallocated! - this->hole_list_[i].end = start; - return 0; - } - } - } - } - return 0; - // @@ OLD COMMENTS, the algorithm has changed since! - // There are several cases: - // - // 1) The fragment is completely contained in data already received, - // nothing changes in this case. - // - // 2) Part of the fragment is contained in data already received and - // part is new data: - // 2.1) The new data closes a hole, remove it from the list - // 2.2) The beginning of the new fragment is the new data, reduce - // the size of the hole - // 2.3) The end of the new fragment is the new data, increment - // the size of the received block - // - // 3) The fragment is completely contained in a hole - // 3.1) It closes the hole, remove it from the list - // 3.2) It starts at the beginning of a hole, grow the received - // block - // 3.3) It ends at the end of a hole, reduce the hole size - // 3.4) It is in the middle of a hole, insert a new hole - // -} - -int -ACE_RMCast_Partial_Message::insert_hole (size_t i, - ACE_UINT32 start, - ACE_UINT32 end) -{ - // ACE_DEBUG ((LM_DEBUG, - // "Partial_Message::insert_hole %d = [%d,%d]\n", - // i, start, end)); - if (this->hole_count_ + 1 > this->max_hole_count_) - { - this->max_hole_count_ *= 2; - Hole *tmp; - ACE_NEW_RETURN (tmp, Hole[this->max_hole_count_], -1); - for (size_t j = 0; j != this->hole_count_; ++j) - { - tmp[j] = this->hole_list_[j]; - } - delete[] this->hole_list_; - this->hole_list_ = tmp; - } - if (this->hole_count_ != 0) - { - for (size_t j = this->hole_count_ - 1; j >= i + 1; --j) - { - this->hole_list_[j+1] = this->hole_list_[j]; - } - } - - this->hole_list_[i + 1].start = start; - this->hole_list_[i + 1].end = end; - this->hole_count_++; - - return 0; -} - -int -ACE_RMCast_Partial_Message::remove_hole (size_t i) -{ - // ACE_DEBUG ((LM_DEBUG, - // "Partial_Message::remove_hole %d\n", - // i)); - for (size_t j = i; j != this->hole_count_ - 1; ++j) - this->hole_list_[j] = this->hole_list_[j + 1]; - - this->hole_count_--; - return 0; -} diff --git a/protocols/ace/RMCast/RMCast_Partial_Message.h b/protocols/ace/RMCast/RMCast_Partial_Message.h deleted file mode 100644 index 0c14cd7828a..00000000000 --- a/protocols/ace/RMCast/RMCast_Partial_Message.h +++ /dev/null @@ -1,102 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = DESCRIPTION -// Helper class used in the reassembly layer of the realiable -// multicast library. -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_PARTIAL_MESSAGE_H -#define ACE_RMCAST_PARTIAL_MESSAGE_H -#include /**/ "ace/pre.h" - -#include "RMCast_Export.h" -#include "ace/Task.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#ifndef ACE_RMCAST_DEFAULT_HOLE_COUNT -#define ACE_RMCAST_DEFAULT_HOLE_COUNT 16 -#endif /* ACE_RMCAST_DEFAULT_HOLE_COUNT */ - -//! Represent a partially received message in the -//! ACE_RMCast_Reassembly module -/*! - * This class provides temporary storage for the fragments as they are - * received in the ACE_RMCast_Reassembly module. It also keeps track - * of what portions of the message are still missing. - */ -class ACE_RMCast_Export ACE_RMCast_Partial_Message -{ -public: - //! Constructor, reserve enough memory for the complete message - ACE_RMCast_Partial_Message (ACE_UINT32 message_size); - - //! Destructor - ~ACE_RMCast_Partial_Message (void); - - //! Process a fragment - /*! - * A fragment starting at <offset> has been received, copy the - * fragment contents and update the list of holes. - */ - int fragment_received (ACE_UINT32 message_size, - ACE_UINT32 offset, - ACE_Message_Block *mb); - - //! Return 1 if the message is complete - int is_complete (void) const; - - //! Return the body of the message, the memory is *not* owned by the - //! caller - ACE_Message_Block *message_body (void); - -private: - //! Insert a new hole into the list - /*! - * The class keeps an array to represent the missing portions of the - * message. This method inserts a new hole, i.e. a new element in - * the array at index <i>. The <start> and <end> arguments represent - * the offsets of the missing portion of the message. - */ - int insert_hole (size_t i, - ACE_UINT32 start, - ACE_UINT32 end); - - //! Remove a hole from the list - int remove_hole (size_t i); - -private: - //! Maintain the message storage - ACE_Message_Block message_body_; - - //! Represent a missing portion of a message - struct Hole - { - //! Offset where the missing portion of the message starts - ACE_UINT32 start; - //! Offset where the missing portion of the message ends - ACE_UINT32 end; - }; - - //! Implement a growing array of Hole structures - //@{ - Hole *hole_list_; - size_t max_hole_count_; - size_t hole_count_; - //@} -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Partial_Message.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_PARTIAL_MESSAGE_H */ diff --git a/protocols/ace/RMCast/RMCast_Partial_Message.i b/protocols/ace/RMCast/RMCast_Partial_Message.i deleted file mode 100644 index 7be89aa1932..00000000000 --- a/protocols/ace/RMCast/RMCast_Partial_Message.i +++ /dev/null @@ -1,15 +0,0 @@ -// $Id$ - -ACE_INLINE int -ACE_RMCast_Partial_Message::is_complete (void) const -{ - return (this->hole_count_ == 0) - || (this->hole_count_ == 1 - && this->hole_list_[0].start == this->hole_list_[0].end); -} - -ACE_INLINE ACE_Message_Block * -ACE_RMCast_Partial_Message::message_body (void) -{ - return &this->message_body_; -} diff --git a/protocols/ace/RMCast/RMCast_Proxy.cpp b/protocols/ace/RMCast/RMCast_Proxy.cpp deleted file mode 100644 index 6aa870ea702..00000000000 --- a/protocols/ace/RMCast/RMCast_Proxy.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Proxy.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Proxy.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Proxy, "$Id$") - -ACE_RMCast_Proxy::~ACE_RMCast_Proxy (void) -{ -} - -ACE_UINT32 -ACE_RMCast_Proxy::next_expected (void) const -{ - return this->next_expected_; -} - -ACE_UINT32 -ACE_RMCast_Proxy::highest_received (void) const -{ - return this->highest_received_; -} - -int -ACE_RMCast_Proxy::ack (ACE_RMCast::Ack &ack) -{ - this->next_expected_ = ack.next_expected; - this->highest_received_ = ack.highest_received; - return this->ACE_RMCast_Module::ack (ack); -} - -int -ACE_RMCast_Proxy::reply_ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - if (this->next_expected_ < ack_join.next_sequence_number) - { - this->next_expected_ = ack_join.next_sequence_number; - this->highest_received_ = ack_join.next_sequence_number; - } - return 0; -} diff --git a/protocols/ace/RMCast/RMCast_Proxy.h b/protocols/ace/RMCast/RMCast_Proxy.h deleted file mode 100644 index 303a5e8ffe4..00000000000 --- a/protocols/ace/RMCast/RMCast_Proxy.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Proxy.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_PROXY_H -#define ACE_RMCAST_PROXY_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -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 -{ -public: - //! Constructor - ACE_RMCast_Proxy (void); - // Constructor - - //! Destructor - virtual ~ACE_RMCast_Proxy (void); - - //! Return the next sequence number expected by the peer. Only - //! applies to remote receiver proxies. - /*! - * Please read the documentation in ACE_RMCast::Ack - */ - virtual ACE_UINT32 next_expected (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; - - //@{ - //! 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 &); - virtual int reply_ack_leave (ACE_RMCast::Ack_Leave &) = 0; - virtual int reply_ack (ACE_RMCast::Ack &) = 0; - virtual int reply_join (ACE_RMCast::Join &) = 0; - virtual int reply_leave (ACE_RMCast::Leave &) = 0; - //@} - - /*! - * Proxies process the ACK sequence numbers to cache the ack - * information from the peer. - */ - virtual int ack (ACE_RMCast::Ack &); - -private: - //@{ - //! Cache the sequence numbers reported from the remote peer using - //! Ack messages - ACE_UINT32 next_expected_; - ACE_UINT32 highest_received_; - //@} -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Proxy.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_PROXY_H */ diff --git a/protocols/ace/RMCast/RMCast_Proxy.i b/protocols/ace/RMCast/RMCast_Proxy.i deleted file mode 100644 index 6fee09fe9e5..00000000000 --- a/protocols/ace/RMCast/RMCast_Proxy.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Proxy::ACE_RMCast_Proxy (void) - : next_expected_ (0) - , highest_received_ (0) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Reassembly.cpp b/protocols/ace/RMCast/RMCast_Reassembly.cpp deleted file mode 100644 index 7f48b06d5e1..00000000000 --- a/protocols/ace/RMCast/RMCast_Reassembly.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// $Id$ - -#include "RMCast_Reassembly.h" -#include "RMCast_Partial_Message.h" -#include "ace/Message_Block.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -ACE_RCSID(RMCast, RMCast_Reassembly, "$Id$") - -ACE_RMCast_Reassembly:: -ACE_RMCast_Reassembly (void) - : ACE_RMCast_Module () -{ -} - -ACE_RMCast_Reassembly::~ACE_RMCast_Reassembly (void) -{ - (void) this->close_i (); -} - -/** - * - * We cleanup the resources in the destructor - */ -int -ACE_RMCast_Reassembly::close () -{ - this->close_i (); - return this->ACE_RMCast_Module::close (); -} - -int -ACE_RMCast_Reassembly::data (ACE_RMCast::Data &data) -{ - if (this->next () == 0) - return 0; - - // ACE_DEBUG ((LM_DEBUG, - // "Reassembly::data - %d,%d,%d\n", - // data.sequence_number, - // data.total_size, - // data.fragment_offset)); - - if (data.payload->length () + data.fragment_offset > data.total_size) - { - ACE_ERROR ((LM_ERROR, - "RMCast_Reassembly::data - invalid size\n")); - return -1; // Corrupt message? - } - - ACE_RMCast_Partial_Message *message; - - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - if (this->messages_.find (data.sequence_number, message) == -1) - { - ACE_NEW_RETURN (message, - ACE_RMCast_Partial_Message (data.total_size), - -1); - - // ACE_DEBUG ((LM_DEBUG, - // "Reassembly::data - new message\n")); - if (this->messages_.bind (data.sequence_number, - message) == -1) - return -1; // Internal error? - } - - if (message->fragment_received (data.total_size, - data.fragment_offset, - data.payload) == -1) - { - // ACE_DEBUG ((LM_DEBUG, - // "Error in fragment_received\n")); - return -1; - } - - if (!message->is_complete ()) - { - // ACE_DEBUG ((LM_DEBUG, - // "Reassembly::data - message still incomplete\n")); - return 0; - } - - if (this->messages_.unbind (data.sequence_number) == -1) - { - // ACE_DEBUG ((LM_DEBUG, - // "Reassembly::data - message now complete\n")); - return -1; - } - } - - // Push the message... - ACE_RMCast::Data downstream_data; - downstream_data.source = data.source; - downstream_data.sequence_number = data.sequence_number; - downstream_data.total_size = static_cast<ACE_UINT32> (message->message_body ()->length ()); - downstream_data.fragment_offset = 0; - downstream_data.payload = message->message_body (); - - int r = this->next ()->data (downstream_data); - - delete message; - - return r; -} - -void -ACE_RMCast_Reassembly::close_i (void) -{ - for (Message_Map_Iterator i = this->messages_.begin (); - i != this->messages_.end (); - ++i) - { - ACE_RMCast_Partial_Message *message = (*i).int_id_; - if (message != 0) - delete message; - } - this->messages_.unbind_all (); -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - -template class ACE_Hash_Map_Manager<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Null_Mutex>; -template class ACE_Hash_Map_Manager_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Null_Mutex>; -template class ACE_Hash_Map_Iterator_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex >; -template class ACE_Hash_Map_Reverse_Iterator_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex >; -template class ACE_Hash_Map_Iterator_Base_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex >; -template class ACE_Hash_Map_Entry<ACE_UINT32,ACE_RMCast_Partial_Message*>; - -template class ACE_Less_Than<ACE_UINT32>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Hash_Map_Manager<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Null_Mutex> -#pragma instantiate ACE_Hash_Map_Manager_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex> -#pragma instantiate ACE_Hash_Map_Iterator<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Null_Mutex> -#pragma instantiate ACE_Hash_Map_Iterator_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex > -#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex > -#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ACE_UINT32,ACE_RMCast_Partial_Message*,ACE_Hash<ACE_UINT32>,ACE_Equal_To<ACE_UINT32>,ACE_Null_Mutex > -#pragma instantiate ACE_Hash_Map_Entry<ACE_UINT32,ACE_RMCast_Partial_Message*> - -#pragma instantiate ACE_Less_Than<ACE_UINT32> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - diff --git a/protocols/ace/RMCast/RMCast_Reassembly.h b/protocols/ace/RMCast/RMCast_Reassembly.h deleted file mode 100644 index f6fc8989719..00000000000 --- a/protocols/ace/RMCast/RMCast_Reassembly.h +++ /dev/null @@ -1,71 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = DESCRIPTION -// The reassembly task for the reliable multicast library -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_REASSEMBLY_H -#define ACE_RMCAST_REASSEMBLY_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "ace/Hash_Map_Manager.h" -#include "ace/Synch_Traits.h" -#include "ace/Thread_Mutex.h" -#include "ace/Null_Mutex.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -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); - - //! Destructor - virtual ~ACE_RMCast_Reassembly (void); - - // = The ACE_RMCast_Module methods - virtual int close (void); - virtual int data (ACE_RMCast::Data &data); - -private: - /// Cleanup resources, but do not close the other modules in the - /// stack - void close_i (void); - -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> - Message_Map; - typedef - 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_; -}; - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_REASSEMBLY_H */ diff --git a/protocols/ace/RMCast/RMCast_Receiver_Module.cpp b/protocols/ace/RMCast/RMCast_Receiver_Module.cpp deleted file mode 100644 index 05e6ceb8c7f..00000000000 --- a/protocols/ace/RMCast/RMCast_Receiver_Module.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Receiver_Module.h" -#include "RMCast_Proxy.h" -#include "ace/Log_Msg.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Receiver_Module.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Receiver_Module, "$Id$") - -ACE_RMCast_Receiver_Module::~ACE_RMCast_Receiver_Module (void) -{ -} - -int -ACE_RMCast_Receiver_Module::data (ACE_RMCast::Data &data) -{ - switch (this->state_) - { - case RS_NON_EXISTENT: - case RS_JOINING: - if (data.source != 0) - { - //ACE_DEBUG ((LM_DEBUG, - // "Receiver_Module::data - joining\n")); - - this->state_ = RS_JOINING; - ACE_RMCast::Join join; - if (data.source->reply_join (join) != 0) - this->leaving (data.source); - } - break; - - case RS_JOINED: - // ACE_DEBUG ((LM_DEBUG, - // "Receiver_Module::data - joined\n")); - if (this->ACE_RMCast_Module::data (data) != 0) - this->leaving (data.source); - break; - - default: - case RS_LEAVING: - this->leaving (data.source); - break; - } - return 0; -} - -int -ACE_RMCast_Receiver_Module::poll (ACE_RMCast::Poll &poll) -{ - switch (this->state_) - { - case RS_NON_EXISTENT: - case RS_JOINING: - if (poll.source != 0) - { - this->state_ = RS_JOINING; - ACE_RMCast::Join join; - if (poll.source->reply_join (join) != 0) - this->leaving (poll.source); - } - break; - - case RS_JOINED: - if (this->ACE_RMCast_Module::poll (poll) != 0) - this->leaving (poll.source); - - default: - case RS_LEAVING: - this->leaving (poll.source); - break; - } - return 0; -} - -int -ACE_RMCast_Receiver_Module::ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - switch (this->state_) - { - case RS_NON_EXISTENT: - if (ack_join.source != 0) - { - //ACE_DEBUG ((LM_DEBUG, - // "Receiver_Module::ack_join - joining\n")); - - this->state_ = RS_JOINING; - ACE_RMCast::Join join; - if (ack_join.source->reply_join (join) != 0) - this->leaving (ack_join.source); - } - break; - - case RS_JOINING: - case RS_JOINED: - //ACE_DEBUG ((LM_DEBUG, - // "Receiver_Module::ack_join - joined\n")); - - this->state_ = RS_JOINED; - if (this->ACE_RMCast_Module::ack_join (ack_join) != 0) - this->leaving (ack_join.source); - break; - - default: - case RS_LEAVING: - this->leaving (ack_join.source); - break; - } - return 0; -} - -int -ACE_RMCast_Receiver_Module::ack_leave (ACE_RMCast::Ack_Leave &ack_leave) -{ - //ACE_DEBUG ((LM_DEBUG, - // "Receiver_Module::ack_leave\n")); - - (void) this->ACE_RMCast_Module::ack_leave (ack_leave); - - // Returning -1 should remove the Proxy from the local set - return -1; -} - -int -ACE_RMCast_Receiver_Module::ack (ACE_RMCast::Ack &) -{ - return -1; -} - -int -ACE_RMCast_Receiver_Module::join (ACE_RMCast::Join &) -{ - return -1; -} - -int -ACE_RMCast_Receiver_Module::leave (ACE_RMCast::Leave &) -{ - return -1; -} - -void -ACE_RMCast_Receiver_Module::leaving (ACE_RMCast_Proxy *proxy) -{ - this->state_ = RS_LEAVING; - if (proxy != 0) - { - ACE_RMCast::Leave leave; - (void) proxy->reply_leave (leave); - } - (void) this->close (); -} diff --git a/protocols/ace/RMCast/RMCast_Receiver_Module.h b/protocols/ace/RMCast/RMCast_Receiver_Module.h deleted file mode 100644 index 112ad768696..00000000000 --- a/protocols/ace/RMCast/RMCast_Receiver_Module.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace/RMCast -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_RECEIVER_MODULE_H -#define ACE_RMCAST_RECEIVER_MODULE_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Keep track of the receiver module. -/** - * A receiver proxy must reject invalid messages and communicate with - * the sender to join and leave the multicast group. - * - * This module performs all the task related to - * - */ -class ACE_RMCast_Export ACE_RMCast_Receiver_Module : public ACE_RMCast_Module -{ -public: - //! Constructor - ACE_RMCast_Receiver_Module (void); - - //! Destructor - virtual ~ACE_RMCast_Receiver_Module (void); - - virtual int data (ACE_RMCast::Data &); - virtual int poll (ACE_RMCast::Poll &); - virtual int ack_join (ACE_RMCast::Ack_Join &); - virtual int ack_leave (ACE_RMCast::Ack_Leave &); - virtual int ack (ACE_RMCast::Ack &); - virtual int join (ACE_RMCast::Join &); - virtual int leave (ACE_RMCast::Leave &); - - /// 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> - <BR> - DATA JOINING JOINING JOINED LEAVING<BR> - Send/Join Send/Join Recv/Data Send/Leave<BR> - <BR> - POLL JOINING JOINING JOINED LEAVING<BR> - Send/Join Send/Join Send/Ack Send/Leave<BR> - <BR> - ACK_JOIN JOINING JOINED JOINED LEAVING<BR> - Send/Join Receive Msg Receive Msg Send/Leave<BR> - <BR> - ACK_LEAVE NON_EXISTENT NON_EXISTENT NON_EXISTENT NON_EXISTENT<BR> - Noop Destroy Destroy Destroy<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> - </CODE> - */ - enum Receiver_State - { - RS_NON_EXISTENT, - RS_JOINING, - RS_JOINED, - RS_LEAVING - }; - -private: - /// Enter the leaving state, prepare for termination - void leaving (ACE_RMCast_Proxy *proxy); - -private: - /// The current state of the receiver - int state_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Receiver_Module.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_RECEIVER_MODULE_H */ diff --git a/protocols/ace/RMCast/RMCast_Receiver_Module.i b/protocols/ace/RMCast/RMCast_Receiver_Module.i deleted file mode 100644 index 6662f7f048a..00000000000 --- a/protocols/ace/RMCast/RMCast_Receiver_Module.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Receiver_Module::ACE_RMCast_Receiver_Module (void) - : state_ (ACE_RMCast_Receiver_Module::RS_NON_EXISTENT) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Reliable_Factory.cpp b/protocols/ace/RMCast/RMCast_Reliable_Factory.cpp deleted file mode 100644 index b471af89c3d..00000000000 --- a/protocols/ace/RMCast/RMCast_Reliable_Factory.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// $Id$ - -#include "RMCast_Reliable_Factory.h" -#include "RMCast_Receiver_Module.h" -#include "RMCast_Reassembly.h" -#include "RMCast_Reordering.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Reliable_Factory.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Reliable_Factory, "$Id$") - -ACE_RMCast_Reliable_Factory::~ACE_RMCast_Reliable_Factory (void) -{ -} - -ACE_RMCast_Module* -ACE_RMCast_Reliable_Factory::create (void) -{ - ACE_RMCast_Module *receiver; - ACE_NEW_RETURN (receiver, ACE_RMCast_Receiver_Module, 0); - - ACE_RMCast_Module *reassembly; - ACE_NEW_RETURN (reassembly, ACE_RMCast_Reassembly, 0); - - ACE_RMCast_Module *reordering; - ACE_NEW_RETURN (reordering, ACE_RMCast_Reordering, 0); - - ACE_RMCast_Module *user = this->factory_->create (); - if (user == 0) - { - delete receiver; - delete reordering; - delete reassembly; - return 0; - } - receiver->next (reassembly); - reassembly->next (reordering); - reordering->next (user); - return receiver; -} - -void -ACE_RMCast_Reliable_Factory::destroy (ACE_RMCast_Module *receiver) -{ - ACE_RMCast_Module *reassembly = receiver->next (); - ACE_RMCast_Module *reordering = reassembly->next (); - ACE_RMCast_Module *user = reordering->next (); - this->factory_->destroy (user); - delete reordering; - delete reassembly; - delete receiver; -} diff --git a/protocols/ace/RMCast/RMCast_Reliable_Factory.h b/protocols/ace/RMCast/RMCast_Reliable_Factory.h deleted file mode 100644 index 8f9b9aa6aa1..00000000000 --- a/protocols/ace/RMCast/RMCast_Reliable_Factory.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Reliable_Factory.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_RELIABLE_FACTORY_H -#define ACE_RMCAST_RELIABLE_FACTORY_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module_Factory.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Implement an ACE_RMCast_Module_Factory that "creates" a single -/// object. -/** - * Many applications (and even some internal components), will use a - * single ACE_RMCast_Module to process all the events, for example, a - * receiver may decide to use the same ACE_RMCast_Module to process - * all incoming events, instead of using one per remote sender. - */ -class ACE_RMCast_Export ACE_RMCast_Reliable_Factory : public ACE_RMCast_Module_Factory -{ -public: - /// Constructor - ACE_RMCast_Reliable_Factory (ACE_RMCast_Module_Factory *factory); - - //! Destructor - virtual ~ACE_RMCast_Reliable_Factory (void); - - /** - * The create() method will return always @c reliable. - */ - virtual ACE_RMCast_Module *create (void); - virtual void destroy (ACE_RMCast_Module *); - -private: - /// Delegate on another factory to create the user module - ACE_RMCast_Module_Factory *factory_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Reliable_Factory.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_RELIABLE_FACTORY_H */ diff --git a/protocols/ace/RMCast/RMCast_Reliable_Factory.i b/protocols/ace/RMCast/RMCast_Reliable_Factory.i deleted file mode 100644 index 47ba22754ec..00000000000 --- a/protocols/ace/RMCast/RMCast_Reliable_Factory.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Reliable_Factory:: - ACE_RMCast_Reliable_Factory (ACE_RMCast_Module_Factory *factory) - : factory_ (factory) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Reordering.cpp b/protocols/ace/RMCast/RMCast_Reordering.cpp deleted file mode 100644 index 1aebf27d8ee..00000000000 --- a/protocols/ace/RMCast/RMCast_Reordering.cpp +++ /dev/null @@ -1,179 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Reordering.h" -#include "RMCast_Proxy.h" -#include "ace/Guard_T.h" -#include "ace/Message_Block.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Reordering.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Reordering, "$Id$") - -ACE_RMCast_Reordering::~ACE_RMCast_Reordering (void) -{ -} - -int -ACE_RMCast_Reordering::close (void) -{ - Messages_Iterator i = this->messages_.begin (); - Messages_Iterator end = this->messages_.end (); - - while (i != end) - { - ACE_Message_Block::release ((*i).item ().payload); - this->messages_.unbind ((*i).key ()); - i = this->messages_.begin (); - } - return this->ACE_RMCast_Module::close (); -} - -int -ACE_RMCast_Reordering::data (ACE_RMCast::Data &data) -{ - int must_ack = 0; - int result = 0; - ACE_RMCast::Ack ack; - - //ACE_DEBUG ((LM_DEBUG, "Received message (%d)\n", data.sequence_number)); - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - - if (data.sequence_number < this->next_expected_) - { - // Old message. Ack with the current status (look at the end - // of this block). - must_ack = 1; - - //ACE_DEBUG ((LM_DEBUG, ".... old message is ignored\n")); - } - - else if (data.sequence_number == this->next_expected_) - { - //ACE_DEBUG ((LM_DEBUG, ".... message is in order, received\n")); - - // Accept the message, the current thread will dispatch it, so - // it is marked as accepted (using the <next_expected> field). - // Any other thread will not push that message because now it - // is "old". - - this->next_expected_++; - - // Right message, process as many messages as possible from - // the queue, then ack the right level... - - // NOTE: we cannot release the mutex while dispatching - // events, otherwise: how do we stop other threads from - // delivering messages out of order? I.E. what if the - // next thread receives the next message? - if (this->next () != 0) - { - result = this->next ()->data (data); - } - - // After delivering one message there may be more messages - // pending - if (result == 0) - result = this->push_queued_messages (); - - //@@ This should be strategized, for example, only Ack if - // there is a message out of order or something, otherwise - // continue with happiness. That works well for "optimistic - // models". - must_ack = 1; - } - - else - { - //ACE_DEBUG ((LM_DEBUG, ".... message out of sequence, saved\n")); - - // Out of sequence. - if (this->highest_received_ < data.sequence_number) - { - this->highest_received_ = data.sequence_number; - } - ACE_RMCast::Data new_data = data; - new_data.payload = ACE_Message_Block::duplicate (data.payload); - (void) this->messages_.bind (data.sequence_number, new_data); - // re-ack, otherwise save it and ack. - } - - ack.next_expected = this->next_expected_; - ack.highest_received = this->highest_received_; - } - - if (must_ack && data.source != 0) - (void) data.source->reply_ack (ack); - - return result; -} - -int -ACE_RMCast_Reordering::ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - //ACE_DEBUG ((LM_DEBUG, "RMCast_Reordering::ack_join - <%d,%d>\n", - // this->next_expected_, - // ack_join.next_sequence_number)); - - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - if (this->next_expected_ >= ack_join.next_sequence_number) - { - // Nothing to do in this case... - return 0; - } - - Messages_Iterator i = this->messages_.begin (); - Messages_Iterator end = this->messages_.end (); - - while (i != end - && (*i).key () < ack_join.next_sequence_number) - { - ACE_Message_Block::release ((*i).item ().payload); - this->messages_.unbind ((*i).key ()); - i = this->messages_.begin (); - } - - this->next_expected_ = ack_join.next_sequence_number; - if (this->highest_received_ < ack_join.next_sequence_number) - this->highest_received_ = ack_join.next_sequence_number; - - this->push_queued_messages (); - } - - return 0; -} - -int -ACE_RMCast_Reordering::push_queued_messages (void) -{ - Messages_Iterator i = this->messages_.begin (); - Messages_Iterator end = this->messages_.end (); - - while (i != end - && (*i).key () == this->next_expected_) - { - int r = 0; - if (this->next () != 0) - { - ACE_RMCast::Data data = (*i).item (); - r = this->next ()->data (data); - } - - ACE_Message_Block::release ((*i).item ().payload); - this->messages_.unbind ((*i).key ()); - i = this->messages_.begin (); - this->next_expected_++; - if (r != 0) - return r; - } - return 0; -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/protocols/ace/RMCast/RMCast_Reordering.h b/protocols/ace/RMCast/RMCast_Reordering.h deleted file mode 100644 index 68901480ef5..00000000000 --- a/protocols/ace/RMCast/RMCast_Reordering.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace/RMCast -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_REORDERING_H -#define ACE_RMCAST_REORDERING_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "ace/RB_Tree.h" -#include "ace/Synch_Traits.h" -#include "ace/Thread_Mutex.h" -#include "ace/Null_Mutex.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_Proxy; - -/// Pass messages up in sent order -/** - * Some applications require receivers to process messages in the same - * order that messages are sent. This module buffers out of order - * messages and only delivers a message if: - * - All the previous messages have been delivered. - * - The sender sends a notification that previous messages will not - * be resent. - * - * The module also sends the Ack feedback to the sender. - * - * NOTE: This is not the same as causal or total ordering, that could - * be implemented someday, but requires a lot more than what we have - * right now. - * - */ -class ACE_RMCast_Export ACE_RMCast_Reordering : public ACE_RMCast_Module -{ -public: - /// Constructor - ACE_RMCast_Reordering (void); - - /// Destructor - virtual ~ACE_RMCast_Reordering (void); - - /// Use a Red-Black Tree to keep the queue of messages - //@{ - typedef ACE_RB_Tree<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> Messages; - typedef ACE_RB_Tree_Iterator<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> Messages_Iterator; - //@} - - /// Remove messages still pending - virtual int close (void); - - /// Process a Data message. - /** - * Process a Data message, sending the right Ack message back. - * The message is passed up only if it is in order. - */ - virtual int data (ACE_RMCast::Data &); - - /// During the join process the server informs us of the next - /// expected message - virtual int ack_join (ACE_RMCast::Ack_Join &); - -private: - /// Push any messages that are pending in the queue - int push_queued_messages (void); - -protected: - /// The reordering buffer - Messages messages_; - - /// The smallest value of next_expected for all the proxies - ACE_UINT32 next_expected_; - - /// The highest value of highest_received for all the proxies - ACE_UINT32 highest_received_; - - /// Synchronization - ACE_SYNCH_MUTEX mutex_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Reordering.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_REORDERING_H */ diff --git a/protocols/ace/RMCast/RMCast_Reordering.i b/protocols/ace/RMCast/RMCast_Reordering.i deleted file mode 100644 index ccbf852bc67..00000000000 --- a/protocols/ace/RMCast/RMCast_Reordering.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Reordering::ACE_RMCast_Reordering (void) - : next_expected_ (0) - , highest_received_ (0) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Resend_Handler.cpp b/protocols/ace/RMCast/RMCast_Resend_Handler.cpp deleted file mode 100644 index 4bb5d717742..00000000000 --- a/protocols/ace/RMCast/RMCast_Resend_Handler.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// $Id$ - -#include "RMCast_Resend_Handler.h" -#include "RMCast_Retransmission.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Resend_Handler.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Resend_Handler, "$Id$") - -ACE_RMCast_Resend_Handler::~ACE_RMCast_Resend_Handler (void) -{ -} - -int -ACE_RMCast_Resend_Handler::handle_timeout (const ACE_Time_Value &, - const void *) -{ - (void) this->retransmission_->resend_all (); - return 0; -} diff --git a/protocols/ace/RMCast/RMCast_Resend_Handler.h b/protocols/ace/RMCast/RMCast_Resend_Handler.h deleted file mode 100644 index 363b0ee5cc3..00000000000 --- a/protocols/ace/RMCast/RMCast_Resend_Handler.h +++ /dev/null @@ -1,44 +0,0 @@ -// $Id$ - -#ifndef ACE_RMCAST_RESEND_HANDLER_H -#define ACE_RMCAST_RESEND_HANDLER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Export.h" -#include "ace/Event_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_Retransmission; - -/// Implement an adapter to resend messages in the -/// ACE_RMCast_Retransmission layer, but based on Reactor based -/// timeouts. -class ACE_RMCast_Export ACE_RMCast_Resend_Handler : public ACE_Event_Handler -{ -public: - /// Constructor, save io_udp as the Adaptee in the Adapter pattern. - ACE_RMCast_Resend_Handler (ACE_RMCast_Retransmission *retransmission); - - /// Destructor - ~ACE_RMCast_Resend_Handler (void); - - //@{ - //! Documented in ACE_Event_Handler class - virtual int handle_timeout (const ACE_Time_Value ¤t_time, - const void *act = 0); - //@} - -private: - //! The adaptee - ACE_RMCast_Retransmission *retransmission_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Resend_Handler.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_RESEND_HANDLER_H */ diff --git a/protocols/ace/RMCast/RMCast_Resend_Handler.i b/protocols/ace/RMCast/RMCast_Resend_Handler.i deleted file mode 100644 index 9ad6cd8870d..00000000000 --- a/protocols/ace/RMCast/RMCast_Resend_Handler.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Resend_Handler:: -ACE_RMCast_Resend_Handler (ACE_RMCast_Retransmission *r) - : retransmission_ (r) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Resend_Worker.cpp b/protocols/ace/RMCast/RMCast_Resend_Worker.cpp deleted file mode 100644 index 77f41aee1fb..00000000000 --- a/protocols/ace/RMCast/RMCast_Resend_Worker.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Resend_Worker.h" -#include "RMCast_Module.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Resend_Worker.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Resend_Worker, "$Id$") - -int -ACE_RMCast_Resend_Worker::work (ACE_UINT32 const & key, - ACE_RMCast::Data const &item) -{ - if (key > this->max_sequence_number_) - return 0; - //ACE_DEBUG ((LM_DEBUG, - // "RMCast_Resend_Worker::work - message %d resent\n", - // key)); - - ACE_RMCast::Data data = item; - int r = this->next_->data (data); - if (r != 0) - return r; - this->n++; - - return 1; // @@ Stop after the first message... -} diff --git a/protocols/ace/RMCast/RMCast_Resend_Worker.h b/protocols/ace/RMCast/RMCast_Resend_Worker.h deleted file mode 100644 index 2b49f97876a..00000000000 --- a/protocols/ace/RMCast/RMCast_Resend_Worker.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_RESEND_WORKER_H -#define ACE_RMCAST_RESEND_WORKER_H -#include /**/ "ace/pre.h" - -#include "RMCast.h" -#include "RMCast_Copy_On_Write.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_Module; - -/// Process an Ack message in the ACE_RMCast_Retransmission module -/** - * The retransmission module uses internal iterators, thus it needs to - * create helper Worker classes to process some messages. - */ -class ACE_RMCast_Resend_Worker - : public ACE_RMCast_Worker<ACE_UINT32,ACE_RMCast::Data> -{ -public: - ACE_RMCast_Resend_Worker (ACE_RMCast_Module *next, - ACE_UINT32 max_sequence_number); - - virtual int work (ACE_UINT32 const & key, - ACE_RMCast::Data const &item); - - int n; - -private: - ACE_RMCast_Module *next_; - - ACE_UINT32 max_sequence_number_; - -private: - ACE_RMCast_Resend_Worker (const ACE_RMCast_Resend_Worker&); - ACE_RMCast_Resend_Worker& operator= (const ACE_RMCast_Resend_Worker&); -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Resend_Worker.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_RESEND_WORKER_H */ diff --git a/protocols/ace/RMCast/RMCast_Resend_Worker.i b/protocols/ace/RMCast/RMCast_Resend_Worker.i deleted file mode 100644 index d609c27f006..00000000000 --- a/protocols/ace/RMCast/RMCast_Resend_Worker.i +++ /dev/null @@ -1,12 +0,0 @@ -// $Id$ - -ACE_INLINE - -ACE_RMCast_Resend_Worker:: -ACE_RMCast_Resend_Worker (ACE_RMCast_Module *next, - ACE_UINT32 max_sequence_number) - : n (0) - , next_ (next) - , max_sequence_number_ (max_sequence_number) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Retransmission.cpp b/protocols/ace/RMCast/RMCast_Retransmission.cpp deleted file mode 100644 index c6f03626e39..00000000000 --- a/protocols/ace/RMCast/RMCast_Retransmission.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Retransmission.h" -#include "RMCast_Proxy.h" -#include "RMCast_Ack_Worker.h" -#include "RMCast_Resend_Worker.h" -#include "ace/Message_Block.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Retransmission.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Retransmission, "$Id$") - -ACE_RMCast_Retransmission::~ACE_RMCast_Retransmission (void) -{ -} - -int -ACE_RMCast_Retransmission::resend (ACE_UINT32 max_sequence_number) -{ - if (this->next () == 0) - return 0; - - ACE_RMCast_Resend_Worker worker (this->next (), max_sequence_number); - - if (this->messages_.for_each (&worker) == -1) - return -1; - - return worker.n; -} - -int -ACE_RMCast_Retransmission::resend_all (void) -{ - if (this->next () == 0) - return 0; - - ACE_RMCast_Resend_Worker worker (this->next (), ACE_UINT32_MAX); - - if (this->messages_.for_each (&worker) == -1) - return -1; - - return worker.n; -} - -int -ACE_RMCast_Retransmission::has_data (void) -{ - return !this->messages_.empty (); -} - -int -ACE_RMCast_Retransmission::close (void) -{ - // @@ - return 0; -} - -int -ACE_RMCast_Retransmission::data (ACE_RMCast::Data &data) -{ - if (this->next () == 0) - return 0; - - int r = this->next ()->data (data); - if (r == 0) - { - ACE_RMCast::Data copy = data; - copy.payload = ACE_Message_Block::duplicate (data.payload); - r = this->messages_.bind (data.sequence_number, copy); - } - return r; -} - -int -ACE_RMCast_Retransmission::join (ACE_RMCast::Join &join) -{ - if (join.source == 0) - return 0; - - ACE_RMCast::Ack_Join ack_join; - ack_join.source = 0; - ack_join.next_sequence_number = this->messages_.first_key (); - - (void) join.source->reply_ack_join (ack_join); - - // @@ We should force a full retransmission of all the messages! - - return 0; -} - -int -ACE_RMCast_Retransmission::leave (ACE_RMCast::Leave &leave) -{ - if (leave.source == 0) - return 0; - - ACE_RMCast::Ack_Leave ack_leave; - ack_leave.source = 0; - - (void) leave.source->reply_ack_leave (ack_leave); - - return 0; -} - -int -ACE_RMCast_Retransmission::ack (ACE_RMCast::Ack &ack) -{ - Messages::Write_Guard ace_mon (this->messages_); - - ACE_RMCast_Ack_Worker worker (ack, ace_mon, &this->messages_); - - return this->messages_.for_each (&worker); -} - -#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>; - -template class ACE_RMCast_Copy_On_Write<ACE_UINT32,ACE_RMCast::Data,ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator>; -template class ACE_RMCast_Copy_On_Write_Container<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator>; -template class ACE_RMCast_Copy_On_Write_Write_Guard<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator>; -template class ACE_RMCast_Copy_On_Write_Read_Guard<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator>; -template class ACE_RMCast_Copy_On_Write_Collection<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator>; -template class ACE_RMCast_Worker<ACE_UINT32,ACE_RMCast::Data>; - -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) - -#pragma instantiate ACE_RB_Tree<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> -#pragma instantiate ACE_RB_Tree_Iterator_Base<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> -#pragma instantiate ACE_RB_Tree_Iterator<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> -#pragma instantiate ACE_RB_Tree_Reverse_Iterator<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> -#pragma instantiate ACE_RB_Tree_Node<ACE_UINT32,ACE_RMCast::Data> - -#pragma instantiate ACE_RMCast_Copy_On_Write<ACE_UINT32,ACE_RMCast::Data,ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator> -#pragma instantiate ACE_RMCast_Copy_On_Write_Container<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator> -#pragma instantiate ACE_RMCast_Copy_On_Write_Write_Guard<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator> -#pragma instantiate ACE_RMCast_Copy_On_Write_Read_Guard<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator> -#pragma instantiate ACE_RMCast_Copy_On_Write_Collection<ACE_RMCast_Retransmission::Collection,ACE_RMCast_Retransmission::Collection_Iterator> -#pragma instantiate ACE_RMCast_Worker<ACE_UINT32,ACE_RMCast::Data> - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/protocols/ace/RMCast/RMCast_Retransmission.h b/protocols/ace/RMCast/RMCast_Retransmission.h deleted file mode 100644 index b51d1438c2a..00000000000 --- a/protocols/ace/RMCast/RMCast_Retransmission.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Retransmission.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_RETRANSMISSION_H -#define ACE_RMCAST_RETRANSMISSION_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "RMCast_Copy_On_Write.h" -#include "ace/RB_Tree.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Store messages for retransmission in reliable configurations -/** - * Reliable configurations of the RMCast framework need to store - * messages on the sender side to resend them if one or more clients - * do not receive them successfully. - */ -class ACE_RMCast_Export ACE_RMCast_Retransmission : public ACE_RMCast_Module -{ -public: - // = Initialization and termination methods. - /// Constructor - ACE_RMCast_Retransmission (void); - - /// Destructor - virtual ~ACE_RMCast_Retransmission (void); - - /// Use a Red-Black Tree to keep the queue of messages - typedef ACE_RB_Tree<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> Collection; - typedef ACE_RB_Tree_Iterator<ACE_UINT32,ACE_RMCast::Data,ACE_Less_Than<ACE_UINT32>,ACE_Null_Mutex> Collection_Iterator; - - /// The messages are stored in the Copy_On_Write wrapper to provide - /// an efficient, but thread safe interface. - typedef ACE_RMCast_Copy_On_Write<ACE_UINT32,ACE_RMCast::Data,Collection,Collection_Iterator> Messages; - - /// Resend messages - /** - * Resends all the messages up to \param max_sequence_number - * Returns the number of messages sent, or -1 if there where any - * errors. - */ - int resend (ACE_UINT32 max_sequence_number); - - /// Resend all messages - /** - * Resends all the messages currently in the queue. - */ - int resend_all (void); - - /// Return 0 if there is no pending data to send - int has_data (void); - - /// Cleanup all the stored messages - virtual int close (void); - - /// Pass the message downstream, but also save it in the - /// retransmission queue - /** - * Sequence number are assigned by the ACE_RMCast_Fragmentation - * class, consequently this class first passes the message - * downstream, to obtain the sequence number and then stores the - * message for later retransmission. - */ - virtual int data (ACE_RMCast::Data &data); - - /// Process an Ack message from the remote receivers. - /** - * Normally this Ack message will be a summary of all the Ack - * messages received by the ACE_RMCast_Membership class - */ - virtual int ack (ACE_RMCast::Ack &); - - /// Detect when new members join the group and Ack_Join them - /** - * When a new receiver joins the group this module sends an Ack_Join - * message with the next sequence number that the receiver should - * expect. - * The sequence number is obtained from the current list of cached - * messages. - */ - virtual int join (ACE_RMCast::Join &); - - /// A receiver is leaving - /** - * Normally the ACE_RMCast_Membership module could do this, but, - * because this module processes the Join messages, it seems more - * natural to process the Leave messages too. - */ - virtual int leave (ACE_RMCast::Leave &); - -protected: - - /// The retransmission buffer - Messages messages_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Retransmission.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_RETRANSMISSION_H */ diff --git a/protocols/ace/RMCast/RMCast_Retransmission.i b/protocols/ace/RMCast/RMCast_Retransmission.i deleted file mode 100644 index e67b41120ce..00000000000 --- a/protocols/ace/RMCast/RMCast_Retransmission.i +++ /dev/null @@ -1,6 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Retransmission::ACE_RMCast_Retransmission (void) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Sequencer.cpp b/protocols/ace/RMCast/RMCast_Sequencer.cpp deleted file mode 100644 index 7ee857ca762..00000000000 --- a/protocols/ace/RMCast/RMCast_Sequencer.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_Sequencer.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Sequencer.i" -#endif /* ! __ACE_INLINE__ */ - -#include "ace/Guard_T.h" - -ACE_RCSID(RMCast, RMCast_Sequencer, "$Id$") - -ACE_RMCast_Sequencer::~ACE_RMCast_Sequencer (void) -{ -} - -int -ACE_RMCast_Sequencer::data (ACE_RMCast::Data &data) -{ - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - data.sequence_number = this->sequence_number_generator_++; - } - return this->ACE_RMCast_Module::data (data); -} diff --git a/protocols/ace/RMCast/RMCast_Sequencer.h b/protocols/ace/RMCast/RMCast_Sequencer.h deleted file mode 100644 index 28f83a1d4b3..00000000000 --- a/protocols/ace/RMCast/RMCast_Sequencer.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace/RMCast -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_SEQUENCER_H -#define ACE_RMCAST_SEQUENCER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module.h" -#include "ace/Synch_Traits.h" -#include "ace/Thread_Mutex.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Assign sequence numbers to outgoing messages -/** - * On the sender side we must assign sequence numbers to the messages - * <B>before</B> they are put in the retransmission queue. - */ -class ACE_RMCast_Export ACE_RMCast_Sequencer : public ACE_RMCast_Module -{ -public: - /// Constructor - ACE_RMCast_Sequencer (void); - - /// Destructor - virtual ~ACE_RMCast_Sequencer (void); - - virtual int data (ACE_RMCast::Data &); - -protected: - /// Create the sequence numbers - ACE_UINT32 sequence_number_generator_; - - /// Synchronization - ACE_SYNCH_MUTEX mutex_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Sequencer.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_SEQUENCER_H */ diff --git a/protocols/ace/RMCast/RMCast_Sequencer.i b/protocols/ace/RMCast/RMCast_Sequencer.i deleted file mode 100644 index e7b7ff0f492..00000000000 --- a/protocols/ace/RMCast/RMCast_Sequencer.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Sequencer::ACE_RMCast_Sequencer (void) - : sequence_number_generator_ (0) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Singleton_Factory.cpp b/protocols/ace/RMCast/RMCast_Singleton_Factory.cpp deleted file mode 100644 index 5e5bd9f0930..00000000000 --- a/protocols/ace/RMCast/RMCast_Singleton_Factory.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// $Id$ - -#include "RMCast_Singleton_Factory.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_Singleton_Factory.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_Singleton_Factory, "$Id$") - -ACE_RMCast_Singleton_Factory::~ACE_RMCast_Singleton_Factory (void) -{ -} - -ACE_RMCast_Module* -ACE_RMCast_Singleton_Factory::create (void) -{ - return this->singleton_; -} - -void -ACE_RMCast_Singleton_Factory::destroy (ACE_RMCast_Module *) -{ -} diff --git a/protocols/ace/RMCast/RMCast_Singleton_Factory.h b/protocols/ace/RMCast/RMCast_Singleton_Factory.h deleted file mode 100644 index 6ab5819bf30..00000000000 --- a/protocols/ace/RMCast/RMCast_Singleton_Factory.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_Singleton_Factory.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_SINGLETON_FACTORY_H -#define ACE_RMCAST_SINGLETON_FACTORY_H -#include /**/ "ace/pre.h" - -#include "RMCast_Module_Factory.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/// Implement an ACE_RMCast_Module_Factory that "creates" a single -/// object. -/** - * Many applications (and even some internal components), will use a - * single ACE_RMCast_Module to process all the events, for example, a - * receiver may decide to use the same ACE_RMCast_Module to process - * all incoming events, instead of using one per remote sender. - */ -class ACE_RMCast_Export ACE_RMCast_Singleton_Factory : public ACE_RMCast_Module_Factory -{ -public: - /// Constructor - /** - * @param singleton This object is returned by any call to - * create(). - */ - ACE_RMCast_Singleton_Factory (ACE_RMCast_Module *singleton); - - //! Destructor - virtual ~ACE_RMCast_Singleton_Factory (void); - - virtual ACE_RMCast_Module *create (void); - virtual void destroy (ACE_RMCast_Module *); - -private: - /// The singleton object - ACE_RMCast_Module *singleton_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_Singleton_Factory.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_SINGLETON_FACTORY_H */ diff --git a/protocols/ace/RMCast/RMCast_Singleton_Factory.i b/protocols/ace/RMCast/RMCast_Singleton_Factory.i deleted file mode 100644 index a45837dfa93..00000000000 --- a/protocols/ace/RMCast/RMCast_Singleton_Factory.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_Singleton_Factory:: - ACE_RMCast_Singleton_Factory (ACE_RMCast_Module *singleton) - : singleton_ (singleton) -{ -} diff --git a/protocols/ace/RMCast/RMCast_UDP_Event_Handler.cpp b/protocols/ace/RMCast/RMCast_UDP_Event_Handler.cpp deleted file mode 100644 index 6f7ae18f19e..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Event_Handler.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// -// $Id$ -// - -#include "RMCast_UDP_Event_Handler.h" -#include "RMCast_IO_UDP.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_UDP_Event_Handler.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_UDP_Event_Handler, "$Id$") - -ACE_RMCast_UDP_Event_Handler::~ACE_RMCast_UDP_Event_Handler (void) -{ -} - -ACE_HANDLE -ACE_RMCast_UDP_Event_Handler::get_handle (void) const -{ - return this->io_udp_->get_handle (); -} - -int -ACE_RMCast_UDP_Event_Handler::handle_input (ACE_HANDLE h) -{ - return this->io_udp_->handle_input (h); -} - -int -ACE_RMCast_UDP_Event_Handler::handle_timeout (const ACE_Time_Value &, - const void *) -{ - // @@ return this->io_udp_->handle_timeout (); - return 0; -} diff --git a/protocols/ace/RMCast/RMCast_UDP_Event_Handler.h b/protocols/ace/RMCast/RMCast_UDP_Event_Handler.h deleted file mode 100644 index e8873ed67fd..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Event_Handler.h +++ /dev/null @@ -1,59 +0,0 @@ -// $Id$ - -#ifndef ACE_RMCAST_UDP_EVENT_HANDLER_H -#define ACE_RMCAST_UDP_EVENT_HANDLER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Export.h" -#include "ace/Event_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_RMCast_IO_UDP; -class ACE_INET_Addr; - -//! Implement an Adapter for the ACE_RMCast_IO_UDP class -/*! - * Applications may wish to use the ACE_Reactor to demultiplex I/O - * events for an ACE_RMCast_IO_UDP object. However other application - * may choose to make ACE_RMCast_IO_UDP active, or they may dedicate - * their own threads for its events. - * To avoid couplin ACE_RMCast_IO_UDP with the Reactor we don't make - * it derived from ACE_Event_Handler or any other class in the Reactor - * framework, instead, this simple Adapter can forward the Reactor - * messages to an ACE_RMCast_IO_UDP object. - */ -class ACE_RMCast_Export ACE_RMCast_UDP_Event_Handler : public ACE_Event_Handler -{ -public: - //! Constructor, save io_udp as the Adaptee in the Adapter pattern. - ACE_RMCast_UDP_Event_Handler (ACE_RMCast_IO_UDP *io_udp); - - //! Destructor - /*! - * Notice that this class does not own the ACE_RMCast_IO_UDP - * adaptee, so it does not destroy it. - */ - ~ACE_RMCast_UDP_Event_Handler (void); - - //@{ - //! Documented in ACE_Event_Handler class - virtual ACE_HANDLE get_handle (void) const; - virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); - virtual int handle_timeout (const ACE_Time_Value ¤t_time, - const void *act = 0); - //@} - -private: - //! The adaptee - ACE_RMCast_IO_UDP *io_udp_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_UDP_Event_Handler.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_UDP_EVENT_HANDLER_H */ diff --git a/protocols/ace/RMCast/RMCast_UDP_Event_Handler.i b/protocols/ace/RMCast/RMCast_UDP_Event_Handler.i deleted file mode 100644 index 99b4c0ac7e5..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Event_Handler.i +++ /dev/null @@ -1,8 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_RMCast_UDP_Event_Handler:: -ACE_RMCast_UDP_Event_Handler (ACE_RMCast_IO_UDP *io) - : io_udp_ (io) -{ -} diff --git a/protocols/ace/RMCast/RMCast_UDP_Proxy.cpp b/protocols/ace/RMCast/RMCast_UDP_Proxy.cpp deleted file mode 100644 index cb669397756..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Proxy.cpp +++ /dev/null @@ -1,190 +0,0 @@ -// $Id$ - -#include "RMCast_UDP_Proxy.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_UDP_Proxy.i" -#endif /* ! __ACE_INLINE__ */ - -#include "RMCast_Module.h" -#include "RMCast_IO_UDP.h" -#include "ace/Message_Block.h" -#include "ace/OS_Memory.h" -#include "ace/OS_NS_string.h" -#include "ace/os_include/arpa/os_inet.h" - -ACE_RCSID(RMCast, RMCast_UDP_Proxy, "$Id$") - -ACE_RMCast_UDP_Proxy::ACE_RMCast_UDP_Proxy (ACE_RMCast_IO_UDP *io_udp, - const ACE_INET_Addr &addr) - : io_udp_ (io_udp) - , peer_addr_ (addr) -{ -} - -ACE_RMCast_UDP_Proxy::~ACE_RMCast_UDP_Proxy (void) -{ -} - -int -ACE_RMCast_UDP_Proxy::receive_message (char *buffer, size_t size) -{ - int type = buffer[0]; - - // @@ What should we do with invalid messages like this? - // - if (type < 0 || type >= ACE_RMCast::RMCAST_MT_LAST) - return 0; - - if (type == ACE_RMCast::RMCAST_MT_POLL) - { - ACE_RMCast::Poll poll; - poll.source = this; - return this->poll (poll); - } - - else if (type == ACE_RMCast::RMCAST_MT_ACK_JOIN) - { - ACE_RMCast::Ack_Join ack_join; - ack_join.source = this; - - const size_t header_size = 1 + sizeof(ACE_UINT32); - if (size < header_size) - { - // The message is too small - return 0; - } - - ACE_UINT32 tmp; - - ACE_OS::memcpy (&tmp, buffer + 1, - sizeof(tmp)); - ack_join.next_sequence_number = ACE_NTOHL (tmp); - return this->ack_join (ack_join); - } - - else if (type == ACE_RMCast::RMCAST_MT_ACK_LEAVE) - { - ACE_RMCast::Ack_Leave ack_leave; - ack_leave.source = this; - return this->ack_leave (ack_leave); - } - - else if (type == ACE_RMCast::RMCAST_MT_DATA) - { - ACE_RMCast::Data data; - data.source = this; - const size_t header_size = 1 + 3 * sizeof(ACE_UINT32); - if (size < header_size) - { - // The message is too small - return 0; - } - - ACE_UINT32 tmp; - - ACE_OS::memcpy (&tmp, buffer + 1, - sizeof(tmp)); - data.sequence_number = ACE_NTOHL (tmp); - - ACE_OS::memcpy (&tmp, buffer + 1 + sizeof(tmp), - sizeof(tmp)); - data.total_size = ACE_NTOHL (tmp); - - ACE_OS::memcpy (&tmp, buffer + 1 + 2 * sizeof(tmp), - sizeof(tmp)); - data.fragment_offset = ACE_NTOHL (tmp); - - // Pass it up the module... - ACE_Message_Block *mb; - ACE_NEW_RETURN (mb, ACE_Message_Block, -1); - mb->size (size - header_size); - mb->copy (buffer + header_size, size - header_size); - - data.payload = mb; - return this->data (data); - } - - else if (type == ACE_RMCast::RMCAST_MT_JOIN) - { - ACE_RMCast::Join join; - join.source = this; - return this->join (join); - } - - else if (type == ACE_RMCast::RMCAST_MT_LEAVE) - { - ACE_RMCast::Leave leave; - leave.source = this; - return this->leave (leave); - } - - else if (type == ACE_RMCast::RMCAST_MT_ACK) - { - ACE_RMCast::Ack ack; - ack.source = this; - - const size_t header_size = 1 + sizeof(ACE_UINT32); - if (size < header_size) - { - // The message is too small - return 0; - } - - ACE_UINT32 tmp; - - ACE_OS::memcpy (&tmp, buffer + 1, - sizeof(tmp)); - ack.next_expected = ACE_NTOHL (tmp); - ACE_OS::memcpy (&tmp, buffer + 1 + sizeof(ACE_UINT32), - sizeof(tmp)); - ack.highest_received = ACE_NTOHL (tmp); - - return this->ack (ack); - } - - return 0; -} - -int -ACE_RMCast_UDP_Proxy::reply_data (ACE_RMCast::Data &data) -{ - return this->io_udp_->send_data (data, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_poll (ACE_RMCast::Poll &poll) -{ - return this->io_udp_->send_poll (poll, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_ack_join (ACE_RMCast::Ack_Join &ack_join) -{ - (void) this->ACE_RMCast_Proxy::reply_ack_join (ack_join); - return this->io_udp_->send_ack_join (ack_join, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_ack_leave (ACE_RMCast::Ack_Leave &ack_leave) -{ - return this->io_udp_->send_ack_leave (ack_leave, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_ack (ACE_RMCast::Ack &ack) -{ - return this->io_udp_->send_ack (ack, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_join (ACE_RMCast::Join &join) -{ - return this->io_udp_->send_join (join, this->peer_addr_); -} - -int -ACE_RMCast_UDP_Proxy::reply_leave (ACE_RMCast::Leave &leave) -{ - return this->io_udp_->send_leave (leave, this->peer_addr_); -} diff --git a/protocols/ace/RMCast/RMCast_UDP_Proxy.h b/protocols/ace/RMCast/RMCast_UDP_Proxy.h deleted file mode 100644 index 01db65f66d1..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Proxy.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RMCast_UDP_Proxy.h -// -// = AUTHOR -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#ifndef ACE_RMCAST_UDP_PROXY_H -#define ACE_RMCAST_UDP_PROXY_H -#include /**/ "ace/pre.h" - -#include "RMCast_Proxy.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/INET_Addr.h" - -class ACE_RMCast_IO_UDP; - -/// Define the proxy implementation for UDP based communication -/** - * Proxy objects are transport specific, they are responsible for - * storing the remote peer addressing information. - * This class implements the UDP version of a proxy. - */ -class ACE_RMCast_Export ACE_RMCast_UDP_Proxy : public ACE_RMCast_Proxy -{ -public: - /// Constructor - /** - * The \param io_udp argument is kept to send the replys through the - * right socket. - * The \param peer_addr is the address used byu the peer to receive - * responses. - */ - ACE_RMCast_UDP_Proxy (ACE_RMCast_IO_UDP *io_udp, - const ACE_INET_Addr &peer_addr); - - /// Destructor - virtual ~ACE_RMCast_UDP_Proxy (void); - - /// Receive a message, parse and send it upstream in the right - /// format. - int receive_message (char *buffer, size_t size); - - /// Make the peer address available - const ACE_INET_Addr &peer_addr (void) const; - - //@{ - /** - * Implement the ACE_RMCast_Proxy methods, in this case we use the - * @var io_udp_ object to send the data, using the address of our - * remote peer. - */ - virtual int reply_data (ACE_RMCast::Data &); - virtual int reply_poll (ACE_RMCast::Poll &); - virtual int reply_ack_join (ACE_RMCast::Ack_Join &); - virtual int reply_ack_leave (ACE_RMCast::Ack_Leave &); - virtual int reply_ack (ACE_RMCast::Ack &); - virtual int reply_join (ACE_RMCast::Join &); - virtual int reply_leave (ACE_RMCast::Leave &); - //@} - -private: - /// The IO facade - ACE_RMCast_IO_UDP *io_udp_; - - /// The remote peer's address - ACE_INET_Addr peer_addr_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_UDP_Proxy.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_UDP_PROXY_H */ diff --git a/protocols/ace/RMCast/RMCast_UDP_Proxy.i b/protocols/ace/RMCast/RMCast_UDP_Proxy.i deleted file mode 100644 index b7a85e78ce2..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Proxy.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE const ACE_INET_Addr& -ACE_RMCast_UDP_Proxy::peer_addr (void) const -{ - return this->peer_addr_; -} diff --git a/protocols/ace/RMCast/RMCast_UDP_Reliable_Receiver.cpp b/protocols/ace/RMCast/RMCast_UDP_Reliable_Receiver.cpp deleted file mode 100644 index 8c41e9bb663..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Reliable_Receiver.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// $Id$ - -#include "RMCast_UDP_Reliable_Receiver.h" -#include "RMCast_UDP_Event_Handler.h" -#include "ace/Reactor.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_UDP_Reliable_Receiver.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_UDP_Reliable_Receiver, "$Id$") - -ACE_RMCast_UDP_Reliable_Receiver::ACE_RMCast_UDP_Reliable_Receiver (ACE_RMCast_Module *user_module) - : user_factory_ (user_module) - , factory_ (&user_factory_) - , io_udp_ (&factory_) -{ -} - -ACE_RMCast_UDP_Reliable_Receiver::~ACE_RMCast_UDP_Reliable_Receiver (void) -{ -} - -void -ACE_RMCast_UDP_Reliable_Receiver::reactive_incoming_messages (ACE_Reactor *reactor) -{ - ACE_RMCast_UDP_Event_Handler *eh; - ACE_NEW (eh, ACE_RMCast_UDP_Event_Handler (&this->io_udp_)); - - /// @@ TODO Make sure it is removed from the Reactor at some point - (void) reactor->register_handler (eh, ACE_Event_Handler::READ_MASK); -} diff --git a/protocols/ace/RMCast/RMCast_UDP_Reliable_Receiver.h b/protocols/ace/RMCast/RMCast_UDP_Reliable_Receiver.h deleted file mode 100644 index 56797861b4b..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Reliable_Receiver.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_UDP_RELIABLE_RECEIVER_H -#define ACE_RMCAST_UDP_RELIABLE_RECEIVER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Singleton_Factory.h" -#include "RMCast_Reliable_Factory.h" -#include "RMCast_IO_UDP.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_Reactor; - -class ACE_RMCast_Export ACE_RMCast_UDP_Reliable_Receiver : public ACE_RMCast_Module -{ -public: - /// Constructor - ACE_RMCast_UDP_Reliable_Receiver (ACE_RMCast_Module *user_control); - - /// Destructor - virtual ~ACE_RMCast_UDP_Reliable_Receiver (void); - - /// Open the UDP I/O module. - int init (const ACE_INET_Addr &mcast_group); - - /// Use the reactor to handle incoming messages - void reactive_incoming_messages (ACE_Reactor *reactor); - -private: - /// All the proxys give their messages to user module - ACE_RMCast_Singleton_Factory user_factory_; - - /// This factory creates the per-proxy stack - ACE_RMCast_Reliable_Factory factory_; - - /// Handle all the UDP I/O - ACE_RMCast_IO_UDP io_udp_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_UDP_Reliable_Receiver.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_UDP_RELIABLE_RECEIVER_H */ diff --git a/protocols/ace/RMCast/RMCast_UDP_Reliable_Receiver.i b/protocols/ace/RMCast/RMCast_UDP_Reliable_Receiver.i deleted file mode 100644 index 01b2ebe2cad..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Reliable_Receiver.i +++ /dev/null @@ -1,7 +0,0 @@ -// $Id$ - -ACE_INLINE int -ACE_RMCast_UDP_Reliable_Receiver::init (const ACE_INET_Addr &mcast_group) -{ - return this->io_udp_.subscribe (mcast_group); -} diff --git a/protocols/ace/RMCast/RMCast_UDP_Reliable_Sender.cpp b/protocols/ace/RMCast/RMCast_UDP_Reliable_Sender.cpp deleted file mode 100644 index 641fb3403ac..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Reliable_Sender.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// $Id$ - -#include "RMCast_UDP_Reliable_Sender.h" -#include "RMCast_UDP_Event_Handler.h" -#include "RMCast_Resend_Handler.h" -#include "ace/Reactor.h" - -#if !defined (__ACE_INLINE__) -# include "RMCast_UDP_Reliable_Sender.i" -#endif /* ! __ACE_INLINE__ */ - -ACE_RCSID(RMCast, RMCast_UDP_Reliable_Sender, "$Id$") - -ACE_RMCast_UDP_Reliable_Sender::ACE_RMCast_UDP_Reliable_Sender (ACE_RMCast_Module *user_control) - : user_control_ (user_control) - - // We use a singleton factory, all proxys send their messages to the - // retransmission module. There should be only control messages - // coming back, so this is OK. - , factory_ (&membership_) - , io_udp_ (&factory_) -{ - // Control messages are received by the membership module and passed - // up to the both the retransmission and user modules, we use a fork - // module to do that - this->membership_.next (&this->fork_); - - this->fork_.next (&this->retransmission_); - this->fork_.secondary (user_control); - - // Messages are passed down to the sequencer module - this->next (&this->sequencer_); - - // then to the retransmission module - this->sequencer_.next (&this->retransmission_); - - // Then fork the messages, at this point control messages are sent - // back to the user, other messages continue down to the - // fragmentation layer. - this->retransmission_.next (&this->fragment_); - - // The fragmentation layer delegates all messages to the UDP I/O - // module, that sends every message back to the application. - this->fragment_.next (&this->io_udp_); -} - -ACE_RMCast_UDP_Reliable_Sender::~ACE_RMCast_UDP_Reliable_Sender (void) -{ -} - -void -ACE_RMCast_UDP_Reliable_Sender::reactive_incoming_messages (ACE_Reactor *reactor) -{ - ACE_RMCast_UDP_Event_Handler *eh; - ACE_NEW (eh, ACE_RMCast_UDP_Event_Handler (&this->io_udp_)); - - /// @@ TODO Make sure it is removed from the Reactor at some point - (void) reactor->register_handler (eh, ACE_Event_Handler::READ_MASK); -} - -void -ACE_RMCast_UDP_Reliable_Sender::reactive_resends (ACE_Reactor *reactor, - const ACE_Time_Value &period) -{ - ACE_RMCast_Resend_Handler *eh; - ACE_NEW (eh, ACE_RMCast_Resend_Handler (&this->retransmission_)); - - /// @@ TODO make sure it is removed from the Reactor at some point - (void) reactor->schedule_timer (eh, 0, period, period); -} diff --git a/protocols/ace/RMCast/RMCast_UDP_Reliable_Sender.h b/protocols/ace/RMCast/RMCast_UDP_Reliable_Sender.h deleted file mode 100644 index 9b1fa01143b..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Reliable_Sender.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -#ifndef ACE_RMCAST_UDP_RELIABLE_SENDER_H -#define ACE_RMCAST_UDP_RELIABLE_SENDER_H -#include /**/ "ace/pre.h" - -#include "RMCast_Singleton_Factory.h" -#include "RMCast_IO_UDP.h" -#include "RMCast_Sequencer.h" -#include "RMCast_Retransmission.h" -#include "RMCast_Membership.h" -#include "RMCast_Fragment.h" -#include "RMCast_Fork.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class ACE_Reactor; - -class ACE_RMCast_Export ACE_RMCast_UDP_Reliable_Sender : public ACE_RMCast_Module -{ -public: - /// Constructor - ACE_RMCast_UDP_Reliable_Sender (ACE_RMCast_Module *user_control); - - /// Destructor - virtual ~ACE_RMCast_UDP_Reliable_Sender (void); - - /// Open the UDP I/O module. - int init (const ACE_INET_Addr &mcast_group); - - /// Use the reactor to handle incoming messages - void reactive_incoming_messages (ACE_Reactor *reactor); - - /// Use the reactor to periodically resend messages - void reactive_resends (ACE_Reactor *reactor, - const ACE_Time_Value &period); - - /// Check if there is still some messages to send, return 0 if not. - int has_data (void); - - /// Check if there are any members still connected - int has_members (void); - -private: - /// The application-level control module - ACE_RMCast_Module *user_control_; - - /// Assign sequence numbers - ACE_RMCast_Sequencer sequencer_; - - /// The retransmission module - ACE_RMCast_Retransmission retransmission_; - - /// All the proxys give their messages to the retransmission module - ACE_RMCast_Singleton_Factory factory_; - - /// Handle all the UDP I/O - ACE_RMCast_IO_UDP io_udp_; - - /// The membership module - ACE_RMCast_Membership membership_; - - /// The fragmentation module - ACE_RMCast_Fragment fragment_; - - /// Redirect control messages to the user supplied module - ACE_RMCast_Fork fork_; -}; - -#if defined (__ACE_INLINE__) -#include "RMCast_UDP_Reliable_Sender.i" -#endif /* __ACE_INLINE__ */ - -#include /**/ "ace/post.h" -#endif /* ACE_RMCAST_UDP_RELIABLE_SENDER_H */ diff --git a/protocols/ace/RMCast/RMCast_UDP_Reliable_Sender.i b/protocols/ace/RMCast/RMCast_UDP_Reliable_Sender.i deleted file mode 100644 index 93868a86ede..00000000000 --- a/protocols/ace/RMCast/RMCast_UDP_Reliable_Sender.i +++ /dev/null @@ -1,19 +0,0 @@ -// $Id$ - -ACE_INLINE int -ACE_RMCast_UDP_Reliable_Sender::init (const ACE_INET_Addr &mcast_group) -{ - return this->io_udp_.init (mcast_group, ACE_Addr::sap_any); -} - -ACE_INLINE int -ACE_RMCast_UDP_Reliable_Sender::has_data (void) -{ - return this->retransmission_.has_data (); -} - -ACE_INLINE int -ACE_RMCast_UDP_Reliable_Sender::has_members (void) -{ - return this->membership_.has_members (); -} diff --git a/protocols/ace/RMCast/RMCast_Worker.cpp b/protocols/ace/RMCast/RMCast_Worker.cpp deleted file mode 100644 index 6f24892eace..00000000000 --- a/protocols/ace/RMCast/RMCast_Worker.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// $Id$ - -#ifndef ACE_RMCAST_WORKER_CPP -#define ACE_RMCAST_WORKER_CPP - -#include "RMCast_Worker.h" - -ACE_RCSID(RMCast, RMCast_Worker, "$Id$") - -template<class KEY, class ITEM> -ACE_RMCast_Worker<KEY,ITEM>::~ACE_RMCast_Worker (void) -{ -} - -#endif /* ACE_RMCAST_WORKER_CPP */ diff --git a/protocols/ace/RMCast/RMCast_Worker.h b/protocols/ace/RMCast/RMCast_Worker.h deleted file mode 100644 index 6431b192904..00000000000 --- a/protocols/ace/RMCast/RMCast_Worker.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// - -#ifndef ACE_RMCAST_WORKER_H -#define ACE_RMCAST_WORKER_H - -#include "ace/config-all.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -template<class KEY, class ITEM> -class ACE_RMCast_Worker -{ -public: - virtual ~ACE_RMCast_Worker (void); - - virtual int work (KEY const & key, - ITEM const & item) = 0; -}; - -#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "RMCast_Worker.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - -#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) -#pragma implementation ("RMCast_Worker.cpp") -#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ - -#endif /* ACE_RMCAST_WORKER_H */ diff --git a/protocols/ace/RMCast/Retransmit.cpp b/protocols/ace/RMCast/Retransmit.cpp new file mode 100644 index 00000000000..e04cec2f689 --- /dev/null +++ b/protocols/ace/RMCast/Retransmit.cpp @@ -0,0 +1,132 @@ +// file : ace/RMCast/Retransmit.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/OS.h> + +#include <ace/RMCast/Retransmit.h> + +namespace ACE_RMCast +{ + ACE_Time_Value const tick (0, 50000); + + Retransmit:: + Retransmit () + { + } + + void Retransmit:: + out_start (Out_Element* out) + { + Element::out_start (out); + + tracker_mgr_.spawn (track_thunk, this); + } + + void Retransmit:: + out_stop () + { + tracker_mgr_.cancel_all (1); + tracker_mgr_.wait (); + + Element::out_stop (); + } + + void Retransmit:: + send (Message_ptr m) + { + if (Data const* data = static_cast<Data const*> (m->find (Data::id))) + { + u64 sn (static_cast<SN const*> (m->find (SN::id))->num ()); + + Lock l (mutex_); + + queue_.bind (sn, Descr (new Data (*data))); + } + + out_->send (m); + } + + void Retransmit:: + recv (Message_ptr m) + { + if (NAK const* nak = static_cast<NAK const*> (m->find (NAK::id))) + { + Address to (static_cast<To const*> (m->find (To::id))->address ()); + + if (nak->address () == to) + { + Lock l (mutex_); + + for (NAK::iterator j (const_cast<NAK*> (nak)->begin ()); + !j.done (); + j.advance ()) + { + u64* psn; + j.next (psn); + + + Queue::ENTRY* pair; + + if (queue_.find (*psn, pair) == 0) + { + //cerr << 5 << "PRTM " << to << " " << pair->ext_id_ << endl; + + Message_ptr m (new Message); + + m->add (Profile_ptr (new SN (pair->ext_id_))); + m->add (pair->int_id_.data ()); + + pair->int_id_.reset (); + + out_->send (m); + } + else + { + //@@ TODO: message aging + // + //cerr << 4 << "message " << *psn << " not available" << endl; + } + } + } + } + else + { + in_->recv (m); + } + } + + ACE_THR_FUNC_RETURN Retransmit:: + track_thunk (void* obj) + { + reinterpret_cast<Retransmit*> (obj)->track (); + return 0; + } + + void Retransmit:: + track () + { + while (true) + { + { + Lock l (mutex_); + + for (Queue::iterator i (queue_); !i.done ();) + { + if ((*i).int_id_.inc () >= 60) + { + u64 sn ((*i).ext_id_); + i.advance (); + queue_.unbind (sn); + } + else + { + i.advance (); + } + } + } + + ACE_OS::sleep (tick); + } + } +} diff --git a/protocols/ace/RMCast/Retransmit.h b/protocols/ace/RMCast/Retransmit.h new file mode 100644 index 00000000000..6348ba66009 --- /dev/null +++ b/protocols/ace/RMCast/Retransmit.h @@ -0,0 +1,97 @@ +// file : ace/RMCast/Retransmit.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_RETRANSMIT_H +#define ACE_RMCAST_RETRANSMIT_H + +#include <ace/Hash_Map_Manager.h> + +#include <ace/Thread_Manager.h> + +#include <ace/RMCast/Stack.h> +#include <ace/RMCast/Protocol.h> +#include <ace/RMCast/Bits.h> + +namespace ACE_RMCast +{ + class Retransmit : public Element + { + public: + Retransmit (); + + virtual void + out_start (Out_Element* out); + + virtual void + out_stop (); + + public: + virtual void + send (Message_ptr m); + + virtual void + recv (Message_ptr m); + + private: + struct Descr + { + // Shouldn't be available but ACE_Hash_Map needs it. + // + Descr () + : data_ (), count_ (0) + { + } + + Descr (Data_ptr d) + : data_ (d), count_ (0) + { + } + + unsigned long + inc () + { + return ++count_; + } + + void + reset () + { + count_ = 0; + } + + // It would be logical to return data_ptr but ACE ref_auto_ptr + // hasn't learned how to convert between pointers yet. + // + Profile_ptr + data () const + { + return Profile_ptr (new Data (*data_)); + } + + private: + Data_ptr data_; + unsigned long count_; + }; + + typedef + ACE_Hash_Map_Manager<u64, Descr, ACE_Null_Mutex> + Queue; + + private: + void + track (); + + static ACE_THR_FUNC_RETURN + track_thunk (void* obj); + + private: + Queue queue_; + Mutex mutex_; + + ACE_Thread_Manager tracker_mgr_; + }; +} + + +#endif // ACE_RMCAST_RETRANSMIT_H diff --git a/protocols/ace/RMCast/Simulator.cpp b/protocols/ace/RMCast/Simulator.cpp new file mode 100644 index 00000000000..4b08f37f3da --- /dev/null +++ b/protocols/ace/RMCast/Simulator.cpp @@ -0,0 +1,40 @@ +// file : ace/RMCast/Simulator.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/RMCast/Simulator.h> + +namespace ACE_RMCast +{ + Simulator:: + Simulator () + { + srand (time (0)); + } + + void Simulator:: + send (Message_ptr m) + { + // Note: Simulator may work in unpredictable ways mainly due + // to the "reliable loopback" mechanism. + // + out_->send (m); + return; + + int r (rand ()); + + if ((r % 3) == 0) return; + + Lock l (mutex_); + + if (hold_.get ()) + { + out_->send (m); + out_->send (hold_); + } + else + { + hold_ = m; + } + } +} diff --git a/protocols/ace/RMCast/Simulator.h b/protocols/ace/RMCast/Simulator.h new file mode 100644 index 00000000000..9e19f26bb8b --- /dev/null +++ b/protocols/ace/RMCast/Simulator.h @@ -0,0 +1,30 @@ +// file : ace/RMCast/Simulator.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_SIMULATOR_H +#define ACE_RMCAST_SIMULATOR_H + +#include <ace/RMCast/Stack.h> +#include <ace/RMCast/Protocol.h> +#include <ace/RMCast/Bits.h> + +namespace ACE_RMCast +{ + class Simulator : public Element + { + public: + Simulator (); + + public: + virtual void + send (Message_ptr m); + + private: + Message_ptr hold_; + Mutex mutex_; + }; +} + + +#endif // ACE_RMCAST_SIMULATOR_H diff --git a/protocols/ace/RMCast/Socket.cpp b/protocols/ace/RMCast/Socket.cpp new file mode 100644 index 00000000000..640a1a7d694 --- /dev/null +++ b/protocols/ace/RMCast/Socket.cpp @@ -0,0 +1,112 @@ +// file : ace/RMCast/Socket.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/OS.h> + +#include <ace/RMCast/Socket.h> + +namespace ACE_RMCast +{ + Socket:: + Socket (Address const& a, bool loop) + : loop_ (loop), sn_ (1), cond_ (mutex_) + { + acknowledge_ = auto_ptr<Acknowledge> (new Acknowledge ()); + retransmit_ = auto_ptr<Retransmit> (new Retransmit ()); + simulator_ = auto_ptr<Simulator> (new Simulator ()); + link_ = auto_ptr<Link> (new Link (a)); + + // Start IN stack from top to bottom. + // + in_start (0); + acknowledge_->in_start (this); + retransmit_->in_start (acknowledge_.get ()); + simulator_->in_start (retransmit_.get ()); + link_->in_start (simulator_.get ()); + + // Start OUT stack from bottom up. + // + link_->out_start (0); + simulator_->out_start (link_.get ()); + retransmit_->out_start (simulator_.get ()); + acknowledge_->out_start (retransmit_.get ()); + out_start (acknowledge_.get ()); + } + + Socket:: + ~Socket () + { + // Stop OUT stack from top to bottom. + // + out_stop (); + acknowledge_->out_stop (); + retransmit_->out_stop (); + simulator_->out_stop (); + link_->out_stop (); + + // Stop IN stack from bottom up. + // + link_->in_stop (); + simulator_->in_stop (); + retransmit_->in_stop (); + acknowledge_->in_stop (); + in_stop (); + } + + + void Socket:: + send (void const* buf, size_t s) + { + Message_ptr m (new Message); + + m->add (Profile_ptr (new SN (sn_++))); + m->add (Profile_ptr (new Data (buf, s))); + + send (m); + } + + size_t Socket:: + recv (void* buf, size_t s) + { + Lock l (mutex_); + + while (queue_.is_empty ()) cond_.wait (); + + Message_ptr m; + if (queue_.dequeue_head (m) == -1) abort (); + + Data const* d (static_cast<Data const*>(m->find (Data::id))); + + size_t r (d->size () < s ? d->size () : s); + + ACE_OS::memcpy (buf, d->buf (), r); + + return r; + } + + void Socket:: + recv (Message_ptr m) + { + if (m->find (Data::id) != 0) + { + if (!loop_) + { + Address to (static_cast<To const*> (m->find (To::id))->address ()); + + Address from ( + static_cast<From const*> (m->find (From::id))->address ()); + + if (to == from) return; + } + + Lock l (mutex_); + + bool signal (queue_.is_empty ()); + + queue_.enqueue_tail (m); + + if (signal) cond_.signal (); + } + } +} diff --git a/protocols/ace/RMCast/Socket.h b/protocols/ace/RMCast/Socket.h new file mode 100644 index 00000000000..62f72b9597e --- /dev/null +++ b/protocols/ace/RMCast/Socket.h @@ -0,0 +1,59 @@ +// file : ace/RMCast/Socket.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_SOCKET_H +#define ACE_RMCAST_SOCKET_H + +#include <ace/Unbounded_Queue.h> + +#include <ace/RMCast/Stack.h> +#include <ace/RMCast/Protocol.h> +#include <ace/RMCast/Bits.h> + +#include <ace/RMCast/Link.h> +#include <ace/RMCast/Simulator.h> +#include <ace/RMCast/Retransmit.h> +#include <ace/RMCast/Acknowledge.h> + +namespace ACE_RMCast +{ + class Socket : protected Element + { + public: + ~Socket (); + + Socket (Address const& a, bool loop = true); + + public: + virtual void + send (void const* buf, size_t s); + + virtual size_t + recv (void* buf, size_t s); + + private: + using Element::send; + + virtual void + recv (Message_ptr m); + + private: + bool loop_; + + u64 sn_; //@@ lock? + + Mutex mutex_; + Condition cond_; + + ACE_Unbounded_Queue<Message_ptr> queue_; + + auto_ptr<Acknowledge> acknowledge_; + auto_ptr<Retransmit> retransmit_; + auto_ptr<Simulator> simulator_; + auto_ptr<Link> link_; + }; +} + + +#endif // ACE_RMCAST_SOCKET_H diff --git a/protocols/ace/RMCast/Stack.cpp b/protocols/ace/RMCast/Stack.cpp new file mode 100644 index 00000000000..729e289cf0e --- /dev/null +++ b/protocols/ace/RMCast/Stack.cpp @@ -0,0 +1,9 @@ +// file : ace/RMCast/Stack.cpp +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#include <ace/RMCast/Stack.h> + +namespace ACE_RMCast +{ +} diff --git a/protocols/ace/RMCast/Stack.h b/protocols/ace/RMCast/Stack.h new file mode 100644 index 00000000000..e371370977d --- /dev/null +++ b/protocols/ace/RMCast/Stack.h @@ -0,0 +1,87 @@ +// file : ace/RMCast/Stack.h +// author : Boris Kolpackov <boris@kolpackov.net> +// cvs-id : $Id$ + +#ifndef ACE_RMCAST_STACK_H +#define ACE_RMCAST_STACK_H + +#include <ace/RMCast/Protocol.h> + +namespace ACE_RMCast +{ + struct Out_Element + { + virtual + ~Out_Element () + { + } + + Out_Element () + : out_ (0) + { + } + + virtual void + out_start (Out_Element* out) + { + out_ = out; + } + + virtual void + send (Message_ptr m) + { + if (out_) out_->send (m); + } + + virtual void + out_stop () + { + out_ = 0; + } + + protected: + Out_Element* out_; + }; + + + struct In_Element + { + virtual + ~In_Element () + { + } + + In_Element () + : in_ (0) + { + } + + virtual void + in_start (In_Element* in) + { + in_ = in; + } + + virtual void + recv (Message_ptr m) + { + if (in_) in_->recv (m); + } + + virtual void + in_stop () + { + in_ = 0; + } + + protected: + In_Element* in_; + }; + + struct Element : In_Element, Out_Element + { + }; + +} + +#endif // ACE_RMCAST_STACK_H diff --git a/tests/RMCast/Main.cpp b/tests/RMCast/Main.cpp deleted file mode 100644 index 44b92128394..00000000000 --- a/tests/RMCast/Main.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// tests -// -// = FILENAME -// Main.cpp -// -// = DESCRIPTION -// This is a wrapper for the test programs. It obviates the test cpp's -// from having to always include OS.h. -// -// = AUTHOR -// Don Hinton <dhinton@dresystems.com> -// -// ============================================================================ - -#include "ace/OS_main.h" -#if defined (ACE_HAS_WINCE) -# include "ace/ACE.h" -#endif /* ACE_HAS_WINCE */ -int run_main (int argc, ACE_TCHAR *argv[]); - -int -ACE_TMAIN (int argc, ACE_TCHAR *argv[]) -{ - return run_main (argc, argv); -} diff --git a/tests/RMCast/Makefile.am b/tests/RMCast/Makefile.am deleted file mode 100644 index eb9d58d666e..00000000000 --- a/tests/RMCast/Makefile.am +++ /dev/null @@ -1,129 +0,0 @@ -## Process this file with automake to create Makefile.in -## -## $Id$ -## -## This file was generated by MPC. Any changes made directly to -## this file will be lost the next time it is generated. -## -## MPC Command: -## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu - -ACE_BUILDDIR = $(top_builddir) -ACE_ROOT = $(top_srcdir) - -noinst_PROGRAMS = -## Makefile.RMCast_Fragment_Test.am - -if BUILD_RMCAST -noinst_PROGRAMS += RMCast_Fragment_Test - -RMCast_Fragment_Test_CPPFLAGS = \ - -I$(ACE_ROOT) \ - -I$(ACE_BUILDDIR) - -RMCast_Fragment_Test_SOURCES = \ - $(ACE_ROOT)/tests/Main.cpp \ - RMCast_Fragment_Test.cpp - -RMCast_Fragment_Test_LDADD = \ - $(top_builddir)/ace/RMCast/libACE_RMCast.la $(top_builddir)/tests/libTest_Output.la $(top_builddir)/ace/libACE.la - -endif BUILD_RMCAST - -## Makefile.RMCast_Membership_Test.am - -if BUILD_RMCAST -noinst_PROGRAMS += RMCast_Membership_Test - -RMCast_Membership_Test_CPPFLAGS = \ - -I$(ACE_ROOT) \ - -I$(ACE_BUILDDIR) - -RMCast_Membership_Test_SOURCES = \ - $(ACE_ROOT)/tests/Main.cpp \ - RMCast_Membership_Test.cpp - -RMCast_Membership_Test_LDADD = \ - $(top_builddir)/ace/RMCast/libACE_RMCast.la $(top_builddir)/tests/libTest_Output.la $(top_builddir)/ace/libACE.la - -endif BUILD_RMCAST - -## Makefile.RMCast_Reassembly_Test.am - -if BUILD_RMCAST -noinst_PROGRAMS += RMCast_Reassembly_Test - -RMCast_Reassembly_Test_CPPFLAGS = \ - -I$(ACE_ROOT) \ - -I$(ACE_BUILDDIR) - -RMCast_Reassembly_Test_SOURCES = \ - $(ACE_ROOT)/tests/Main.cpp \ - RMCast_Reassembly_Test.cpp - -RMCast_Reassembly_Test_LDADD = \ - $(top_builddir)/ace/RMCast/libACE_RMCast.la $(top_builddir)/tests/libTest_Output.la $(top_builddir)/ace/libACE.la - -endif BUILD_RMCAST - -## Makefile.RMCast_Reordering_Test.am - -if BUILD_RMCAST -noinst_PROGRAMS += RMCast_Reordering_Test - -RMCast_Reordering_Test_CPPFLAGS = \ - -I$(ACE_ROOT) \ - -I$(ACE_BUILDDIR) - -RMCast_Reordering_Test_SOURCES = \ - $(ACE_ROOT)/tests/Main.cpp \ - RMCast_Reordering_Test.cpp - -RMCast_Reordering_Test_LDADD = \ - $(top_builddir)/ace/RMCast/libACE_RMCast.la $(top_builddir)/tests/libTest_Output.la $(top_builddir)/ace/libACE.la - -endif BUILD_RMCAST - -## Makefile.RMCast_Retransmission_Test.am - -if BUILD_RMCAST -noinst_PROGRAMS += RMCast_Retransmission_Test - -RMCast_Retransmission_Test_CPPFLAGS = \ - -I$(ACE_ROOT) \ - -I$(ACE_BUILDDIR) - -RMCast_Retransmission_Test_SOURCES = \ - $(ACE_ROOT)/tests/Main.cpp \ - RMCast_Retransmission_Test.cpp - -RMCast_Retransmission_Test_LDADD = \ - $(top_builddir)/ace/RMCast/libACE_RMCast.la $(top_builddir)/tests/libTest_Output.la $(top_builddir)/ace/libACE.la - -endif BUILD_RMCAST - -## Makefile.RMCast_UDP_Best_Effort_Test.am - -if BUILD_RMCAST -noinst_PROGRAMS += RMCast_UDP_Best_Effort_Test - -RMCast_UDP_Best_Effort_Test_CPPFLAGS = \ - -I$(ACE_ROOT) \ - -I$(ACE_BUILDDIR) - -RMCast_UDP_Best_Effort_Test_SOURCES = \ - $(ACE_ROOT)/tests/Main.cpp \ - RMCast_UDP_Best_Effort_Test.cpp - -RMCast_UDP_Best_Effort_Test_LDADD = \ - $(top_builddir)/ace/RMCast/libACE_RMCast.la $(top_builddir)/tests/libTest_Output.la $(top_builddir)/ace/libACE.la - -endif BUILD_RMCAST - -## Clean up template repositories, etc. -clean-local: - -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* - -rm -f gcctemp.c gcctemp so_locations *.ics - -rm -rf cxx_repository ptrepository ti_files - -rm -rf templateregistry ir.out - -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/tests/RMCast/RMCast_Fragment_Test.cpp b/tests/RMCast/RMCast_Fragment_Test.cpp deleted file mode 100644 index 841fb2104c3..00000000000 --- a/tests/RMCast/RMCast_Fragment_Test.cpp +++ /dev/null @@ -1,304 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = DESCRIPTION -// Unit test for the fragmentation module of the RMCast library. -// -// = AUTHORS -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#include "../test_config.h" -#include "ace/OS_NS_string.h" -#include "ace/OS_NS_time.h" -#include "ace/ACE.h" -#include "ace/Message_Block.h" -#include "ace/Task.h" -#include "ace/RMCast/RMCast_Fragment.h" - -ACE_RCSID(tests, RMCast_Fragment_Test, "$Id$") - -class ACE_RMCast_Fragment_Tester - : public ACE_Task_Base - , public ACE_RMCast_Module -{ -public: - ACE_RMCast_Fragment_Tester (void); - - virtual int data (ACE_RMCast::Data &data); - virtual int svc (void); - -private: - void initialize (ACE_Message_Block *mb); - // Initialize the message block with zero data - - int compare (ACE_Message_Block *mb); - // Compare the message block to <received_> - -private: - ACE_RMCast_Fragment fragment_; - - ACE_Message_Block received_; - ACE_UINT32 received_bytes_; - ACE_UINT32 message_sequence_number_; -}; - -int -run_main (int, ACE_TCHAR *[]) -{ - ACE_START_TEST (ACE_TEXT ("RMCast_Fragment_Test")); - - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"), - ACE::major_version(), - ACE::minor_version(), - ACE::beta_version())); - - ACE_RMCast_Fragment_Tester tester; - - if (tester.svc () == -1) - ACE_ERROR ((LM_ERROR, ACE_TEXT ("Error running the svc() routine\n"))); - - ACE_END_TEST; - return 0; -} - -// **************************************************************** - -ACE_RMCast_Fragment_Tester::ACE_RMCast_Fragment_Tester (void) -{ - this->fragment_.next (this); -} - -int -ACE_RMCast_Fragment_Tester::svc (void) -{ - { - this->received_.wr_ptr (this->received_.rd_ptr ()); - this->received_bytes_ = 0; - this->message_sequence_number_ = 0; - - ACE_UINT32 n = 128 * 1024; - ACE_Message_Block big_blob (n); - big_blob.wr_ptr (n); - - this->initialize (&big_blob); - - ACE_RMCast::Data data; - data.payload = &big_blob; - if (this->fragment_.data (data) == -1) - return -1; - - if (this->received_bytes_ != n) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Unexpected number of ") - ACE_TEXT ("received bytes (%d/%d)\n"), - this->received_bytes_, n), - -1); - - if (this->compare (&big_blob) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Mismatched big_blob data\n")), - -1); - } - - } - - - { - this->received_.wr_ptr (this->received_.rd_ptr ()); - this->received_bytes_ = 0; - this->message_sequence_number_ = 0; - - const int n = 256; - const int size = 512; - ACE_Message_Block smallb[n]; - smallb[0].size (size); - smallb[0].wr_ptr (size); - - for (int i = 1; i != n; ++i) - { - smallb[i].size (size); - smallb[i].wr_ptr (size); - smallb[i - 1].cont (&smallb[i]); - } - this->initialize (smallb); - - ACE_RMCast::Data data; - data.payload = smallb; - if (this->fragment_.data (data) == -1) - return -1; - - ACE_UINT32 total = n * size; - if (this->received_bytes_ != total) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Unexpected number of ") - ACE_TEXT ("received bytes (%d/%d)\n"), - this->received_bytes_, total), - -1); - - if (this->compare (smallb) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Mismatched smallb chain data\n")), - -1); - } - - } - - { - this->received_.wr_ptr (this->received_.rd_ptr ()); - this->received_bytes_ = 0; - this->message_sequence_number_ = 0; - - const int n = 256; - ACE_UINT32 total = 0; - - ACE_RANDR_TYPE seed = - static_cast<ACE_RANDR_TYPE> (ACE_OS::time (0)); - - int size = 64 + ACE_OS::rand_r(seed) % 128; - ACE_Message_Block smallb[n]; - smallb[0].size (size); - smallb[0].wr_ptr (size); - total += size; - - for (int i = 1; i != n; ++i) - { - size = 64 + ACE_OS::rand_r(seed) % 128; - total += size; - smallb[i].size (size); - smallb[i].wr_ptr (size); - smallb[i - 1].cont (&smallb[i]); - } - this->initialize (smallb); - - ACE_RMCast::Data data; - data.payload = smallb; - if (this->fragment_.data (data) == -1) - return -1; - - if (this->received_bytes_ != total) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Unexpected number of ") - ACE_TEXT ("received bytes (%d/%d)\n"), - this->received_bytes_, total), - -1); - - if (this->compare (smallb) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Mismatched smallb chain data\n")), - -1); - } - - } - return 0; -} - -void -ACE_RMCast_Fragment_Tester::initialize (ACE_Message_Block *mb) -{ - for (ACE_Message_Block *i = mb; i != 0; i = i->cont ()) - { - char z = 0; - for (char *j = i->rd_ptr (); j != i->wr_ptr (); ++j) - { - *j = ++z; - } - } -} - -int -ACE_RMCast_Fragment_Tester::compare (ACE_Message_Block *mb) -{ - size_t n = mb->total_size (); - ACE_Message_Block blob (n); - - for (const ACE_Message_Block *i = mb; i != 0; i = i->cont ()) - { - blob.copy (i->rd_ptr (), i->length ()); - } - - if (ACE_OS::memcmp (blob.rd_ptr (), - this->received_.rd_ptr (), - n) != 0) - { - for (size_t offset = 0; offset < n; offset += 256) - { - size_t z = 256; - if (n - offset < 256) - z = n - offset; - ACE_HEX_DUMP ((LM_DEBUG, - blob.rd_ptr () + offset, - z, - ACE_TEXT ("BIG BLOB"))); - ACE_HEX_DUMP ((LM_DEBUG, - this->received_.rd_ptr () + offset, - z, - ACE_TEXT ("RECEIVED"))); - } - return -1; - } - return 0; -} - -int -ACE_RMCast_Fragment_Tester::data (ACE_RMCast::Data &data) -{ - ACE_UINT32 sequence_number = data.sequence_number; - ACE_UINT32 message_size = data.total_size; - size_t offset = data.fragment_offset; - ACE_Message_Block *mb = data.payload; - - if (this->received_bytes_ == 0) - { - this->received_.size (message_size); - this->received_.wr_ptr (message_size); - this->message_sequence_number_ = sequence_number; - } - else - { - if (this->message_sequence_number_ != sequence_number) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Mismatched sequence number\n")), - -1); - if (this->received_.length () != message_size) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Mismatched sequence size\n")), - -1); - } - - size_t payload_size = mb->length (); - size_t fragment_size = payload_size; - if (payload_size > 0) - { - ACE_OS::memcpy (this->received_.rd_ptr () + offset, - mb->rd_ptr (), - payload_size); - this->received_bytes_ += static_cast<ACE_UINT32> (payload_size); - offset += payload_size; - } - - for (const ACE_Message_Block *i = mb->cont (); i != 0; i = i->cont ()) - { - payload_size = i->length (); - // ACE_DEBUG ((LM_DEBUG, - // "offset = %d , payload = %d\n", offset, payload_size)); - fragment_size += payload_size; - ACE_OS::memcpy (this->received_.rd_ptr () + offset, - i->rd_ptr (), payload_size); - this->received_bytes_ += static_cast<ACE_UINT32> (payload_size); - offset += payload_size; - } - - if (fragment_size > this->fragment_.max_fragment_size ()) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid fragment size\n")), - -1); - - return 0; -} diff --git a/tests/RMCast/RMCast_Membership_Test.cpp b/tests/RMCast/RMCast_Membership_Test.cpp deleted file mode 100644 index 633f5bdc1d9..00000000000 --- a/tests/RMCast/RMCast_Membership_Test.cpp +++ /dev/null @@ -1,453 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = DESCRIPTION -// Unit test for the UDP sending module of the RMCast library. -// -// = AUTHORS -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#include "../test_config.h" -#include "ace/RMCast/RMCast_Proxy.h" -#include "ace/RMCast/RMCast_Membership.h" -#include "ace/ACE.h" -#include "ace/OS_NS_time.h" -#include "ace/Task.h" - -ACE_RCSID(tests, RMCast_Membership_Test, "$Id$") - -// **************************************************************** - -//! Simple proxy for the ACE_RMCast_Membership test harness -/*! - * Implement a simple version of the ACE_RMCast_Proxy class used in - * the ACE_RMCast_Membership test harness. - */ -class Test_Proxy : public ACE_RMCast_Proxy -{ -public: - Test_Proxy (void); - - //! Get the flag to remember if this proxy has joined the group or - //! not. - int joined (void) const - { - return this->joined_; - } - //! Set the flag to remember if this proxy has joined the group or - //! not. - void joined (int j) - { - this->joined_ = j; - } - - //@{ - //! All the reply_ methods just return 0, there is no real remote - //! peer, this is just a test harness - virtual int reply_data (ACE_RMCast::Data &) - { - return 0; - } - virtual int reply_poll (ACE_RMCast::Poll &) - { - return 0; - } - virtual int reply_ack_join (ACE_RMCast::Ack_Join &) - { - return 0; - } - virtual int reply_ack_leave (ACE_RMCast::Ack_Leave &) - { - return 0; - } - virtual int reply_ack (ACE_RMCast::Ack &) - { - return 0; - } - virtual int reply_join (ACE_RMCast::Join &) - { - return 0; - } - virtual int reply_leave (ACE_RMCast::Leave &) - { - return 0; - } - //@} - -private: - //! Remember if we joined the group already. - int joined_; -}; - -// **************************************************************** - -//! The number of proxies used in the test -/*! - * Not all member will be present in the group at the same time. But - * this variable controls the maximum number - */ -const size_t nproxy = 16; - -//! A simple module to receive the messages from ACE_RMCast_Membership -/*! - * The ACE_RMCast_Membership layer pushes messages to its next module - * when all the members have acked a message, when a new member joins, - * when a member leaves, etc. - * This class will verify that the messages are exactly what we - * expect. - */ -class Tester : public ACE_RMCast_Module -{ -public: - Tester (void); - - //! Run the test for \iterations times - void run (int iterations); - - virtual int join (ACE_RMCast::Join &join); - virtual int leave (ACE_RMCast::Leave &leave); - virtual int ack (ACE_RMCast::Ack &ack); - -private: - //! Add a few proxies to the group - void join_random (void); - - //! Remove a few proxies from the group - void leave_random (void); - - //! Generate a few ack messages from all the proxies currently in - //! the group - void generate_acks (int iterations); - -private: - //! The array of proxies - Test_Proxy proxy_[nproxy]; - - //! The Membership layer - ACE_RMCast_Membership membership_; - - //! Synchronize internal data structures - ACE_SYNCH_MUTEX lock_; - - //! The test is randomized to get better coverage. This is the seed - //! variable for the test - ACE_RANDR_TYPE seed_; -}; - -// **************************************************************** - -//! An Adapter to run Tester::run the test is a separate thread -class Task : public ACE_Task_Base -{ -public: - Task (Tester *tester); - - // = Read the documentation in "ace/Task.h" - int svc (void); - -private: - //! The tester object. - Tester *tester_; -}; - -// **************************************************************** - -int -run_main (int, ACE_TCHAR *[]) -{ - ACE_START_TEST (ACE_TEXT ("RMCast_Membership_Test")); - - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"), - ACE::major_version(), - ACE::minor_version(), - ACE::beta_version())); - - { - ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Running single threaded test\n"))); - //! Run the test in single threaded mode - Tester tester; - tester.run (100); - } - { - ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Running multi threaded test\n"))); - //! Run the test in multi-threaded mode - Tester tester; - Task task (&tester); - if (task.activate (THR_NEW_LWP|THR_JOINABLE, 4) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Cannot activate the threads\n")), - 1); - ACE_Thread_Manager::instance ()->wait (); - } - - ACE_END_TEST; - return 0; -} - -// **************************************************************** - -Test_Proxy::Test_Proxy (void) - : joined_ (0) -{ -} - -// **************************************************************** - -Tester::Tester (void) - : seed_ (static_cast<ACE_RANDR_TYPE> (ACE_OS::time (0))) -{ - // Initialize the stack... - this->membership_.next (this); - for (size_t i = 0; i != nproxy; ++i) - this->proxy_[i].next (&this->membership_); -} - -void -Tester::run (int iterations) -{ - for (int i = 0; i < iterations; ++i) - { - // Connect a few.... - this->join_random (); - - // Push acks.... - this->generate_acks (iterations); - - // Disconnect a few - this->leave_random (); - - // Push acks... - this->generate_acks (iterations / 10); - } -} - -int -Tester::join (ACE_RMCast::Join &join) -{ - if (join.source == 0) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid join message in Tester\n")), - -1); - } - for (size_t i = 0; i != nproxy; ++i) - { - if (&this->proxy_[i] != join.source) - continue; - if (this->proxy_[i].joined () != 1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid state for proxy %d ") - ACE_TEXT ("in Tester::join\n")), - -1); - return 0; - } - // Not found - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Unknown proxy in Tester::join\n")), - -1); -} - -int -Tester::leave (ACE_RMCast::Leave &leave) -{ - if (leave.source == 0) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid leave message in Tester\n")), - -1); - } - for (size_t i = 0; i != nproxy; ++i) - { - if (&this->proxy_[i] != leave.source) - continue; - if (this->proxy_[i].joined () != 0) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid state for proxy %d ") - ACE_TEXT ("in Tester::leave\n")), - -1); - return 0; - } - // Not found - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Unknown proxy in Tester::leave\n")), - -1); -} - -int -Tester::ack (ACE_RMCast::Ack &ack) -{ - // After the membership layer the source makes no sense.... - if (ack.source == 0) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid ack message in Tester\n")), - -1); - } - - // ACE_DEBUG ((LM_DEBUG, - // ACE_TEXT ("Received ack in Tester %d,%d\n"), - // ack.next_expected, - // ack.highest_received)); - - // Assume the lock is held, verify that the ack message satisfy the - // invariants... - ACE_UINT32 next_expected = 0; - ACE_UINT32 highest_received = 0; - int set = 0; - for (size_t i = 0; i != nproxy; ++i) - { - if (!this->proxy_[i].joined ()) - continue; - if (!set) - { - set = 1; - next_expected = this->proxy_[i].next_expected (); - highest_received = this->proxy_[i].highest_received (); - } - else - { - if (next_expected > - this->proxy_[i].next_expected ()) - { - next_expected = - this->proxy_[i].next_expected (); - } - if (highest_received < - this->proxy_[i].highest_received ()) - { - highest_received = - this->proxy_[i].highest_received (); - } - } - } - // No local proxy just return... - if (!set) - return 0; - - // Check the invariants - if (ack.next_expected != next_expected) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid next_expected in Ack\n")), - -1); - } - if (ack.highest_received != highest_received) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid highest_received in Ack\n")), - -1); - } - return 0; -} - -void -Tester::join_random (void) -{ - for (size_t i = 0; i != nproxy; ++i) - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->lock_); - int r = ACE_OS::rand_r (this->seed_) % 100; - if (this->proxy_[i].joined () == 0 && r > 25) - { - this->proxy_[i].joined (1); - - ACE_RMCast::Join join; - join.source = &this->proxy_[i]; - // ACE_DEBUG ((LM_DEBUG, - // ACE_TEXT ("Sending join mesage for proxy %d\n"), - // i)); - this->proxy_[i].join (join); - } - } -} - -void -Tester::leave_random (void) -{ - for (size_t i = 0; i != nproxy; ++i) - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->lock_); - int r = ACE_OS::rand_r (this->seed_) % 100; - if (this->proxy_[i].joined () == 1 && r > 75) - { - this->proxy_[i].joined (0); - - ACE_RMCast::Leave leave; - leave.source = &this->proxy_[i]; - // ACE_DEBUG ((LM_DEBUG, - // ACE_TEXT ("Sending leave mesage for proxy %d\n"), - // i)); - this->proxy_[i].leave (leave); - } - } -} - -void -Tester::generate_acks (int iterations) -{ - int n = 0; - for (size_t i = 0; n < iterations && i != nproxy; ++i, ++n) - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->lock_); - int r = ACE_OS::rand_r (this->seed_) % 10; - if (this->proxy_[i].joined () == 0) - continue; - - ACE_RMCast::Ack ack; - ack.source = &this->proxy_[i]; - ack.next_expected = - this->proxy_[i].next_expected (); - ack.highest_received = - this->proxy_[i].highest_received (); - - // we randomly perform one of 3 actions, with different - // probabilities - switch (r) - { - case 0: - // Ack the same data that we already have: - break; - case 1: - case 2: - case 3: - case 4: - // Simulate out of sequence messages... - ack.highest_received++; - break; - default: - if (ack.highest_received > ack.next_expected) - ack.next_expected++; - break; - } - // ACE_DEBUG ((LM_DEBUG, - // ACE_TEXT ("Sending ack message (%d,%d) through proxy %d\n"), - // ack.next_expected, - // ack.highest_received, - // i)); - int result = this->proxy_[i].ack (ack); - if (result != 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("Returned %d in proxy %d\n"), - result, i)); - } - } -} - -// **************************************************************** - -Task::Task (Tester *tester) - : tester_ (tester) -{ -} - -int -Task::svc (void) -{ - this->tester_->run (100); - return 0; -} diff --git a/tests/RMCast/RMCast_Reassembly_Test.cpp b/tests/RMCast/RMCast_Reassembly_Test.cpp deleted file mode 100644 index 27f96b9e138..00000000000 --- a/tests/RMCast/RMCast_Reassembly_Test.cpp +++ /dev/null @@ -1,306 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = DESCRIPTION -// Unit test for the reassembly module of the RMCast library. -// -// = AUTHORS -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#include "../test_config.h" -#include "ace/OS_NS_string.h" -#include "ace/OS_NS_time.h" -#include "ace/Task.h" -#include "ace/ACE.h" -#include "ace/RMCast/RMCast_Reassembly.h" - -ACE_RCSID(tests, RMCast_Reassembly_Test, "$Id$") - -class ACE_RMCast_Reassembly_Tester - : public ACE_Task_Base - , public ACE_RMCast_Module -{ -public: - ACE_RMCast_Reassembly_Tester (void); - - virtual int data (ACE_RMCast::Data &data); - virtual int svc (void); - -private: - void initialize (ACE_Message_Block *mb); - // Initialize the message block with zero data - - int compare (ACE_Message_Block *received, - ACE_Message_Block *original); - // Compare the message block to <received_> - - int put_fragment (ACE_UINT32 sequence_number, - ACE_UINT32 offset, - ACE_UINT32 fragment_size, - ACE_Message_Block *mb); - // Put one fragment out - - ACE_UINT32 next_sequence_number (void); - // Return the next sequence number.. - -private: - ACE_RMCast_Reassembly reassembly_; - - ACE_SYNCH_MUTEX mutex_; - ACE_UINT32 message_sequence_number_; -}; - -int -run_main (int, ACE_TCHAR *[]) -{ - ACE_START_TEST (ACE_TEXT ("RMCast_Reassembly_Test")); - - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"), - ACE::major_version(), - ACE::minor_version(), - ACE::beta_version())); - - ACE_RMCast_Reassembly_Tester tester; - - if (tester.activate (THR_NEW_LWP|THR_JOINABLE, 4) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Cannot activate the threads\n")), - 1); - - ACE_Thread_Manager::instance ()->wait (); - - ACE_END_TEST; - return 0; -} - -// **************************************************************** - -ACE_RMCast_Reassembly_Tester::ACE_RMCast_Reassembly_Tester (void) - : message_sequence_number_ (0) -{ - this->reassembly_.next (this); -} - -int -ACE_RMCast_Reassembly_Tester::svc (void) -{ - for (int iteration = 0; iteration != 50; ++iteration) - { - ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) iteration %d\n"), iteration)); - ACE_UINT32 sequence_number = this->next_sequence_number (); - { - ACE_Message_Block received; - - const size_t fragment_size = 128; - ACE_UINT32 n = 32 * fragment_size; - ACE_Message_Block big_blob (n); - big_blob.wr_ptr (n); - - this->initialize (&big_blob); - - // Use an ACT to store the results in <received> - ACE_Message_Block *received_pointer = &received; - ACE_OS::memcpy (big_blob.rd_ptr (), - &received_pointer, - sizeof(received_pointer)); - - for (size_t offset = 0; offset < n; offset += fragment_size) - { - if (this->put_fragment (sequence_number, - static_cast<ACE_UINT32> (offset), - static_cast<ACE_UINT32> (fragment_size), - &big_blob) == -1) - { - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("Error in put_fragment\n"))); - return -1; - } - } - - if (this->compare (&received, &big_blob) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Mismatched big_blob data\n")), - -1); - } - } - - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%t) iteration %d, first test passed\n"), - iteration)); - sequence_number = this->next_sequence_number (); - { - ACE_Message_Block received; - - const size_t fragment_size = 128; - ACE_UINT32 n = 32 * fragment_size; - ACE_Message_Block big_blob (n); - big_blob.wr_ptr (n); - - this->initialize (&big_blob); - - // Use an ACT to store the results in <received> - ACE_Message_Block *received_pointer = &received; - ACE_OS::memcpy (big_blob.rd_ptr (), - &received_pointer, - sizeof(received_pointer)); - - ACE_RANDR_TYPE seed = - static_cast<ACE_RANDR_TYPE> (ACE_OS::time (0)); - for (int i = 0; i != 100; ++i) - { - size_t offset = ACE_OS::rand_r (seed) % n; - if (offset >= n) - { - offset = n/2; - } - if (this->put_fragment (sequence_number, - static_cast<ACE_UINT32> (offset), - static_cast<ACE_UINT32> (fragment_size), - &big_blob) == -1) - { - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("Error in put_fragment\n"))); - return -1; - } - } - - for (size_t offset = 0; offset < n; offset += fragment_size) - { - if (this->put_fragment (sequence_number, - static_cast<ACE_UINT32> (offset), - static_cast<ACE_UINT32> (fragment_size), - &big_blob) == -1) - { - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("Error in put_fragment\n"))); - return -1; - } - } - - if (this->compare (&received, &big_blob) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Mismatched random big_blob data\n")), - -1); - } - } - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%t) iteration %d, random test passed\n"), - iteration)); - } - - return 0; -} - -void -ACE_RMCast_Reassembly_Tester::initialize (ACE_Message_Block *mb) -{ - for (ACE_Message_Block *i = mb; i != 0; i = i->cont ()) - { - char z = 0; - for (char *j = i->rd_ptr (); j != i->wr_ptr (); ++j) - { - *j = ++z; - } - } -} - -int -ACE_RMCast_Reassembly_Tester::compare (ACE_Message_Block *received, - ACE_Message_Block *original) -{ - size_t n = original->total_size (); - ACE_Message_Block blob (n); - - for (const ACE_Message_Block *i = original; i != 0; i = i->cont ()) - { - blob.copy (i->rd_ptr (), i->length ()); - } - - if (received->rd_ptr () == 0) - ACE_ERROR_RETURN ((LM_DEBUG, ACE_TEXT ("INCOMPLETE MESSAGE\n")), -1); - - if (ACE_OS::memcmp (blob.rd_ptr (), - received->rd_ptr (), - n) != 0) - { - for (size_t i = 0; i < n; i += 256) - { - size_t z = 256; - if (n - i < 256) - z = n - i; - ACE_HEX_DUMP ((LM_DEBUG, - blob.rd_ptr () + i, - z, - ACE_TEXT ("BIG BLOB"))); - } - for (size_t j = 0; j < n; j += 256) - { - size_t z = 256; - if (n - j < 256) - z = n - j; - ACE_HEX_DUMP ((LM_DEBUG, - received->rd_ptr () + j, - z, - ACE_TEXT ("RECEIVED"))); - } - return -1; - } - return 0; -} - -int -ACE_RMCast_Reassembly_Tester::data (ACE_RMCast::Data &data) -{ - ACE_Message_Block *mb = data.payload; - - ACE_Message_Block *pointer; - ACE_OS::memcpy (&pointer, mb->rd_ptr (), sizeof(pointer)); - - size_t l = mb->length (); - pointer->size (l); - pointer->wr_ptr (pointer->rd_ptr () + l); - ACE_OS::memcpy (pointer->rd_ptr (), mb->rd_ptr (), l); - return 0; -} - -int -ACE_RMCast_Reassembly_Tester::put_fragment (ACE_UINT32 sequence_number, - ACE_UINT32 offset, - ACE_UINT32 fragment_size, - ACE_Message_Block *mb) -{ - size_t total_length = mb->total_length (); - - size_t size = fragment_size; - if (offset + size >= total_length) - { - size = total_length - offset; - } - ACE_Message_Block p (mb->rd_ptr () + offset, size); - - p.wr_ptr (size); - - ACE_RMCast::Data data; - data.sequence_number = sequence_number; - data.total_size = static_cast<ACE_UINT32> (total_length); - data.fragment_offset = offset; - data.payload = &p; - return this->reassembly_.data (data); -} - -ACE_UINT32 -ACE_RMCast_Reassembly_Tester::next_sequence_number () -{ - ACE_UINT32 r; - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, 0); - r = this->message_sequence_number_++; - } - return r; -} diff --git a/tests/RMCast/RMCast_Reordering_Test.cpp b/tests/RMCast/RMCast_Reordering_Test.cpp deleted file mode 100644 index 594d11c668c..00000000000 --- a/tests/RMCast/RMCast_Reordering_Test.cpp +++ /dev/null @@ -1,318 +0,0 @@ -// $Id$ - -#include "../test_config.h" -#include "ace/OS_NS_time.h" -#include "ace/ACE.h" -#include "ace/Task.h" -#include "ace/RMCast/RMCast_Proxy.h" -#include "ace/RMCast/RMCast_Reordering.h" - -ACE_RCSID(tests, RMCast_Reordering_Test, "$Id$") - -// **************************************************************** - -class Tester; - -//! Simple proxy for the ACE_RMCast_Reordering test harness -/*! - * Implement a simple version of the ACE_RMCast_Proxy class used in - * the ACE_RMCast_Reordering test harness. - */ -class Test_Proxy : public ACE_RMCast_Proxy -{ -public: - Test_Proxy (void); - - void set_tester (Tester *tester) - { - this->tester_ = tester; - } - - //! Most of the reply_ methods just return 0, there is no real remote - //! peer, this is just a test harness - //@{ - virtual int reply_data (ACE_RMCast::Data &) - { - return 0; - } - virtual int reply_poll (ACE_RMCast::Poll &) - { - return 0; - } - virtual int reply_ack_join (ACE_RMCast::Ack_Join &) - { - return 0; - } - virtual int reply_ack_leave (ACE_RMCast::Ack_Leave &) - { - return 0; - } - //! Must check that that sequence number is reasonable - virtual int reply_ack (ACE_RMCast::Ack &); - virtual int reply_join (ACE_RMCast::Join &) - { - return 0; - } - virtual int reply_leave (ACE_RMCast::Leave &) - { - return 0; - } - //@} - -private: - //! Keep a reference to the main testing class so it can be called - //! back. - Tester *tester_; -}; - -// **************************************************************** - -//! A simple module to receive the messages from ACE_RMCast_Reordering -/*! - * The ACE_RMCast_Reordering layer pushes messages to its next module - * when all the members have acked a message, when a new member joins, - * when a member leaves, etc. - * This class will verify that the messages are exactly what we - * expect. - */ -class Tester : public ACE_RMCast_Module -{ -public: - Tester (void); - - //! Run the test for \iterations times - void run (int iterations); - - //! The proxy has received an Ack message, we need to validate it - int reply_ack (ACE_RMCast::Ack &ack); - - //! Receive the data messages and validate their order - virtual int data (ACE_RMCast::Data &data); - -private: - //! Generate a new message to drive the test - void generate_messages (int count); - -private: - //! The array of proxies - Test_Proxy proxy_; - - //! The Reordering layer - ACE_RMCast_Reordering reordering_; - - //! The test is randomized to get better coverage. This is the seed - //! variable for the test - ACE_RANDR_TYPE seed_; - - //! The lowest sequence number used to generate messages - ACE_UINT32 lowest_sequence_number_; - - //! The next expected sequence number - ACE_UINT32 next_expected_; - - //! Synchronization - ACE_SYNCH_MUTEX mutex_; -}; - -// **************************************************************** - -//! An Adapter to run Tester::run the test is a separate thread -class Task : public ACE_Task_Base -{ -public: - Task (Tester *tester); - - // = Read the documentation in "ace/Task.h" - int svc (void); - -private: - //! The tester object. - Tester *tester_; -}; - -// **************************************************************** - -int -run_main (int, ACE_TCHAR *[]) -{ - ACE_START_TEST (ACE_TEXT ("RMCast_Reordering_Test")); - - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"), - ACE::major_version(), - ACE::minor_version(), - ACE::beta_version())); - - { - ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Running single threaded test\n"))); - //! Run the test in single threaded mode - Tester tester; - tester.run (100); - } - { - ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Running multi threaded test\n"))); - //! Run the test in multi-threaded mode - Tester tester; - Task task (&tester); - if (task.activate (THR_NEW_LWP|THR_JOINABLE, 4) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Cannot activate the threads\n")), - 1); - ACE_Thread_Manager::instance ()->wait (); - } - - ACE_END_TEST; - return 0; -} - -// **************************************************************** - -Tester::Tester (void) - : seed_ (static_cast<ACE_RANDR_TYPE> (ACE_OS::time (0))) - , lowest_sequence_number_ (0) - , next_expected_ (0) -{ - // Initialize the stack... - this->reordering_.next (this); - - this->proxy_.set_tester (this); -} - -void -Tester::run (int iterations) -{ - ACE_RMCast::Ack_Join ack_join; - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_); - ack_join.source = &this->proxy_; - ack_join.next_sequence_number = this->lowest_sequence_number_; - } - int result = this->reordering_.ack_join (ack_join); - if (result != 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("Reordering::ack_join returned %d\n"), - result)); - } - - for (int i = 0; i < iterations; ++i) - { - // Push data - this->generate_messages (iterations / 10); - } - if (this->next_expected_ == 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("Tester::run - no messages received\n"))); - } - else - { - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("Tester::run (%t) - %d messages received\n"), - this->next_expected_)); - } -} - -int -Tester::reply_ack (ACE_RMCast::Ack &ack) -{ - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - - // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Received Ack message (%d, %d)\n"), - // ack.next_expected, this->lowest_sequence_number_)); - - const int success_ratio = 95; - int c = ACE_OS::rand_r (this->seed_) % 100; - - if (c < success_ratio) - { - this->lowest_sequence_number_ = ack.next_expected; - } - return 0; -} - -void -Tester::generate_messages (int count) -{ - ACE_Message_Block payload (1024); - payload.wr_ptr (1024); - - ACE_RMCast::Data data; - data.source = &this->proxy_; - data.payload = &payload; - - ACE_UINT32 min_sn; - ACE_UINT32 max_sn; - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_); - min_sn = this->lowest_sequence_number_; - max_sn = this->lowest_sequence_number_ + count; - } - for (ACE_UINT32 i = min_sn; i != max_sn; ++i) - { - data.sequence_number = i; - - const int success_ratio = 95; - int c; - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_); - c = ACE_OS::rand_r (this->seed_) % 100; - } - if (c < success_ratio) - { - int result = this->reordering_.data (data); - if (result != 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("Reordering::data returned %d\n"), - result)); - } - } - } -} - -int -Tester::data (ACE_RMCast::Data &data) -{ - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1); - - if (this->next_expected_ != data.sequence_number) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("Tester::data - ") - ACE_TEXT ("out of sequence message (%d != %d)\n"), - this->next_expected_, - data.sequence_number)); - return -1; - } - - this->next_expected_++; - return 0; -} - -// **************************************************************** - -Task::Task (Tester *tester) - : tester_ (tester) -{ -} - -int -Task::svc (void) -{ - this->tester_->run (100); - return 0; -} - -// **************************************************************** - -Test_Proxy::Test_Proxy (void) - : tester_ (0) -{ -} - -int -Test_Proxy::reply_ack (ACE_RMCast::Ack & ack) -{ - return this->tester_->reply_ack (ack); -} diff --git a/tests/RMCast/RMCast_Retransmission_Test.cpp b/tests/RMCast/RMCast_Retransmission_Test.cpp deleted file mode 100644 index a827314d08a..00000000000 --- a/tests/RMCast/RMCast_Retransmission_Test.cpp +++ /dev/null @@ -1,501 +0,0 @@ -// $Id$ - -#include "../test_config.h" -#include "ace/OS_NS_time.h" -#include "ace/ACE.h" -#include "ace/Task.h" - -#include "ace/RMCast/RMCast_Proxy.h" -#include "ace/RMCast/RMCast_Retransmission.h" - -ACE_RCSID(tests, RMCast_Retransmission_Test, "$Id$") - -// **************************************************************** - -class Tester; - -//! Simple proxy for the ACE_RMCast_Retransmission test harness -/*! - * Implement a simple version of the ACE_RMCast_Proxy class used in - * the ACE_RMCast_Retransmission test harness. - */ -class Test_Proxy : public ACE_RMCast_Proxy -{ -public: - Test_Proxy (void); - - void set_tester (Tester *tester) - { - this->tester_ = tester; - } - - //! Get the flag to remember if this proxy has joined the group or - //! not. - int joined (void) const - { - return this->joined_; - } - - //! Set the flag to remember if this proxy has joined the group or - //! not. - void joined (int j) - { - this->joined_ = j; - } - - //! Most of the reply_ methods just return 0, there is no real remote - //! peer, this is just a test harness - //@{ - virtual int reply_data (ACE_RMCast::Data &) - { - return 0; - } - virtual int reply_poll (ACE_RMCast::Poll &) - { - return 0; - } - //! Must check that that sequence number is reasonable - virtual int reply_ack_join (ACE_RMCast::Ack_Join &); - virtual int reply_ack_leave (ACE_RMCast::Ack_Leave &) - { - return 0; - } - virtual int reply_ack (ACE_RMCast::Ack &) - { - return 0; - } - virtual int reply_join (ACE_RMCast::Join &) - { - return 0; - } - virtual int reply_leave (ACE_RMCast::Leave &) - { - return 0; - } - //@} - - int data (ACE_RMCast::Data &data); - int ack (ACE_RMCast::Ack &ack); - -private: - //! Remember if we joined the group already. - int joined_; - - //! Keep a reference to the main testing class so it can be called - //! back. - Tester *tester_; - - //! The test is randomized to get better coverage. This is the seed - //! variable for the test - ACE_RANDR_TYPE seed_; - - //! Synchronize internal data structures. - ACE_SYNCH_MUTEX lock_; -}; - -// **************************************************************** - -//! The number of proxies used in the test -/*! - * Not all member will be present in the group at the same time. But - * this variable controls the maximum number - */ -const size_t nproxy = 16; -//! A simple module to receive the messages from ACE_RMCast_Retransmission -/*! - * The ACE_RMCast_Retransmission layer pushes messages to its next module - * when all the members have acked a message, when a new member joins, - * when a member leaves, etc. - * This class will verify that the messages are exactly what we - * expect. - */ -class Tester : public ACE_RMCast_Module -{ -public: - Tester (void); - - //! Run the test for \param iterations times - void run (int iterations); - - //! Validate the number of messages received by each proxy - void validate_message_count (void); - - //! One of the proxies has received an Ack_Join message, we need to - //! validate it - int reply_ack_join (Test_Proxy *proxy, ACE_RMCast::Ack_Join &ack_join); - - //! One of the proxies has received an Ack message. - /*! - * In this method we simulate the role of the Membership layer, - * however we just do brute force instead of trying to optimize the - * Ack processing - */ - int proxy_received_ack (Test_Proxy *proxy, ACE_RMCast::Ack &ack); - - virtual int data (ACE_RMCast::Data &data); - -private: - //! Generate a new message to drive the test - void generate_one_message (void); - - //! Send a single Ack that summarizes the state of all the proxies. - int send_ack (void); - - //! Ask the retransmission layer to resend lost messages - int resend (void); - -private: - //! The array of proxies - Test_Proxy proxy_[nproxy]; - - //! The Retransmission layer - ACE_RMCast_Retransmission retransmission_; - - //! Synchronize internal data structures - ACE_SYNCH_MUTEX lock_; - - //! The test is randomized to get better coverage. This is the seed - //! variable for the test - ACE_RANDR_TYPE seed_; - - //! Generate sequence numbers for the Retransmission layer - ACE_UINT32 sequence_number_generator_; -}; - -// **************************************************************** - -//! An Adapter to run Tester::run the test is a separate thread -class Task : public ACE_Task_Base -{ -public: - Task (Tester *tester); - - // = Read the documentation in "ace/Task.h" - int svc (void); - -private: - //! The tester object. - Tester *tester_; -}; - -// **************************************************************** - -int -run_main (int, ACE_TCHAR *[]) -{ - ACE_START_TEST (ACE_TEXT ("RMCast_Retransmission_Test")); - - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"), - ACE::major_version(), - ACE::minor_version(), - ACE::beta_version())); - - { - ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Running single threaded test\n"))); - //! Run the test in single threaded mode - Tester tester; - tester.run (100); - tester.validate_message_count (); - } - { - ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Running multi threaded test\n"))); - //! Run the test in multi-threaded mode - Tester tester; - Task task (&tester); - if (task.activate (THR_NEW_LWP|THR_JOINABLE, 4) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Cannot activate the threads\n")), - 1); - ACE_Thread_Manager::instance ()->wait (); - tester.validate_message_count (); - } - - ACE_END_TEST; - return 0; -} - -// **************************************************************** - -Tester::Tester (void) - : seed_ (static_cast<ACE_RANDR_TYPE> (ACE_OS::time (0))) - , sequence_number_generator_ (0) -{ - // Initialize the stack... - this->retransmission_.next (this); - - for (size_t i = 0; i != nproxy; ++i) - { - this->proxy_[i].set_tester (this); - this->proxy_[i].joined (1); - } -} - -void -Tester::run (int iterations) -{ - for (int i = 0; i < iterations; ++i) - { - // Push data - this->generate_one_message (); - - this->send_ack (); - - // Re-send unacked data - if (i % 5 == 0) - { - this->resend (); - this->send_ack (); - } - } - - while (this->resend () != 0) - { - this->send_ack (); - } -} - -void -Tester::validate_message_count (void) -{ - for (size_t i = 0; i != nproxy; ++i) - { - if (this->proxy_[i].joined () == 0) - continue; - if (this->proxy_[i].next_expected () != this->sequence_number_generator_) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("Invalid message count for proxy %d, ") - ACE_TEXT ("it is %d, should be %d\n"), - i, this->proxy_[i].next_expected (), - this->sequence_number_generator_)); - } - } -} - -int -Tester::reply_ack_join (Test_Proxy *, ACE_RMCast::Ack_Join &ack_join) -{ - if (ack_join.next_sequence_number > this->sequence_number_generator_) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("Unexpected sequence number in ack_join ") - ACE_TEXT ("(%d,%d)\n"), - ack_join.next_sequence_number, - this->sequence_number_generator_)); - return -1; - } - return 0; -} - -int -Tester::proxy_received_ack (Test_Proxy *, ACE_RMCast::Ack &) -{ - return this->send_ack (); -} - -int -Tester::send_ack () -{ - ACE_RMCast::Ack ack; - - int set = 0; - for (size_t i = 0; i != nproxy; ++i) - { - if (this->proxy_[i].joined () == 0) - continue; - if (!set) - { - ack.next_expected = this->proxy_[i].next_expected (); - ack.highest_received = this->proxy_[i].highest_received (); - set = 1; - } - else - { - if (ack.next_expected > this->proxy_[i].next_expected ()) - ack.next_expected = this->proxy_[i].next_expected (); - if (ack.highest_received < this->proxy_[i].highest_received ()) - ack.highest_received = this->proxy_[i].highest_received (); - } - } - if (!set) - return 0; - // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Tested::ack - (%d,%d)\n"), - // ack.next_expected, ack.highest_received)); - return this->retransmission_.ack (ack); -} - -void -Tester::generate_one_message (void) -{ - ACE_Message_Block payload (1024); - payload.wr_ptr (1024); - - ACE_RMCast::Data data; - data.payload = &payload; - { - ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->lock_); - data.sequence_number = this->sequence_number_generator_++; - } - - int result = this->retransmission_.data (data); - if (result != 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("Retransmission::data returned %d\n"), - result)); - } -} - -int -Tester::resend (void) -{ - ACE_UINT32 max_sequence_number = - this->sequence_number_generator_; - int r = this->retransmission_.resend (max_sequence_number); - if (r == -1) - { - // ACE_DEBUG ((LM_DEBUG, - // ACE_TEXT ("Error returned from Retransmission::resend\n"))); - } - return r; -} - -int -Tester::data (ACE_RMCast::Data &data) -{ - // After going through the Retransmission layer we got some data, - // simulate the work of the following layers: - // - Fragmentation: setting message sequence numbers - // - IO_XXX: send to all known members - // - Reassembly: reconstruct the message on the receiving side. - - data.total_size = 1024; - data.fragment_offset = 0; - - for (size_t i = 0; i != nproxy; ++i) - { - int result = this->proxy_[i].data (data); - if (result != 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("Proxy::data returned %d for proxy %d\n"), - result, i)); - return -1; - } - } - return 0; -} - -// **************************************************************** - -Task::Task (Tester *tester) - : tester_ (tester) -{ -} - -int -Task::svc (void) -{ - this->tester_->run (100); - return 0; -} - -// **************************************************************** - -Test_Proxy::Test_Proxy (void) - : joined_ (0) - , tester_ (0) - , seed_ (static_cast<ACE_RANDR_TYPE> (ACE_OS::time (0))) -{ -} - -int -Test_Proxy::data (ACE_RMCast::Data &data) -{ - // ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (%t) Proxy receives message %d\n"), - // data.sequence_number)); - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); - - int c = ACE_OS::rand_r (this->seed_) % 100; - - const int success_ratio = 95; - - if (this->next_expected () > data.sequence_number) - { - // An old message, resend the ack... - ACE_RMCast::Ack ack; - ack.next_expected = this->next_expected (); - ack.highest_received = this->highest_received (); - // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("....it is an already accepted message\n"))); - // Ack the message.... - return this->ack (ack); - } - - if (this->next_expected () == data.sequence_number) - { - // The message is the next one that we expected... - // Two choices: accept the message as successfully received or - // reject it, we accept them most of the time. - if (c > success_ratio) - { - // We ignore the message completely as if it was lost in the - // network - // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("....and drops it\n"))); - return 0; - } - - ACE_RMCast::Ack ack; - ack.next_expected = data.sequence_number + 1; - if (ack.next_expected < this->highest_received ()) - { - ack.highest_received = this->highest_received (); - } - else - { - ack.highest_received = data.sequence_number; - } - // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("....and accepts it\n"))); - // Ack the message.... - return this->ack (ack); - } - - // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("....the message is out of order\n"))); - // This is an out of sequence number, maybe it is lost... - if (c > success_ratio) - { - // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("........and is dropped\n"))); - return 0; - } - - // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("........and is accepted\n"))); - ACE_RMCast::Ack ack; - ack.next_expected = this->next_expected (); - if (data.sequence_number < this->highest_received ()) - { - ack.highest_received = this->highest_received (); - } - else - { - ack.highest_received = data.sequence_number; - } - // Ack the message.... - return this->ack (ack); -} - -int -Test_Proxy::ack (ACE_RMCast::Ack &ack) -{ - (void) this->ACE_RMCast_Proxy::ack (ack); - (void) this->tester_->proxy_received_ack (this, ack); - return 0; -} - -int -Test_Proxy::reply_ack_join (ACE_RMCast::Ack_Join & ack_join) -{ - int r = this->tester_->reply_ack_join (this, ack_join); - if (r == 0) - (void) this->ACE_RMCast_Proxy::reply_ack_join (ack_join); - return r; -} diff --git a/tests/RMCast/RMCast_UDP_Best_Effort_Test.cpp b/tests/RMCast/RMCast_UDP_Best_Effort_Test.cpp deleted file mode 100644 index c9a7d83ed22..00000000000 --- a/tests/RMCast/RMCast_UDP_Best_Effort_Test.cpp +++ /dev/null @@ -1,268 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = DESCRIPTION -// Unit test for the UDP sending module of the RMCast library. -// -// = AUTHORS -// Carlos O'Ryan <coryan@uci.edu> -// -// ============================================================================ - -#include "../test_config.h" -#include "ace/RMCast/RMCast_IO_UDP.h" -#include "ace/RMCast/RMCast_Fragment.h" - -#include "ace/RMCast/RMCast_Module_Factory.h" -#include "ace/RMCast/RMCast_Fragment.h" -#include "ace/RMCast/RMCast_Reassembly.h" - -#include "ace/Task.h" -#include "ace/ACE.h" - -ACE_RCSID(tests, RMCast_UDP_Best_Effort_Test, "$Id$") - -const size_t message_size = 8 * 1024; -const int total_message_count = 40; - -// **************************************************************** - -class Sender_Factory : public ACE_RMCast_Module_Factory -{ -public: - Sender_Factory (void) - { - } - - virtual ACE_RMCast_Module *create (void) - { - return new ACE_RMCast_Reassembly; - } - - virtual void destroy (ACE_RMCast_Module *module) - { - delete module; - } -}; - -// **************************************************************** - -class Receiver_Factory : public ACE_RMCast_Module_Factory -{ -public: - Receiver_Factory (ACE_RMCast_Module *module) - : module_ (module) - { - } - - virtual ACE_RMCast_Module *create (void) - { - ACE_RMCast_Module *x = new ACE_RMCast_Reassembly; - x->next (this->module_); - return x; - } - - virtual void destroy (ACE_RMCast_Module *module) - { - delete module; - } - -private: - ACE_RMCast_Module *module_; -}; - -// **************************************************************** - -class Sender : public ACE_Task_Base -{ -public: - Sender (const ACE_INET_Addr &mcast_group); - - virtual int svc (void); - -private: - Sender_Factory factory_; - ACE_RMCast_IO_UDP io_udp_; - ACE_RMCast_Fragment fragment_; - - ACE_INET_Addr mcast_group_; -}; - -// **************************************************************** - -class Receiver : public ACE_RMCast_Module -{ -public: - Receiver (const ACE_INET_Addr &mcast_group); - - void dump (void); - // Print the results of the test - - int handle_events (ACE_Time_Value *tv); - // Invoke the UDP Receiver handle_events function - - virtual int open (void); - virtual int data (ACE_RMCast::Data &data); - -private: - Receiver_Factory factory_; - ACE_RMCast_IO_UDP io_udp_; - - ACE_INET_Addr mcast_group_; - - int message_count_; -}; - -// **************************************************************** - -int -run_main (int, ACE_TCHAR *[]) -{ - ACE_START_TEST (ACE_TEXT ("RMCast_UDP_Best_Effort_Test")); - - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"), - ACE::major_version(), - ACE::minor_version(), - ACE::beta_version())); - - ACE_INET_Addr mcast_group; - mcast_group.set (12345, ACE_TEXT ("224.9.9.1")); - - Receiver receiver (mcast_group); - if (receiver.open () != 0) - ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Error in Receiver::open\n")), 1); - - Sender sender (mcast_group); - if (sender.activate () != 0) - ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Error in Sender::activate\n")), 1); - - ACE_Time_Value tv (120, 0); - for (;;) - { - int r = receiver.handle_events (&tv); - - if (r < 0) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Error in handle_events()\n")), - 1); - } - if (tv == ACE_Time_Value::zero) - break; - } - - if (ACE_Thread_Manager::instance ()->wait () != 0) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Error in Thread_Manager::wait\n")), - 1); - - receiver.dump (); - - ACE_END_TEST; - return 0; -} - -// **************************************************************** - -Receiver::Receiver (const ACE_INET_Addr &mcast_group) - : factory_ (this) - , io_udp_ (&factory_) - , mcast_group_ (mcast_group) - , message_count_ (0) -{ -} - -int -Receiver::handle_events (ACE_Time_Value *tv) -{ - return this->io_udp_.handle_events (tv); -} - -int -Receiver::open (void) -{ - if (this->io_udp_.subscribe (this->mcast_group_) != 0) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Error in IO_UDP::subscribe\n")), - -1); - return 0; -} - -int -Receiver::data (ACE_RMCast::Data &data) -{ - if (data.total_size != message_size) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid message size (%d,%d,%d)\n"), - data.sequence_number, - data.total_size, - data.fragment_offset), -1); - if (data.fragment_offset != 0) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid message size (%d,%d,%d)\n"), - data.sequence_number, - data.total_size, - data.fragment_offset), -1); - - char expected = 0; - for (char *j = data.payload->rd_ptr (); - j != data.payload->wr_ptr (); - ++j) - { - if (*j != expected++) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Unexpected byte at pos %d\n"), - long(j - data.payload->rd_ptr ())), -1); - } - - this->message_count_++; - - return 0; -} - -void -Receiver::dump (void) -{ - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("Message count = %d/%d\n"), - this->message_count_, - total_message_count)); -} - -// **************************************************************** - -Sender::Sender (const ACE_INET_Addr &mcast_group) - : io_udp_ (&factory_) - , mcast_group_ (mcast_group) -{ -} - -int -Sender::svc () -{ - if (this->fragment_.next (&this->io_udp_) != 0) - ACE_ERROR ((LM_ERROR, ACE_TEXT ("Error in Fragment::next()\n"))); - - if (this->io_udp_.subscribe (this->mcast_group_) != 0) - ACE_ERROR ((LM_ERROR, ACE_TEXT ("Error in IO_UDP::subscribe()\n"))); - - ACE_Message_Block big_blob (message_size); - big_blob.wr_ptr (message_size); - - char filler = 0; - for (char* j = big_blob.rd_ptr (); j != big_blob.wr_ptr (); ++j) - { - *j = filler++; - } - - for (int i = 0; i != total_message_count; ++i) - { - ACE_RMCast::Data data; - data.sequence_number = i; - data.payload = &big_blob; - this->fragment_.data (data); - } - return 0; -} diff --git a/tests/RMCast/acetest.mpb b/tests/RMCast/acetest.mpb deleted file mode 100644 index 3321d43a7fe..00000000000 --- a/tests/RMCast/acetest.mpb +++ /dev/null @@ -1,20 +0,0 @@ -// -*- MPC -*- -// $Id$ - -project : aceexe { - - after += Test_Output - libs += Test_Output - - Source_Files { - $(ACE_ROOT)/tests/Main.cpp - } - Header_Files { - } - Resource_Files { - } - Documentation_Files { - } - Inline_Files { - } -} diff --git a/tests/RMCast/tests.mpc b/tests/RMCast/tests.mpc deleted file mode 100644 index 08ad42c7558..00000000000 --- a/tests/RMCast/tests.mpc +++ /dev/null @@ -1,45 +0,0 @@ -// -*- MPC -*- -// $Id$ - -project(RMCast Fragment Test) : acetest, rmcast { - exename = RMCast_Fragment_Test - Source_Files { - RMCast_Fragment_Test.cpp - } -} - -project(RMCast Membership Test) : acetest, rmcast { - exename = RMCast_Membership_Test - Source_Files { - RMCast_Membership_Test.cpp - } -} - -project(RMCast Reassembly Test) : acetest, rmcast { - exename = RMCast_Reassembly_Test - Source_Files { - RMCast_Reassembly_Test.cpp - } -} - -project(RMCast Reordering Test) : acetest, rmcast { - exename = RMCast_Reordering_Test - Source_Files { - RMCast_Reordering_Test.cpp - } -} - -project(RMCast Retransmission Test) : acetest, rmcast { - exename = RMCast_Retransmission_Test - Source_Files { - RMCast_Retransmission_Test.cpp - } -} - -project(RMCast UDP Best Effort Test) : acetest, rmcast { - exename = RMCast_UDP_Best_Effort_Test - Source_Files { - RMCast_UDP_Best_Effort_Test.cpp - } -} - |