OpenDDS  Snapshot(2023/04/28-20:55)
ReceiveListenerSetMap.cpp
Go to the documentation of this file.
1 /*
2  *
3  *
4  * Distributed under the OpenDDS License.
5  * See: http://www.opendds.org/license.html
6  */
7 
8 #include "DCPS/DdsDcps_pch.h" //Only the _pch include should start with DCPS/
10 #include "dds/DCPS/GuidConverter.h"
11 #include "dds/DCPS/Util.h"
12 
13 #if !defined (__ACE_INLINE__)
15 #endif /* __ACE_INLINE__ */
16 
18 {
19  DBG_ENTRY_LVL("ReceiveListenerSetMap","~ReceiveListenerSetMap",6);
20 }
21 
22 int
24 (GUID_t publisher_id,
25  GUID_t subscriber_id,
26  const TransportReceiveListener_wrch& receive_listener)
27 {
28  DBG_ENTRY_LVL("ReceiveListenerSetMap","insert",6);
29  ReceiveListenerSet_rch listener_set (this->find_or_create(publisher_id));
30 
31  if (listener_set.is_nil()) {
32  // find_or_create failure
33  LogGuid pub_log(publisher_id);
35  ACE_TEXT("(%P|%t) ERROR: ReceiveListenerSetMap::insert: ")
36  ACE_TEXT("failed to find_or_create entry for ")
37  ACE_TEXT("publisher %C.\n"),
38  pub_log.c_str()), -1);
39  }
40 
41  int result = listener_set->insert(subscriber_id, receive_listener);
42 
43  if (result == 0 || result == 1) {
44  return 0;
45  }
46 
47  LogGuid sub_log(subscriber_id);
48  LogGuid pub_log(publisher_id);
50  ACE_TEXT("(%P|%t) ERROR: ReceiveListenerSetMap::insert: ")
51  ACE_TEXT("failed to insert subscriber %C for ")
52  ACE_TEXT("publisher %C.\n"),
53  sub_log.c_str(),
54  pub_log.c_str()));
55 
56  // Deal with possibility that the listener_set just got
57  // created - and just for us. This is to make sure we don't leave any
58  // empty ReceiveListenerSets in our map_.
59  if (listener_set->size() == 0) {
60  listener_set = this->remove_set(publisher_id);
61 
62  if (listener_set.is_nil()) {
64  ACE_TEXT("(%P|%t) ERROR: ReceiveListenerSetMap::insert: ")
65  ACE_TEXT("failed to remove (undo create) ReceiveListenerSet ")
66  ACE_TEXT("for publisher %C.\n"),
67  pub_log.c_str()));
68  }
69  }
70 
71  return -1;
72 }
73 
74 int
76  GUID_t subscriber_id)
77 {
78  DBG_ENTRY_LVL("ReceiveListenerSetMap","remove",6);
79  ReceiveListenerSet_rch listener_set;
80 
81  if (OpenDDS::DCPS::find(map_, publisher_id, listener_set) != 0) {
82  return 0;
83  }
84 
85  int result = listener_set->remove(subscriber_id);
86 
87  // Ignore the result
88  ACE_UNUSED_ARG(result);
89 
90  if (listener_set->size() == 0) {
91  if (unbind(map_, publisher_id) != 0) {
92  LogGuid pub_log(publisher_id);
94  ACE_TEXT("(%P|%t) ERROR: ReceiveListenerSetMap::remove: ")
95  ACE_TEXT("failed to remove empty ReceiveListenerSet for ")
96  ACE_TEXT("publisher %C.\n"),
97  pub_log.c_str()), -1);
98  }
99  }
100 
101  return 0;
102 }
103 
104 //MJM: Other than funky return values, the previous and next methods
105 //MJM: appear to be identical. Can't you implement remove(a,b) as
106 //MJM: "release_subscriber(a,b) ; return 0 ;" Oh. I guess it returns
107 //MJM: -1 from one spot as well. Could the calling code be happy with
108 //MJM: either of these? Is this to place where I found no return value
109 //MJM: of "1". Could you have been meaning to call the other method?
110 
111 /// This method is called when the (remote) subscriber is being
112 /// released. This method will return a 0 if the subscriber_id is
113 /// successfully disassociated with the publisher_id *and* there
114 /// are still other subscribers associated with the publisher_id.
115 /// This method will return 1 if, after the disassociation, the
116 /// publisher_id is no longer associated with any subscribers (which
117 /// also means it's element was removed from our map_).
118 int
120  GUID_t subscriber_id)
121 {
122  DBG_ENTRY_LVL("ReceiveListenerSetMap","release_subscriber",6);
123  ReceiveListenerSet_rch listener_set;
124 
125  if (OpenDDS::DCPS::find(map_, publisher_id, listener_set) != 0) {
126  LogGuid pub_log(publisher_id);
128  ACE_TEXT("(%P|%t) ERROR: ReciveListenerSetMap::release_subscriber: ")
129  ACE_TEXT("publisher %C not found in map_.\n"),
130  pub_log.c_str()));
131  // Return 1 to indicate that the publisher_id is no longer associated
132  // with any subscribers at all.
133  return 1;
134  }
135 
136  int result = listener_set->remove(subscriber_id);
137 
138  // Ignore the result
139  ACE_UNUSED_ARG(result);
140 
141  if (listener_set->size() == 0) {
142  if (unbind(map_, publisher_id) != 0) {
143  LogGuid pub_log(publisher_id);
145  ACE_TEXT("(%P|%t) ERROR: ReceiveListenerSetMap::release_subscriber: ")
146  ACE_TEXT("failed to remove empty ReceiveListenerSet for ")
147  ACE_TEXT("publisher %C.\n"),
148  pub_log.c_str()));
149  }
150 
151  // We always return 1 if we know the publisher_id is no longer
152  // associated with any ReceiveListeners.
153  return 1;
154  }
155 
156  // There are still ReceiveListeners associated with the publisher_id.
157  // We return a 0 in this case.
158  return 0;
159 }
160 
161 void
163 {
164  DBG_ENTRY_LVL("ReceiveListenerSetMap","operator=",6);
165  const MapType& map = rh.map();
166 
167  for (MapType::const_iterator itr = map.begin();
168  itr != map.end();
169  ++itr) {
170  ReceiveListenerSet_rch set = itr->second;
171  ReceiveListenerSet::MapType& smap = set->map();
172 
173  for (ReceiveListenerSet::MapType::iterator sitr = smap.begin();
174  sitr != smap.end();
175  ++sitr) {
176  this->insert(itr->first, sitr->first, sitr->second);
177  }
178  }
179 }
180 
181 void
183 {
184  DBG_ENTRY_LVL("ReceiveListenerSetMap","clear",6);
185 
186  for (MapType::iterator itr = this->map_.begin();
187  itr != this->map_.end();
188  ++itr) {
189  itr->second->clear();
190  }
191 
192  this->map_.clear();
193 }
#define ACE_ERROR(X)
ReceiveListenerSet_rch remove_set(GUID_t publisher_id)
int release_subscriber(GUID_t publisher_id, GUID_t subscriber_id)
const char * c_str() const
void operator=(const ReceiveListenerSetMap &rh)
MapType & map()
Give access to the underlying map for iteration purposes.
ReceiveListenerSet_rch find_or_create(GUID_t publisher_id)
ACE_TEXT("TCP_Factory")
int insert(GUID_t publisher_id, GUID_t subscriber_id, const TransportReceiveListener_wrch &receive_listener)
#define DBG_ENTRY_LVL(CNAME, MNAME, DBG_LVL)
Definition: EntryExit.h:68
#define ACE_ERROR_RETURN(X, Y)
int remove(GUID_t publisher_id, GUID_t subscriber_id)
LM_ERROR
int unbind(Container &c, const typename Container::key_type &k, typename Container::mapped_type &v)
Definition: Util.h:40
int find(Container &c, const Key &key, typename Container::mapped_type *&value)
Definition: Util.h:71