Line data Source code
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 :
8 : #include "DomainParticipantFactoryImpl.h"
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"
17 : #include "transport/framework/TransportRegistry.h"
18 :
19 : #include <dds/DdsDcpsInfoUtilsC.h>
20 :
21 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
22 :
23 : namespace OpenDDS {
24 : namespace DCPS {
25 :
26 9 : DomainParticipantFactoryImpl::DomainParticipantFactoryImpl()
27 9 : : qos_(TheServiceParticipant->initial_DomainParticipantFactoryQos()),
28 18 : default_participant_qos_(TheServiceParticipant->initial_DomainParticipantQos())
29 : {
30 9 : }
31 :
32 18 : DomainParticipantFactoryImpl::~DomainParticipantFactoryImpl()
33 : {
34 9 : if (DCPS_debug_level > 0) {
35 0 : ACE_DEBUG((LM_DEBUG,
36 : "(%P|%t) DomainParticipantFactoryImpl::"
37 : "~DomainParticipantFactoryImpl()\n"));
38 : }
39 18 : }
40 :
41 : DDS::DomainParticipant_ptr
42 0 : DomainParticipantFactoryImpl::create_participant(
43 : DDS::DomainId_t domainId,
44 : const DDS::DomainParticipantQos & qos,
45 : DDS::DomainParticipantListener_ptr a_listener,
46 : DDS::StatusMask mask)
47 : {
48 0 : DDS::DomainParticipantQos par_qos = qos;
49 :
50 0 : if (par_qos == PARTICIPANT_QOS_DEFAULT) {
51 0 : get_default_participant_qos(par_qos);
52 : }
53 :
54 0 : if (!Qos_Helper::valid(par_qos)) {
55 0 : if (DCPS_debug_level > 0) {
56 0 : ACE_ERROR((LM_ERROR,
57 : ACE_TEXT("(%P|%t) ERROR: ")
58 : ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")
59 : ACE_TEXT("invalid qos.\n")));
60 : }
61 0 : return DDS::DomainParticipant::_nil();
62 : }
63 :
64 0 : if (!Qos_Helper::consistent(par_qos)) {
65 0 : if (DCPS_debug_level > 0) {
66 0 : ACE_ERROR((LM_ERROR,
67 : ACE_TEXT("(%P|%t) ERROR: ")
68 : ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")
69 : ACE_TEXT("inconsistent qos.\n")));
70 : }
71 0 : return DDS::DomainParticipant::_nil();
72 : }
73 :
74 : RcHandle<DomainParticipantImpl> dp =
75 0 : make_rch<DomainParticipantImpl>(ref(participant_handles_), domainId, par_qos, a_listener, mask);
76 :
77 0 : if (qos_.entity_factory.autoenable_created_entities) {
78 0 : if (dp->enable() != DDS::RETCODE_OK) {
79 0 : if (DCPS_debug_level > 0) {
80 0 : ACE_ERROR((LM_ERROR,
81 : ACE_TEXT("(%P|%t) ERROR: ")
82 : ACE_TEXT("DomainParticipantFactoryImpl::create_participant, ")
83 : ACE_TEXT("unable to enable DomainParticipant.\n")));
84 : }
85 0 : 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 0 : ACE_TString transport_base_config_name;
92 0 : TheServiceParticipant->get_transport_base_config_name(domainId, transport_base_config_name);
93 :
94 0 : if (TheTransportRegistry->config_has_transport_template(transport_base_config_name)) {
95 0 : OPENDDS_STRING transport_config_name = ACE_TEXT_ALWAYS_CHAR(transport_base_config_name.c_str());
96 0 : 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 0 : const bool ret = TheTransportRegistry->create_new_transport_instance_for_participant(domainId, transport_config_name, transport_instance_name);
100 :
101 0 : if (ret) {
102 0 : TheTransportRegistry->bind_config(transport_config_name, dp.in());
103 0 : TheTransportRegistry->update_config_template_instance_info(transport_config_name, transport_instance_name);
104 : } else {
105 0 : if (DCPS_debug_level > 0) {
106 0 : ACE_ERROR((LM_ERROR,
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 0 : return DDS::DomainParticipant::_nil();
112 : }
113 0 : }
114 :
115 0 : ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex,
116 : guard,
117 : participants_protector_,
118 : DDS::DomainParticipant::_nil());
119 :
120 0 : participants_[domainId].insert(dp);
121 0 : return dp._retn();
122 0 : }
123 :
124 : DDS::ReturnCode_t
125 0 : DomainParticipantFactoryImpl::delete_participant(
126 : DDS::DomainParticipant_ptr a_participant)
127 : {
128 0 : if (CORBA::is_nil(a_participant)) {
129 0 : if (DCPS_debug_level > 0) {
130 0 : ACE_ERROR((LM_ERROR,
131 : ACE_TEXT("(%P|%t) ERROR: ")
132 : ACE_TEXT("DomainParticipantFactoryImpl::delete_participant, ")
133 : ACE_TEXT("Nil participant.\n")));
134 : }
135 0 : return DDS::RETCODE_BAD_PARAMETER;
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 0 : DomainParticipantImpl* the_servant = dynamic_cast<DomainParticipantImpl*>(a_participant);
141 0 : if (!the_servant) {
142 0 : if (DCPS_debug_level > 0) {
143 0 : 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 0 : return DDS::RETCODE_ERROR;
148 : }
149 :
150 0 : RcHandle<DomainParticipantImpl> servant_rch = rchandle_from(the_servant);
151 :
152 0 : TransportConfig_rch tr_cfg = servant_rch->transport_config();
153 0 : if (tr_cfg) {
154 : // check for and remove tranport template instance
155 0 : TheTransportRegistry->remove_transport_template_instance(tr_cfg->name());
156 : }
157 :
158 : //xxx servant rc = 4 (servant::DP::Entity::ServantBase::ref_count_
159 0 : String leftover_entities;
160 0 : if (!the_servant->is_clean(&leftover_entities)) {
161 0 : if (log_level >= LogLevel::Notice) {
162 0 : 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 : }
167 0 : return DDS::RETCODE_PRECONDITION_NOT_MET;
168 : }
169 :
170 0 : const DDS::DomainId_t domain_id = the_servant->get_domain_id();
171 0 : const GUID_t dp_id = the_servant->get_id();
172 :
173 : {
174 0 : ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex,
175 : guard,
176 : participants_protector_,
177 : DDS::RETCODE_ERROR);
178 :
179 0 : DPMap::iterator pos = participants_.find(domain_id);
180 0 : if (pos == participants_.end()) {
181 0 : if (DCPS_debug_level > 0) {
182 0 : ACE_ERROR((LM_ERROR,
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 0 : return DDS::RETCODE_ERROR;
191 : }
192 :
193 0 : if (pos->second.erase(servant_rch) == 0) {
194 0 : if (DCPS_debug_level > 0) {
195 0 : ACE_ERROR((LM_ERROR,
196 : ACE_TEXT("(%P|%t) ERROR: ")
197 : ACE_TEXT("DomainParticipantFactoryImpl::delete_participant, ")
198 : ACE_TEXT(" %p.\n"),
199 : ACE_TEXT("remove")));
200 : }
201 0 : return DDS::RETCODE_ERROR;
202 : }
203 :
204 0 : if (pos->second.empty() && participants_.erase(domain_id) == 0) {
205 0 : if (DCPS_debug_level > 0) {
206 0 : ACE_ERROR((LM_ERROR,
207 : ACE_TEXT("(%P|%t) ERROR: ")
208 : ACE_TEXT("DomainParticipantFactoryImpl::delete_participant, ")
209 : ACE_TEXT(" %p.\n"),
210 : ACE_TEXT("unbind")));
211 : }
212 0 : return DDS::RETCODE_ERROR;
213 : }
214 :
215 0 : guard.release();
216 :
217 0 : const DDS::ReturnCode_t result = the_servant->delete_contained_entities();
218 0 : if (result != DDS::RETCODE_OK) {
219 0 : return result;
220 : }
221 0 : }
222 :
223 0 : Discovery_rch disco = TheServiceParticipant->get_discovery(domain_id);
224 0 : if (disco) {
225 0 : if (!disco->remove_domain_participant(domain_id, dp_id)) {
226 0 : if (DCPS_debug_level > 0) {
227 0 : ACE_ERROR((LM_ERROR,
228 : ACE_TEXT("(%P|%t) ERROR: ")
229 : ACE_TEXT("could not remove domain participant.\n")));
230 : }
231 0 : return DDS::RETCODE_ERROR;
232 : }
233 : }
234 0 : return DDS::RETCODE_OK;
235 0 : }
236 :
237 : DDS::DomainParticipant_ptr
238 0 : DomainParticipantFactoryImpl::lookup_participant(
239 : DDS::DomainId_t domainId)
240 : {
241 0 : ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex,
242 : guard,
243 : participants_protector_,
244 : DDS::DomainParticipant::_nil());
245 :
246 0 : DPSet* entry = 0;
247 :
248 0 : if (find(participants_, domainId, entry) == -1) {
249 0 : if (DCPS_debug_level >= 1) {
250 0 : ACE_DEBUG((LM_DEBUG,
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 0 : 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 0 : return DDS::DomainParticipant::_duplicate(entry->begin()->in());
264 : }
265 0 : }
266 :
267 : DDS::ReturnCode_t
268 0 : DomainParticipantFactoryImpl::set_default_participant_qos(
269 : const DDS::DomainParticipantQos & qos)
270 : {
271 0 : if (Qos_Helper::valid(qos)
272 0 : && Qos_Helper::consistent(qos)) {
273 0 : default_participant_qos_ = qos;
274 0 : return DDS::RETCODE_OK;
275 :
276 : } else {
277 0 : return DDS::RETCODE_INCONSISTENT_POLICY;
278 : }
279 : }
280 :
281 : DDS::ReturnCode_t
282 0 : DomainParticipantFactoryImpl::get_default_participant_qos(
283 : DDS::DomainParticipantQos & qos)
284 : {
285 0 : qos = default_participant_qos_;
286 0 : return DDS::RETCODE_OK;
287 : }
288 :
289 : DDS::DomainParticipantFactory_ptr
290 0 : DomainParticipantFactoryImpl::get_instance()
291 : {
292 0 : return TheParticipantFactory;
293 : }
294 :
295 : DDS::ReturnCode_t
296 0 : DomainParticipantFactoryImpl::set_qos(
297 : const DDS::DomainParticipantFactoryQos & qos)
298 : {
299 0 : if (Qos_Helper::valid(qos) && Qos_Helper::consistent(qos)) {
300 0 : if (!(qos_ == qos) && Qos_Helper::changeable(qos_, qos))
301 0 : qos_ = qos;
302 :
303 0 : return DDS::RETCODE_OK;
304 :
305 : } else {
306 0 : return DDS::RETCODE_INCONSISTENT_POLICY;
307 : }
308 : }
309 :
310 : DDS::ReturnCode_t
311 0 : DomainParticipantFactoryImpl::get_qos(
312 : DDS::DomainParticipantFactoryQos & qos)
313 : {
314 0 : qos = this->qos_;
315 0 : return DDS::RETCODE_OK;
316 : }
317 :
318 : DomainParticipantFactoryImpl::DPMap
319 0 : DomainParticipantFactoryImpl::participants() const
320 : {
321 0 : ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, guard, participants_protector_, DPMap());
322 :
323 0 : return participants_;
324 0 : }
325 :
326 0 : DDS::ReturnCode_t DomainParticipantFactoryImpl::delete_all_participants()
327 : {
328 0 : ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, guard, participants_protector_,
329 : DDS::RETCODE_OUT_OF_RESOURCES);
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 0 : DPMap copy = participants();
337 :
338 0 : DDS::ReturnCode_t rv = DDS::RETCODE_OK;
339 0 : DPMap::iterator itr;
340 0 : for (itr = copy.begin(); itr != copy.end(); ++itr) {
341 0 : DPSet& dp_set = itr->second;
342 0 : DPSet::iterator dp_set_itr;
343 0 : for (dp_set_itr = dp_set.begin(); dp_set_itr != dp_set.end(); ++dp_set_itr) {
344 0 : DomainParticipantImpl* const dp = &**dp_set_itr;
345 0 : DDS::ReturnCode_t tmp = dp->delete_contained_entities();
346 0 : if (tmp) {
347 0 : if (log_level >= LogLevel::Notice) {
348 0 : 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 0 : rv = DDS::RETCODE_ERROR;
354 : }
355 :
356 0 : tmp = delete_participant(dp);
357 0 : if (tmp) {
358 0 : if (log_level >= LogLevel::Notice) {
359 0 : 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 0 : rv = DDS::RETCODE_ERROR;
365 : }
366 : }
367 : }
368 :
369 : // Remove Empty Domain Id Sets
370 0 : participants_.clear();
371 :
372 0 : return rv;
373 0 : }
374 :
375 9 : size_t DomainParticipantFactoryImpl::participant_count() const
376 : {
377 9 : ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, guard, participants_protector_, 0);
378 9 : size_t count = 0;
379 9 : for (DPMap::const_iterator it = participants_.begin(); it != participants_.end(); ++it) {
380 0 : count += it->second.size();
381 : }
382 9 : return count;
383 9 : }
384 :
385 : } // namespace DCPS
386 : } // namespace OpenDDS
387 :
388 : OPENDDS_END_VERSIONED_NAMESPACE_DECL
|