diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-02a | 11 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-03a | 11 | ||||
-rw-r--r-- | ace/OS.h | 3 | ||||
-rw-r--r-- | ace/OS.i | 6 | ||||
-rw-r--r-- | ace/SOCK_Dgram_Mcast.cpp | 726 |
6 files changed, 61 insertions, 707 deletions
diff --git a/ChangeLog b/ChangeLog index f64a2be241a..bd75bc34229 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Tue Jun 18 14:29:26 2002 Douglas C. Schmidt <schmidt@macarena.cs.wustl.edu> + + * ace/SOCK_Dgram_Mcast.cpp: Reverted the file to the previous version + since somehow things got messed up... + +Tue Jun 18 12:44:54 2002 Douglas C. Schmidt <schmidt@tango.doc.wustl.edu> + + * ace/OS.{h,i}: Added a new method called stopped() that + returns 1 if the timer has already been stopped. Thanks to + Giovanni Zito <g.zito@acsys.it> for this suggestion. + Tue Jun 18 12:17:58 2002 Jaiganesh Balasubramanian <jai@doc.ece.uci.edu> * ace/QoS/SOCK_Dgram_Mcast_QoS.cpp: diff --git a/ChangeLogs/ChangeLog-02a b/ChangeLogs/ChangeLog-02a index f64a2be241a..bd75bc34229 100644 --- a/ChangeLogs/ChangeLog-02a +++ b/ChangeLogs/ChangeLog-02a @@ -1,3 +1,14 @@ +Tue Jun 18 14:29:26 2002 Douglas C. Schmidt <schmidt@macarena.cs.wustl.edu> + + * ace/SOCK_Dgram_Mcast.cpp: Reverted the file to the previous version + since somehow things got messed up... + +Tue Jun 18 12:44:54 2002 Douglas C. Schmidt <schmidt@tango.doc.wustl.edu> + + * ace/OS.{h,i}: Added a new method called stopped() that + returns 1 if the timer has already been stopped. Thanks to + Giovanni Zito <g.zito@acsys.it> for this suggestion. + Tue Jun 18 12:17:58 2002 Jaiganesh Balasubramanian <jai@doc.ece.uci.edu> * ace/QoS/SOCK_Dgram_Mcast_QoS.cpp: diff --git a/ChangeLogs/ChangeLog-03a b/ChangeLogs/ChangeLog-03a index f64a2be241a..bd75bc34229 100644 --- a/ChangeLogs/ChangeLog-03a +++ b/ChangeLogs/ChangeLog-03a @@ -1,3 +1,14 @@ +Tue Jun 18 14:29:26 2002 Douglas C. Schmidt <schmidt@macarena.cs.wustl.edu> + + * ace/SOCK_Dgram_Mcast.cpp: Reverted the file to the previous version + since somehow things got messed up... + +Tue Jun 18 12:44:54 2002 Douglas C. Schmidt <schmidt@tango.doc.wustl.edu> + + * ace/OS.{h,i}: Added a new method called stopped() that + returns 1 if the timer has already been stopped. Thanks to + Giovanni Zito <g.zito@acsys.it> for this suggestion. + Tue Jun 18 12:17:58 2002 Jaiganesh Balasubramanian <jai@doc.ece.uci.edu> * ace/QoS/SOCK_Dgram_Mcast_QoS.cpp: @@ -684,6 +684,9 @@ public: /// call to stop. int update (void); + /// Returns 1 if we've already been stopped, else 0. + int stopped (void) const; + private: /// Maximum time we were willing to wait. ACE_Time_Value *max_wait_time_; @@ -11308,6 +11308,12 @@ ACE_Countdown_Time::start (void) } ACE_INLINE int +ACE_Countdown_Time::stopped (void) const +{ + return stopped_; +} + +ACE_INLINE int ACE_Countdown_Time::stop (void) { if (this->max_wait_time_ != 0 && this->stopped_ == 0) diff --git a/ace/SOCK_Dgram_Mcast.cpp b/ace/SOCK_Dgram_Mcast.cpp index e71ae48f24e..194ab00b18f 100644 --- a/ace/SOCK_Dgram_Mcast.cpp +++ b/ace/SOCK_Dgram_Mcast.cpp @@ -1,709 +1,21 @@ /* $Id$ */ +/* + * The legacy ACE_SOCK_Dgram_Mcast class is a specialization of the newer + * ACE_SOCK_Dgram_Mcast_Ex templated class. + * + * This file is a vestige of the original class, which is only used to satisfy + * automated build rules and to elicit environment-specific template support + * behavior, if necessary. + */ + +// Build the "real" class files. #include "ace/SOCK_Dgram_Mcast.h" -#include "ace/INET_Addr.h" - -#ifndef ACE_SOCK_DGRAM_MCAST_T_C -#define ACE_SOCK_DGRAM_MCAST_T_C - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -ACE_RCSID (ace, - SOCK_Dgram_Mcast_T, - "$Id$") - -// This is a workaround for platforms with non-standard -// definitions of the ip_mreq structure -#if ! defined (IMR_MULTIADDR) -#define IMR_MULTIADDR imr_multiaddr -#endif /* ! defined (IMR_MULTIADDR) */ - -// Short-hand for scoping the options enumeration. -typedef ACE_SOCK_Dgram_Mcast_Ex<ACE_SDM_DEFOPT_LOCK> ACE_SDM_OPTIONS; - -// Helper (inline) functions. -class ACE_SDM_helpers -{ -public: - // Convert ACE_INET_Addr to string, using local formatting rules. - enum - { - ADDR_STRING_MAX = 255 // max strlen of ip or interface address string. - // (interface string may be a UNIX pathname) - }; - - static void addr_to_string (const ACE_INET_Addr &ip_addr, - ACE_TCHAR *ret_string, // results here. - int clip_portnum) // clip port# info? - { - // Text displayed in case of conversion error. - static const ACE_TCHAR *cvt_err_string = ACE_LIB_TEXT("<?>"); - - if (ip_addr.addr_to_string (ret_string, - ADDR_STRING_MAX, - 1) == -1) - { - ACE_OS_String::strcpy (ret_string, - cvt_err_string); - } - else - { - ACE_TCHAR *pc; - if (clip_portnum - && (pc = ACE_OS_String::strchr (ret_string, ':'))) - *pc = '\0'; // clip port# info. - } - } - // op== for ip_mreq structs. - static int is_equal (const ip_mreq &m1, - const ip_mreq &m2) - { - return m1.IMR_MULTIADDR.s_addr == m2.IMR_MULTIADDR.s_addr - && m1.imr_interface.s_addr == m2.imr_interface.s_addr; - } -}; - -ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Dgram_Mcast_Ex) - -template <class ACE_SDMOPT_LOCK> -void ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::dump (void) ACE_CONST_WHEN_MUTABLE -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::dump"); - - ACE_TCHAR addr_string[ACE_SDM_helpers::ADDR_STRING_MAX+1]; - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT( \ - "\nOptions: bindaddr=%s, nulliface=%s, dtorunsub=%s\n"), - ((bind_addr_opt_ == ACE_SDM_OPTIONS::OPT_BINDADDR_YES) ? \ - "<Bound>" : "<Not Bound>"), - ((null_iface_opt_ == ACE_SDM_OPTIONS::OPT_NULLIFACE_ALL) ? \ - "<All Ifaces>" : "<Default Iface>"), - ((dtor_unsub_opt_ == ACE_SDM_OPTIONS::OPT_DTORUNSUB_YES) ? \ - "<Enabled>" : "<Disabled>"))); - - // Show bound addr and port#. - ACE_SDM_helpers::addr_to_string (this->bound_addr_, addr_string, 0); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("Bound address=%s\n"), - addr_string)); - - // Show default send addr, port#, and interface. - ACE_SDM_helpers::addr_to_string (this->send_addr_, addr_string, 0); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("Send addr=%s iface=%s\n"), - addr_string, - (this->send_net_if_ ? this->send_net_if_ : ACE_LIB_TEXT("<default>")))); - - // Show list of subscribed addresses. - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("Subscription list:\n"), "")); - { - ACE_GUARD (ACE_SDMOPT_LOCK, guard, this->subscription_list_lock_); - subscription_list_iter_t iter (this->subscription_list_); - for ( ; !iter.done (); iter.advance ()) - { - ACE_TCHAR iface_string[ACE_SDM_helpers::ADDR_STRING_MAX+1]; - ip_mreq *pm = iter.next (); - - // Get subscribed address (w/out port# info - not relevant). - ACE_INET_Addr ip_addr (ACE_static_cast (u_short, 0), - ntohl (pm->IMR_MULTIADDR.s_addr)); - ACE_SDM_helpers::addr_to_string (ip_addr, addr_string, 1); - - // Get interface address/specification. - ACE_INET_Addr if_addr (ACE_static_cast (u_short, 0), - ntohl (pm->imr_interface.s_addr)); - ACE_SDM_helpers::addr_to_string (if_addr, iface_string, 1); - if (ACE_OS_String::strcmp (iface_string, ACE_LIB_TEXT("0.0.0.0")) == 0) - // Receives on system default iface. (Note that null_iface_opt_ - // option processing has already occurred.) - ACE_OS_String::strcpy (iface_string, ACE_LIB_TEXT("<default>")); - - // Dump info. - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\taddr=%s iface=%s\n"), - addr_string, iface_string)); - } - } - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -} - -// Constructor. -template <class ACE_SDMOPT_LOCK> -ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::ACE_SOCK_Dgram_Mcast_Ex - (ACE_TYPENAME ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::options bind_addr_opt, - ACE_TYPENAME ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::options null_iface_opt, - ACE_TYPENAME ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::options dtor_unsub_opt) - : bind_addr_opt_ (bind_addr_opt), - null_iface_opt_ (null_iface_opt), - dtor_unsub_opt_ (dtor_unsub_opt), - send_net_if_ (NULL) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::ACE_SOCK_Dgram_Mcast_Ex"); -} - -// Destructor. -template <class ACE_SDMOPT_LOCK> -ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::~ACE_SOCK_Dgram_Mcast_Ex (void) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::~ACE_SOCK_Dgram_Mcast_Ex"); - - // Free memory and optionally unsubscribe from currently subscribed group(s). - delete [] send_net_if_; - this->clear_subs_list (dtor_unsub_opt_ == ACE_SDM_OPTIONS::OPT_DTORUNSUB_YES); -} - -// Overloaded (public) method. -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::open (const ACE_INET_Addr &mcast_addr, - const ACE_TCHAR *net_if, - int reuse_addr) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::open [public]"); - - // Only perform the <open> initialization if we haven't been opened - // earlier. - if (this->get_handle () == ACE_INVALID_HANDLE) - { - - // Invoke lower-layer ::open. - if (ACE_SOCK::open (SOCK_DGRAM, - PF_INET, - 0, - reuse_addr) == -1) - return -1; - - // Process addr/port reuse option. - if (reuse_addr) - { - int one = 1; - if (this->ACE_SOCK::set_option (SOL_SOCKET, - SO_REUSEADDR, - &one, - sizeof one) == -1) - return -1; -#if defined (SO_REUSEPORT) - if (this->ACE_SOCK::set_option (SOL_SOCKET, - SO_REUSEPORT, - &one, - sizeof one) == -1) - return -1; -#endif /* SO_REUSEPORT */ - } - - // Create an address/port# to bind the socket to. - ACE_INET_Addr bind_addy; - if (bind_addr_opt_ == ACE_SDM_OPTIONS::OPT_BINDADDR_YES) - { - // Bind to explicit addr and port#. - if (bind_addy.set (mcast_addr) == -1) - return -1; - } - else - { - // Bind to "any" address and explicit port#. - if (bind_addy.set (mcast_addr.get_port_number ()) == -1) - return -1; - } - - // Bind to the address (which may be INADDR_ANY) and port# (which may - // be 0) - if (ACE_SOCK_Dgram::shared_open (bind_addy, - PF_INET) == -1) - return -1; - - // Cache the actual bound address (which may be INADDR_ANY) - // and the actual bound port# (which will be a valid, non-zero port#). - ACE_INET_Addr bound_addy; - if (this->get_local_addr (bound_addy) == -1) - // (Unexpected failure - should be bound to something) - if (bound_addy.set (bind_addy) == -1) - // (Shouldn't happen - bind_addy is a valid addy; punt.) - return -1; - if (this->bound_addr_.set (bound_addy) == -1) - // (Shouldn't happen - bound_addy is a valid addy; punt.) - return -1; - - // Cache the address to use in the <send> methods (the passed mcast - // address and the actual bound port#), and set the interface to be - // used for sends if it was specified. - this->send_addr_ = mcast_addr; - this->send_addr_.set_port_number (this->bound_addr_.get_port_number ()); - if (net_if) - { -#if defined (IP_MULTICAST_IF) && (IP_MULTICAST_IF != 0) - ip_mreq send_mreq; - if (make_multicast_ifaddr (&send_mreq, - mcast_addr, - net_if) == -1) - return -1; - if (this->ACE_SOCK::set_option (IPPROTO_IP, - IP_MULTICAST_IF, - &(send_mreq.imr_interface), - sizeof send_mreq.imr_interface) == -1) - return -1; - this->send_net_if_ = new ACE_TCHAR[ACE_OS_String::strlen (net_if)+1]; - ACE_OS_String::strcpy (this->send_net_if_, - net_if); -#else - // Send interface option not supported - ignore it. - // (We may have been invoked by ::subscribe, so we have to allow - // a non-null interface parameter in this function.) - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ( \ - "Send interface specification not supported - IGNORED.\n"))); -#endif // IP_MULTICAST_IF - } - } - - return 0; -} - -// This is a hidden, non-virtual base-class method - it shouldn't be invoked -// ... but it is forwarded to the public interface, with no send interface -// specification, just in case. -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::open (const ACE_Addr &mcast_addr, - int protocol_family, - int protocol, - int reuse_addr) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::open [legacy]"); - // Note: Sun C++ 4.2 needs the useless const_cast. - return ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK> - ::open (ACE_reinterpret_cast (const ACE_INET_Addr&, - ACE_const_cast (ACE_Addr &, mcast_addr)), - ACE_static_cast (ACE_TCHAR*, NULL), - reuse_addr); -} - -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::subscribe_ifs (const ACE_INET_Addr &mcast_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol, - int reuse_addr) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::subscribe_ifs"); - - if (null_iface_opt_ == ACE_SDM_OPTIONS::OPT_NULLIFACE_ALL - && net_if == 0) - { - // Subscribe on all local multicast-capable network interfaces, by - // doing recursive calls with specific interfaces. - - ACE_INET_Addr *if_addrs = 0; - size_t if_cnt; - - if (ACE_Sock_Connect::get_ip_interfaces (if_cnt, - if_addrs) != 0) - return -1; - - size_t nr_subscribed = 0; - - if (if_cnt < 2) - { - if (this->subscribe (mcast_addr, - reuse_addr, - ACE_LIB_TEXT ("0.0.0.0"), - protocol_family, - protocol) == 0) - ++nr_subscribed; - } - else - { - // Iterate through all the interfaces, figure out which ones - // offer multicast service, and subscribe to them. - while (if_cnt > 0) - { - --if_cnt; - - // Convert to 0-based for indexing, next loop check. - if (if_addrs[if_cnt].get_ip_address () == INADDR_LOOPBACK) - continue; - if (this->subscribe (mcast_addr, - reuse_addr, - ACE_TEXT_CHAR_TO_TCHAR - (if_addrs[if_cnt].get_host_addr ()), - protocol_family, - protocol) == 0) - ++nr_subscribed; - } - } - - delete [] if_addrs; - - if (nr_subscribed == 0) - { - errno = ENODEV; - return -1; - } - - // 1 indicates a "short-circuit" return. This handles the - // recursive behavior of checking all the interfaces. - return 1; - } - - // Validate passed multicast addr and iface specifications. - if (this->make_multicast_ifaddr (NULL, - mcast_addr, - net_if) == -1) - return -1; - - // Check for port# different than bound port#. - u_short def_port_number = this->bound_addr_.get_port_number (), - sub_port_number = mcast_addr.get_port_number (); - if (sub_port_number != 0 - && def_port_number != 0 - && sub_port_number != def_port_number) - { - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("Subscribed port# (%u) different than bound port# (%u).\n"), - (u_int) sub_port_number, - (u_int) def_port_number)); - errno = ENXIO; - return -1; - } - - // If bind_addr_opt_ is enabled, check for address different than - // bound address. - if (bind_addr_opt_ == ACE_SDM_OPTIONS::OPT_BINDADDR_YES - && mcast_addr != this->bound_addr_) - { - ACE_TCHAR sub_addr_string[ACE_SDM_helpers::ADDR_STRING_MAX + 1], - bound_addr_string[ACE_SDM_helpers::ADDR_STRING_MAX + 1]; - ACE_SDM_helpers::addr_to_string (mcast_addr, sub_addr_string, 1); - ACE_SDM_helpers::addr_to_string (this->bound_addr_, - bound_addr_string, 1); - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("Subscribed address (%s) different than bound address (%s).\n"), - sub_addr_string, - bound_addr_string)); - errno = ENXIO; - return -1; - } - - // Addressing seems to be ok. - return 0; -} - -// Subscribe and add address/iface to subscription list if successful. -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::subscribe (const ACE_INET_Addr &mcast_addr, - int reuse_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::subscribe"); - ACE_INET_Addr subscribe_addr = mcast_addr; - - // If port# is 0, insert bound port# if it is set. (To satisfy lower-level - // port# validation.) - u_short def_port_number = this->bound_addr_.get_port_number (); - if (subscribe_addr.get_port_number () == 0 - && def_port_number != 0) - subscribe_addr.set_port_number (def_port_number); - - // Attempt subscription. - int result = subscribe_2 (subscribe_addr, - reuse_addr, - net_if, - protocol_family, - protocol); - - if (result == 0) - { - // Add this addr/iface info to the list of subscriptions. - // (Assumes this is unique addr/iface combo - most systems don't allow - // re-sub to same addr/iface.) - ip_mreq *pmreq = new ip_mreq; - if (this->make_multicast_ifaddr (pmreq, - subscribe_addr, - net_if) != -1) // (should not fail) - { - ACE_GUARD_RETURN (ACE_SDMOPT_LOCK, guard, - this->subscription_list_lock_, -1); - subscription_list_.insert_tail (pmreq); - } - else - delete pmreq; - } - - return result >= 0 ? 0 : result; -} - -// Attempt subscribe and return status. -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::subscribe_2 (const ACE_INET_Addr &mcast_addr, - int reuse_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::subscribe_2"); - ip_mreq mreq; - - // Open the socket IFF this is the first ::subscribe and ::open - // was not explicitly invoked. - if (this->open (mcast_addr, - net_if, - reuse_addr) == -1) - return -1; - - int result = this->subscribe_ifs (mcast_addr, - net_if, - protocol_family, - protocol, - reuse_addr); - // Check for error or "short-circuit" return. - if (result != 0) - return result; - - // Create multicast addr/if struct. - else if (this->make_multicast_ifaddr (&mreq, - mcast_addr, - net_if) == -1) - return -1; - - // Tell IP stack to pass messages sent to this group. - else if (this->ACE_SOCK::set_option (IPPROTO_IP, - IP_ADD_MEMBERSHIP, - &mreq, - sizeof mreq) == -1) - return -1; - else - return 0; -} - -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::unsubscribe_ifs (const ACE_INET_Addr &mcast_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::unsubscribe_ifs"); - - - if (null_iface_opt_ == ACE_SDM_OPTIONS::OPT_NULLIFACE_ALL - && net_if == 0) - { - // Unsubscribe on all local multicast-capable network interfaces, by - // doing recursive calls with specific interfaces. - - ACE_INET_Addr *if_addrs = 0; - size_t if_cnt; - - // NOTE - <get_ip_interfaces> doesn't always get all of the - // interfaces. In particular, it may not get a PPP interface. This - // is a limitation of the way <get_ip_interfaces> works with - // old versions of MSVC. The reliable way of getting the interface list - // is available only with MSVC 5 and newer. - if (ACE_Sock_Connect::get_ip_interfaces (if_cnt, - if_addrs) != 0) - return -1; - - size_t nr_unsubscribed = 0; - - if (if_cnt < 2) - { - if (this->unsubscribe (mcast_addr, - ACE_LIB_TEXT ("0.0.0.0"), - protocol_family, - protocol) == 0) - ++nr_unsubscribed; - } - else - while (if_cnt > 0) - { - --if_cnt; - // Convert to 0-based for indexing, next loop check - if (if_addrs[if_cnt].get_ip_address () == INADDR_LOOPBACK) - continue; - if (this->unsubscribe (mcast_addr, - ACE_TEXT_CHAR_TO_TCHAR - (if_addrs[if_cnt].get_host_addr ()), - protocol_family, - protocol) == 0) - ++nr_unsubscribed; - } - - delete [] if_addrs; - - if (nr_unsubscribed == 0) - { - errno = ENODEV; - return -1; - } - - return 1; - } - - return 0; -} - - -// Unsubscribe, and remove address from subscription list. -// Note: If there are duplicate entries, only finds the first in the list (this -// is a defined restriction - most environments don't allow duplicates to be -// created.) -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::unsubscribe (const ACE_INET_Addr &mcast_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::unsubscribe"); - - // Unsubscribe. - int result = this->unsubscribe_2 (mcast_addr, - net_if, - protocol_family, - protocol); - - // (Unconditionally) Remove this addr/if from subscription list. - // (Addr/if is removed even if unsubscribe failed) - ip_mreq tgt_mreq; - if (this->make_multicast_ifaddr (&tgt_mreq, - mcast_addr, - net_if) != -1) - { - ACE_GUARD_RETURN (ACE_SDMOPT_LOCK, guard, - this->subscription_list_lock_, -1); - for (subscription_list_iter_t iter (subscription_list_); - !iter.done (); - iter.advance ()) - { - ip_mreq *pm = iter.next (); - if (ACE_SDM_helpers::is_equal (*pm, tgt_mreq)) - { - iter.remove (); - delete pm; - break; - } - } - } - - return result >= 0 ? 0 : result; -} - -// Attempt unsubscribe and return status. -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::unsubscribe_2 (const ACE_INET_Addr &mcast_addr, - const ACE_TCHAR *net_if, - int protocol_family, - int protocol) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::unsubscribe_2"); - - int result = this->unsubscribe_ifs (mcast_addr, - net_if, - protocol_family, - protocol); - - // Check for error or "short-circuit" return. - if (result != 0) - return result; - - // Validate addr/if specifications and create addr/if struct. - ip_mreq mreq; - if (this->make_multicast_ifaddr (&mreq, - mcast_addr, - net_if) == -1) - return -1; - - // Tell network device driver to stop reading datagrams with the - // <mcast_addr>. - else if (ACE_SOCK::set_option (IPPROTO_IP, - IP_DROP_MEMBERSHIP, - &mreq, - sizeof mreq) == -1) - return -1; - else - return 0; -} - -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::unsubscribe (void) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::unsubscribe"); - return this->clear_subs_list (1); -} - -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::clear_subs_list (int do_unsubscribe) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::clear_subs_list"); - int result = 0; - { - ACE_GUARD_RETURN (ACE_SDMOPT_LOCK, guard, - this->subscription_list_lock_, -1); - for (subscription_list_iter_t iter (subscription_list_); - !iter.done (); - /*Hack: Do _not_ ::advance after remove*/) - { - ip_mreq *pm = iter.next (); - if (do_unsubscribe) - { - int rc = this->ACE_SOCK::set_option (IPPROTO_IP, - IP_DROP_MEMBERSHIP, - pm, - sizeof *pm); - if (rc != 0) - result = rc; - } - iter.remove (); - delete pm; - } - } - return result; -} - -template <class ACE_SDMOPT_LOCK> -int ACE_SOCK_Dgram_Mcast_Ex<ACE_SDMOPT_LOCK>::make_multicast_ifaddr (ip_mreq *ret_mreq, - const ACE_INET_Addr &mcast_addr, - const ACE_TCHAR *net_if) -{ - ACE_TRACE ("ACE_SOCK_Dgram_Mcast_Ex::make_multicast_ifaddr"); - ip_mreq lmreq; // Scratch copy. - if (net_if != 0) - { -#if defined (ACE_WIN32) - // This port number is not necessary, just convenient - ACE_INET_Addr interface_addr; - if (interface_addr.set (mcast_addr.get_port_number (), - net_if) == -1) - return -1; - lmreq.imr_interface.s_addr = - htonl (interface_addr.get_ip_address ()); -#else - ifreq if_address; - -#if defined (ACE_PSOS) - // Look up the interface by number, not name. - if_address.ifr_ifno = ACE_OS::atoi (net_if); -#else - ACE_OS::strcpy (if_address.ifr_name, net_if); -#endif /* defined (ACE_PSOS) */ - - if (ACE_OS::ioctl (this->get_handle (), - SIOCGIFADDR, - &if_address) == -1) - return -1; - - sockaddr_in *socket_address; - socket_address = ACE_reinterpret_cast (sockaddr_in*, - &if_address.ifr_addr); - lmreq.imr_interface.s_addr = socket_address->sin_addr.s_addr; -#endif /* ACE_WIN32 */ - } - else - lmreq.imr_interface.s_addr = INADDR_ANY; - - lmreq.IMR_MULTIADDR.s_addr = ACE_HTONL (mcast_addr.get_ip_address ()); - - // Set return info, if requested. - if (ret_mreq) - *ret_mreq = lmreq; - - return 0; -} - -#endif /* ACE_SOCK_DGRAM_MCAST_T_C */ + +// Instantiate SOCK_Dgram_Mcast_Ex internal templates, if necessary. +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_DLList_Iterator<ip_mreq>; +template class ACE_DLList<ip_mreq>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_DLList_Iterator<ip_mreq> +#pragma instantiate ACE_DLList<ip_mreq> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ |