Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / MProfile.cpp
bloba8590c3d08a1c5c9b0626c21b8b7e0251b63859d
1 // -*- C++ -*-
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)
25 try
27 CORBA::Policy_ptr policy = (*this->policy_list_)[i];
28 policy->destroy ();
30 catch (const ::CORBA::Exception&)
32 // Ignore all exceptions to allow other policies to be
33 // destroyed.
37 delete this->policy_list_;
40 this->cleanup ();
43 void
44 TAO_MProfile::cleanup ()
46 if (this->pfiles_ != nullptr)
48 for (TAO_PHandle i = 0; i < this->last_; ++i)
49 if (this->pfiles_[i])
50 this->pfiles_[i]->_decr_refcnt ();
51 delete [] this->pfiles_;
52 this->pfiles_ = nullptr;
55 this->current_ = 0;
56 this->size_ = 0;
57 this->last_ = 0;
60 int
61 TAO_MProfile::set (CORBA::ULong sz)
63 if (sz == 0)
65 this->cleanup ();
66 return 0;
69 // See if we already have an existing profile list or if we need to
70 // get ridof what we have.
71 if (this->size_ != 0)
73 // Release all of our profiles.
75 for (TAO_PHandle h = 0;
76 h < this->size_;
77 ++h)
78 if (this->pfiles_[h])
80 this->pfiles_[h]->_decr_refcnt ();
81 this->pfiles_[h] = nullptr;
84 // Next see if we can reuse our profile list memory
85 if (this->size_ < sz)
87 // we cant reuse memory since the current array is too small!
88 delete [] this->pfiles_;
90 ACE_NEW_RETURN (this->pfiles_,
91 TAO_Profile *[sz],
92 -1);
93 this->size_ = sz;
95 // else , leave this->size and this->pfiles alone!
97 else
99 // first time, initialize!
100 ACE_NEW_RETURN (this->pfiles_,
101 TAO_Profile *[sz],
102 -1);
103 this->size_ = sz;
106 this->last_ = 0;
107 this->current_ = 0;
109 for (TAO_PHandle i = 0; i != this->size_; ++i)
110 this->pfiles_[i] = nullptr;
112 return this->size_;
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
120 // list!!
122 this->set (mprofile.last_);
124 // set indexes ...
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 ();
139 return 1;
142 // Not thread safe!
144 TAO_MProfile::grow (CORBA::ULong sz)
146 if (sz <= this->size_)
147 return 0;
149 // get the additional space
150 TAO_Profile **new_pfiles = nullptr;
151 TAO_Profile **old_pfiles = nullptr;
152 ACE_NEW_RETURN (new_pfiles,
153 TAO_Profile *[sz],
154 -1);
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;
166 this->size_ = sz;
167 delete [] old_pfiles;
169 return 0;
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)
179 return -1;
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")),
188 -1);
190 return last_ - 1;
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_)
202 // we need to grow!
203 if (this->grow (this->last_ + pfiles->last_) < 0)
204 return -1;
207 // copy over profiles
208 for (TAO_PHandle h = 0; h < pfiles->last_; ++h)
210 if (this->add_profile (pfiles->pfiles_[h]) < 0)
211 return -1;
213 return 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)
231 TAO_PHandle h;
232 int found = 0;
233 for (h = 0; h < this->last_; ++h)
235 if (this->pfiles_[h]->is_equivalent (pfile))
236 { // remove it!
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
247 this->last_--;
248 found = 1;
249 break;
252 if ( found == 0)
253 return -1; // profile not found.
254 return 0;
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)
263 return -1;
265 return 0;
268 CORBA::Boolean
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]))
277 return 1;
279 return 0;
282 CORBA::ULong
283 TAO_MProfile::hash (CORBA::ULong max)
285 CORBA::ULong hashval = 0;
287 if (this->last_ == 0)
288 return 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;
302 void
303 TAO_MProfile::create_policy_list ()
305 ACE_NEW_THROW_EX (this->policy_list_,
306 CORBA::PolicyList,
307 CORBA::NO_MEMORY (0,
308 CORBA::COMPLETED_NO));
311 void
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;
323 CORBA::PolicyList *
324 TAO_MProfile::policy_list ()
326 if (!this->is_policy_list_initialized_)
328 ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX,
329 guard,
330 this->mutex_,
331 nullptr);
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_),
343 CORBA::NO_MEMORY (0,
344 CORBA::COMPLETED_NO));
346 return ret_val;
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();
358 return i;
360 return this->give_profile(pfile, 0);
364 TAO_END_VERSIONED_NAMESPACE_DECL