OpenDDS  Snapshot(2023/04/28-20:55)
DomainParticipantFactoryImpl.cpp
Go to the documentation of this file.
1 /*
2  * Distributed under the OpenDDS License.
3  * See: http://www.opendds.org/license.html
4  */
5 
6 #include <DCPS/DdsDcps_pch.h> // Only the _pch include should start with DCPS/
7 
9 
10 #include "DomainParticipantImpl.h"
11 #include "Marked_Default_Qos.h"
12 #include "GuidConverter.h"
13 #include "Service_Participant.h"
14 #include "Qos_Helper.h"
15 #include "Util.h"
16 #include "DCPS_Utils.h"
18 
19 #include <dds/DdsDcpsInfoUtilsC.h>
20 
22 
23 namespace OpenDDS {
24 namespace DCPS {
25 
27  : qos_(TheServiceParticipant->initial_DomainParticipantFactoryQos()),
28  default_participant_qos_(TheServiceParticipant->initial_DomainParticipantQos())
29 {
30 }
31 
33 {
34  if (DCPS_debug_level > 0) {
36  "(%P|%t) DomainParticipantFactoryImpl::"
37  "~DomainParticipantFactoryImpl()\n"));
38  }
39 }
40 
41 DDS::DomainParticipant_ptr
43  DDS::DomainId_t domainId,
44  const DDS::DomainParticipantQos & qos,
45  DDS::DomainParticipantListener_ptr a_listener,
46  DDS::StatusMask mask)
47 {
48  DDS::DomainParticipantQos par_qos = qos;
49 
50  if (par_qos == PARTICIPANT_QOS_DEFAULT) {
52  }
53 
54  if (!Qos_Helper::valid(par_qos)) {
55  if (DCPS_debug_level > 0) {
57  ACE_TEXT("(%P|%t) ERROR: ")
58  ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")
59  ACE_TEXT("invalid qos.\n")));
60  }
61  return DDS::DomainParticipant::_nil();
62  }
63 
64  if (!Qos_Helper::consistent(par_qos)) {
65  if (DCPS_debug_level > 0) {
67  ACE_TEXT("(%P|%t) ERROR: ")
68  ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")
69  ACE_TEXT("inconsistent qos.\n")));
70  }
71  return DDS::DomainParticipant::_nil();
72  }
73 
75  make_rch<DomainParticipantImpl>(ref(participant_handles_), domainId, par_qos, a_listener, mask);
76 
78  if (dp->enable() != DDS::RETCODE_OK) {
79  if (DCPS_debug_level > 0) {
81  ACE_TEXT("(%P|%t) ERROR: ")
82  ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")
83  ACE_TEXT("unable to enable DomainParticipant.\n")));
84  }
85  return DDS::DomainParticipant::_nil();
86  }
87  }
88 
89  // if the specified transport is a transport template then create a new transport
90  // instance for the new participant if per_participant is set (checked before creating instance).
91  ACE_TString transport_base_config_name;
92  TheServiceParticipant->get_transport_base_config_name(domainId, transport_base_config_name);
93 
94  if (TheTransportRegistry->config_has_transport_template(transport_base_config_name)) {
95  OPENDDS_STRING transport_config_name = ACE_TEXT_ALWAYS_CHAR(transport_base_config_name.c_str());
96  OPENDDS_STRING transport_instance_name = dp->get_unique_id();
97 
98  // unique config and instance names are returned in transport_config_name and transport_instance_name
99  const bool ret = TheTransportRegistry->create_new_transport_instance_for_participant(domainId, transport_config_name, transport_instance_name);
100 
101  if (ret) {
102  TheTransportRegistry->bind_config(transport_config_name, dp.in());
103  TheTransportRegistry->update_config_template_instance_info(transport_config_name, transport_instance_name);
104  } else {
105  if (DCPS_debug_level > 0) {
107  ACE_TEXT("(%P|%t) ERROR: ")
108  ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")
109  ACE_TEXT("could not create new transport instance for participant.\n")));
110  }
111  return DDS::DomainParticipant::_nil();
112  }
113  }
114 
116  guard,
118  DDS::DomainParticipant::_nil());
119 
120  participants_[domainId].insert(dp);
121  return dp._retn();
122 }
123 
126  DDS::DomainParticipant_ptr a_participant)
127 {
128  if (CORBA::is_nil(a_participant)) {
129  if (DCPS_debug_level > 0) {
131  ACE_TEXT("(%P|%t) ERROR: ")
132  ACE_TEXT("DomainParticipantFactoryImpl::delete_participant, ")
133  ACE_TEXT("Nil participant.\n")));
134  }
136  }
137 
138  // The servant's ref count should be 2 at this point, one referenced
139  // by the poa and the other referenced by the map.
140  DomainParticipantImpl* the_servant = dynamic_cast<DomainParticipantImpl*>(a_participant);
141  if (!the_servant) {
142  if (DCPS_debug_level > 0) {
143  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: ")
144  ACE_TEXT("DomainParticipantFactoryImpl::delete_participant: ")
145  ACE_TEXT("failed to obtain the DomainParticipantImpl.\n")));
146  }
147  return DDS::RETCODE_ERROR;
148  }
149 
150  RcHandle<DomainParticipantImpl> servant_rch = rchandle_from(the_servant);
151 
152  TransportConfig_rch tr_cfg = servant_rch->transport_config();
153  if (tr_cfg) {
154  // check for and remove tranport template instance
155  TheTransportRegistry->remove_transport_template_instance(tr_cfg->name());
156  }
157 
158  //xxx servant rc = 4 (servant::DP::Entity::ServantBase::ref_count_
159  String leftover_entities;
160  if (!the_servant->is_clean(&leftover_entities)) {
161  if (log_level >= LogLevel::Notice) {
162  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: "
163  "DomainParticipantFactoryImpl::delete_participant: "
164  "the participant %C is not empty. %C leftover\n",
165  LogGuid(the_servant->get_id()).c_str(), leftover_entities.c_str()));
166  }
168  }
169 
170  const DDS::DomainId_t domain_id = the_servant->get_domain_id();
171  const GUID_t dp_id = the_servant->get_id();
172 
173  {
175  guard,
178 
179  DPMap::iterator pos = participants_.find(domain_id);
180  if (pos == participants_.end()) {
181  if (DCPS_debug_level > 0) {
183  ACE_TEXT("(%P|%t) ERROR: ")
184  ACE_TEXT("DomainParticipantFactoryImpl::delete_participant: ")
185  ACE_TEXT("%p domain_id=%d dp_id=%C.\n"),
186  ACE_TEXT("find"),
187  domain_id,
188  LogGuid(dp_id).c_str()));
189  }
190  return DDS::RETCODE_ERROR;
191  }
192 
193  if (pos->second.erase(servant_rch) == 0) {
194  if (DCPS_debug_level > 0) {
196  ACE_TEXT("(%P|%t) ERROR: ")
197  ACE_TEXT("DomainParticipantFactoryImpl::delete_participant, ")
198  ACE_TEXT(" %p.\n"),
199  ACE_TEXT("remove")));
200  }
201  return DDS::RETCODE_ERROR;
202  }
203 
204  if (pos->second.empty() && participants_.erase(domain_id) == 0) {
205  if (DCPS_debug_level > 0) {
207  ACE_TEXT("(%P|%t) ERROR: ")
208  ACE_TEXT("DomainParticipantFactoryImpl::delete_participant, ")
209  ACE_TEXT(" %p.\n"),
210  ACE_TEXT("unbind")));
211  }
212  return DDS::RETCODE_ERROR;
213  }
214 
215  guard.release();
216 
217  const DDS::ReturnCode_t result = the_servant->delete_contained_entities();
218  if (result != DDS::RETCODE_OK) {
219  return result;
220  }
221  }
222 
223  Discovery_rch disco = TheServiceParticipant->get_discovery(domain_id);
224  if (disco) {
225  if (!disco->remove_domain_participant(domain_id, dp_id)) {
226  if (DCPS_debug_level > 0) {
228  ACE_TEXT("(%P|%t) ERROR: ")
229  ACE_TEXT("could not remove domain participant.\n")));
230  }
231  return DDS::RETCODE_ERROR;
232  }
233  }
234  return DDS::RETCODE_OK;
235 }
236 
237 DDS::DomainParticipant_ptr
239  DDS::DomainId_t domainId)
240 {
242  guard,
244  DDS::DomainParticipant::_nil());
245 
246  DPSet* entry = 0;
247 
248  if (find(participants_, domainId, entry) == -1) {
249  if (DCPS_debug_level >= 1) {
251  ACE_TEXT("(%P|%t) ")
252  ACE_TEXT("DomainParticipantFactoryImpl::lookup_participant, ")
253  ACE_TEXT(" not found for domain %d.\n"),
254  domainId));
255  }
256 
257  return DDS::DomainParticipant::_nil();
258 
259  } else {
260  // No specification about which participant will return. We just return the first
261  // object.
262  // Note: We are not duplicate the object ref, so a delete call is not needed.
263  return DDS::DomainParticipant::_duplicate(entry->begin()->in());
264  }
265 }
266 
269  const DDS::DomainParticipantQos & qos)
270 {
271  if (Qos_Helper::valid(qos)
272  && Qos_Helper::consistent(qos)) {
274  return DDS::RETCODE_OK;
275 
276  } else {
278  }
279 }
280 
284 {
286  return DDS::RETCODE_OK;
287 }
288 
289 DDS::DomainParticipantFactory_ptr
291 {
292  return TheParticipantFactory;
293 }
294 
298 {
299  if (Qos_Helper::valid(qos) && Qos_Helper::consistent(qos)) {
300  if (!(qos_ == qos) && Qos_Helper::changeable(qos_, qos))
301  qos_ = qos;
302 
303  return DDS::RETCODE_OK;
304 
305  } else {
307  }
308 }
309 
313 {
314  qos = this->qos_;
315  return DDS::RETCODE_OK;
316 }
317 
318 DomainParticipantFactoryImpl::DPMap
320 {
322 
323  return participants_;
324 }
325 
327 {
330 
331  /*
332  * Create a copy of the participants because we need to run
333  * delete_participants on them, but delete_participants removes them from the
334  * object's map.
335  */
336  DPMap copy = participants();
337 
339  DPMap::iterator itr;
340  for (itr = copy.begin(); itr != copy.end(); ++itr) {
341  DPSet& dp_set = itr->second;
342  DPSet::iterator dp_set_itr;
343  for (dp_set_itr = dp_set.begin(); dp_set_itr != dp_set.end(); ++dp_set_itr) {
344  DomainParticipantImpl* const dp = &**dp_set_itr;
346  if (tmp) {
347  if (log_level >= LogLevel::Notice) {
348  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: "
349  "DomainParticipantFactoryImpl::delete_all_participants: "
350  "delete_contained_entities returned %C\n",
351  retcode_to_string(tmp)));
352  }
353  rv = DDS::RETCODE_ERROR;
354  }
355 
356  tmp = delete_participant(dp);
357  if (tmp) {
358  if (log_level >= LogLevel::Notice) {
359  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: "
360  "DomainParticipantFactoryImpl::delete_all_participants: "
361  "delete_participant returned %C\n",
362  retcode_to_string(tmp)));
363  }
364  rv = DDS::RETCODE_ERROR;
365  }
366  }
367  }
368 
369  // Remove Empty Domain Id Sets
370  participants_.clear();
371 
372  return rv;
373 }
374 
376 {
378  size_t count = 0;
379  for (DPMap::const_iterator it = participants_.begin(); it != participants_.end(); ++it) {
380  count += it->second.size();
381  }
382  return count;
383 }
384 
385 } // namespace DCPS
386 } // namespace OpenDDS
387 
#define TheTransportRegistry
#define PARTICIPANT_QOS_DEFAULT
Implements the OpenDDS::DCPS::DomainParticipant interfaces.
#define ACE_DEBUG(X)
RcHandle< T > rchandle_from(T *pointer)
Definition: RcHandle_T.h:310
#define ACE_ERROR(X)
const char * c_str(void) const
const ReturnCode_t RETCODE_PRECONDITION_NOT_MET
std::string String
const ReturnCode_t RETCODE_INCONSISTENT_POLICY
virtual DDS::DomainParticipant_ptr create_participant(DDS::DomainId_t domainId, const DDS::DomainParticipantQos &qos, DDS::DomainParticipantListener_ptr a_listener, DDS::StatusMask mask)
static bool changeable(const DDS::UserDataQosPolicy &qos1, const DDS::UserDataQosPolicy &qos2)
Definition: Qos_Helper.inl:948
#define ACE_TEXT_ALWAYS_CHAR(STRING)
const char * c_str() const
DPMap participants_
The collection of domain participants.
reference_wrapper< T > ref(T &r)
Definition: RcHandle_T.h:237
EntityFactoryQosPolicy entity_factory
virtual DDS::ReturnCode_t get_default_participant_qos(DDS::DomainParticipantQos &qos)
DDS::DomainParticipantQos default_participant_qos_
The default qos value of DomainParticipant.
#define OPENDDS_STRING
virtual DDS::ReturnCode_t get_qos(DDS::DomainParticipantFactoryQos &qos)
DOMAINID_TYPE_NATIVE DomainId_t
LM_DEBUG
virtual DDS::ReturnCode_t set_default_participant_qos(const DDS::DomainParticipantQos &qos)
ACE_Recursive_Thread_Mutex participants_protector_
Protect the participant collection.
virtual DDS::DomainParticipantFactory_ptr get_instance()
#define ACE_GUARD_RETURN(MUTEX, OBJ, LOCK, RETURN)
virtual DDS::ReturnCode_t delete_contained_entities()
LM_NOTICE
bool is_clean(String *leftover_entities=0) const
const ReturnCode_t RETCODE_OUT_OF_RESOURCES
virtual DDS::ReturnCode_t delete_participant(DDS::DomainParticipant_ptr a_participant)
OPENDDS_STRING name() const
ACE_TEXT("TCP_Factory")
unsigned long StatusMask
OpenDDS_Dcps_Export unsigned int DCPS_debug_level
Definition: debug.cpp:30
OpenDDS_Dcps_Export LogLevel log_level
const char * retcode_to_string(DDS::ReturnCode_t value)
Definition: DCPS_Utils.cpp:29
DDS::ReturnCode_t copy(DDS::DynamicData_ptr dest, DDS::DynamicData_ptr src)
const ReturnCode_t RETCODE_ERROR
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
virtual DDS::ReturnCode_t set_qos(const DDS::DomainParticipantFactoryQos &qos)
const ReturnCode_t RETCODE_OK
#define TheParticipantFactory
static bool valid(const DDS::UserDataQosPolicy &qos)
Definition: Qos_Helper.inl:723
#define TheServiceParticipant
static bool consistent(const DDS::ResourceLimitsQosPolicy &resource_limits, const DDS::HistoryQosPolicy &history)
Definition: Qos_Helper.inl:596
LM_ERROR
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
DPMap participants() const
Make a copy of the participants map for reading.
Boolean is_nil(T x)
virtual DDS::DomainParticipant_ptr lookup_participant(DDS::DomainId_t domainId)
const ReturnCode_t RETCODE_BAD_PARAMETER
int find(Container &c, const Key &key, typename Container::mapped_type *&value)
Definition: Util.h:71