2 #include "tao/MProfile.h"
3 #include "tao/Profile.h"
4 #include "tao/PolicyC.h"
5 #include "tao/ORB_Constants.h"
6 #include "tao/SystemException.h"
8 #include "ace/Log_Msg.h"
9 #include "ace/Guard_T.h"
10 #include "ace/CORBA_macros.h"
12 #if !defined (__ACE_INLINE__)
13 # include "tao/MProfile.inl"
14 #endif /* __ACE_INLINE__ */
16 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
18 TAO_MProfile::~TAO_MProfile ()
20 if (this->policy_list_
!= nullptr)
22 CORBA::ULong
const len
= this->policy_list_
->length ();
23 for (CORBA::ULong i
= 0; i
< len
; ++i
)
27 CORBA::Policy_ptr policy
= (*this->policy_list_
)[i
];
30 catch (const ::CORBA::Exception
&)
32 // Ignore all exceptions to allow other policies to be
37 delete this->policy_list_
;
44 TAO_MProfile::cleanup ()
46 if (this->pfiles_
!= nullptr)
48 for (TAO_PHandle i
= 0; i
< this->last_
; ++i
)
50 this->pfiles_
[i
]->_decr_refcnt ();
51 delete [] this->pfiles_
;
52 this->pfiles_
= nullptr;
61 TAO_MProfile::set (CORBA::ULong sz
)
69 // See if we already have an existing profile list or if we need to
70 // get ridof what we have.
73 // Release all of our profiles.
75 for (TAO_PHandle h
= 0;
80 this->pfiles_
[h
]->_decr_refcnt ();
81 this->pfiles_
[h
] = nullptr;
84 // Next see if we can reuse our profile list memory
87 // we cant reuse memory since the current array is too small!
88 delete [] this->pfiles_
;
90 ACE_NEW_RETURN (this->pfiles_
,
95 // else , leave this->size and this->pfiles alone!
99 // first time, initialize!
100 ACE_NEW_RETURN (this->pfiles_
,
109 for (TAO_PHandle i
= 0; i
!= this->size_
; ++i
)
110 this->pfiles_
[i
] = nullptr;
116 TAO_MProfile::set (const TAO_MProfile
&mprofile
)
118 // NOTE: We use mprofile->last_ instead of mprofile->size_ to set
119 // this->size_. This is so we can use set () to trim a profile
122 this->set (mprofile
.last_
);
125 this->last_
= mprofile
.last_
;
127 // These are set in set (ULong);
128 // this->current_ = 0;
129 // this->forward_from_ = 0;
131 // Now reference all profiles.
132 for (TAO_PHandle h
= 0; h
< this->last_
; ++h
)
134 this->pfiles_
[h
] = mprofile
.pfiles_
[h
];
135 if (this->pfiles_
[h
] != nullptr)
136 this->pfiles_
[h
]->_incr_refcnt ();
144 TAO_MProfile::grow (CORBA::ULong sz
)
146 if (sz
<= this->size_
)
149 // get the additional space
150 TAO_Profile
**new_pfiles
= nullptr;
151 TAO_Profile
**old_pfiles
= nullptr;
152 ACE_NEW_RETURN (new_pfiles
,
156 old_pfiles
= this->pfiles_
;
158 // got it, now copy profiles
159 for (TAO_PHandle h
= 0; h
< this->size_
; ++h
)
161 new_pfiles
[h
] = old_pfiles
[h
];
162 old_pfiles
[h
] = nullptr;
165 this->pfiles_
= new_pfiles
;
167 delete [] old_pfiles
;
173 TAO_MProfile::add_profile (TAO_Profile
*pfile
)
175 // skip by the used slots
176 if (last_
== size_
) // full!
178 if (this->grow (this->size_
+ 1) < 0)
182 pfiles_
[last_
++] = pfile
;
184 if (pfile
&& pfile
->_incr_refcnt () == 0)
185 TAOLIB_ERROR_RETURN ((LM_ERROR
,
186 ACE_TEXT ("(%P|%t) Unable to increment reference ")
187 ACE_TEXT ("count in add_profile!\n")),
194 TAO_MProfile::add_profiles (TAO_MProfile
*pfiles
)
196 // this->size_ == total number of profiles we can hold
197 // this->last_ == the index of the last profile
198 CORBA::ULong
const space
= this->size_
- this->last_
;
200 if (space
< pfiles
->last_
)
203 if (this->grow (this->last_
+ pfiles
->last_
) < 0)
207 // copy over profiles
208 for (TAO_PHandle h
= 0; h
< pfiles
->last_
; ++h
)
210 if (this->add_profile (pfiles
->pfiles_
[h
]) < 0)
217 // the layout for a full list of 7 Profiles.
219 // last_ == one past the last valid entry, so if the list has 2
220 // profiles then last_ equals 2.
221 // current_ == index of the next profile to be returned (or one past
222 // the last returned.
224 // this->size_ = 7; current_ = 3; last_ = 7
225 // 0, 1, 2, 3, 4, 5, 6}
226 // { _, _, _, _, ..., _}
229 TAO_MProfile::remove_profile (const TAO_Profile
*pfile
)
233 for (h
= 0; h
< this->last_
; ++h
)
235 if (this->pfiles_
[h
]->is_equivalent (pfile
))
237 TAO_Profile
*old
= this->pfiles_
[h
];
238 this->pfiles_
[h
] = nullptr;
239 old
->_decr_refcnt ();
240 // shift other profiles up one
241 // note, if h == last_ - 1 then do nothing.
242 for (TAO_PHandle inner
= h
; inner
< this->last_
- 1; ++inner
)
244 this->pfiles_
[inner
] = this->pfiles_
[inner
+ 1];
246 // subtract 1 from last_ to indicate we have one fewer profiles
253 return -1; // profile not found.
258 TAO_MProfile::remove_profiles (const TAO_MProfile
*pfiles
)
260 for (TAO_PHandle h
= 0; h
< pfiles
->last_
; ++h
)
262 if (this->remove_profile (pfiles
->pfiles_
[h
]) < 0)
269 TAO_MProfile::is_equivalent (const TAO_MProfile
*rhs
)
271 // Two profile lists are equivalent if at least one of the profiles
272 // from the first list is_equivalent to at least one of the profiles
273 // from the second list!!
274 for (TAO_PHandle h1
= 0; h1
< this->last_
; ++h1
)
275 for (TAO_PHandle h2
= 0; h2
< rhs
->last_
; ++h2
)
276 if (this->pfiles_
[h1
]->is_equivalent (rhs
->pfiles_
[h2
]))
283 TAO_MProfile::hash (CORBA::ULong max
)
285 CORBA::ULong hashval
= 0;
287 if (this->last_
== 0)
290 for (TAO_PHandle h
= 0; h
< this->last_
; ++h
)
292 hashval
+= pfiles_
[h
]->hash (max
);
295 // The above hash function return an ULong between 0 and max here we
296 // simply take the average value and round.
297 //return hashval / this->last_;
298 // Changed to a mod value instead of an average.
299 return hashval
% max
;
303 TAO_MProfile::create_policy_list ()
305 ACE_NEW_THROW_EX (this->policy_list_
,
308 CORBA::COMPLETED_NO
));
312 TAO_MProfile::init_policy_list ()
314 // The first time this method is called
315 // it causes the initialization of the policies
316 // for the current profile.
318 this->get_current_profile ()->get_policies (*this->policy_list_
);
320 this->is_policy_list_initialized_
= true;
324 TAO_MProfile::policy_list ()
326 if (!this->is_policy_list_initialized_
)
328 ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX
,
333 if (this->policy_list_
== nullptr)
335 this->create_policy_list ();
337 this->init_policy_list ();
340 CORBA::PolicyList
*ret_val
= nullptr;
341 ACE_NEW_THROW_EX (ret_val
,
342 CORBA::PolicyList (*this->policy_list_
),
344 CORBA::COMPLETED_NO
));
350 TAO_MProfile::give_shared_profile (TAO_Profile
*pfile
)
352 for (unsigned i
= 0; i
< this->last_
; i
++)
353 if (pfile
->tag() == this->pfiles_
[i
]->tag() &&
354 pfile
->compare_key(this->pfiles_
[i
]))
356 this->pfiles_
[i
]->add_generic_endpoint(pfile
->endpoint());
357 pfile
->_decr_refcnt();
360 return this->give_profile(pfile
, 0);
364 TAO_END_VERSIONED_NAMESPACE_DECL