MProfile.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // MProfile.cpp,v 1.45 2006/04/26 17:12:47 mesnier_p Exp
00004 #include "tao/MProfile.h"
00005 #include "tao/Environment.h"
00006 #include "tao/Profile.h"
00007 #include "tao/PolicyC.h"
00008 #include "tao/ORB_Constants.h"
00009 #include "tao/SystemException.h"
00010 
00011 #include "ace/Log_Msg.h"
00012 #include "ace/Guard_T.h"
00013 
00014 ACE_RCSID (tao,
00015            MProfile,
00016            "MProfile.cpp,v 1.45 2006/04/26 17:12:47 mesnier_p Exp")
00017 
00018 #if !defined (__ACE_INLINE__)
00019 # include "tao/MProfile.i"
00020 #endif /* __ACE_INLINE__ */
00021 
00022 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00023 
00024 TAO_MProfile::~TAO_MProfile (void)
00025 {
00026   if (this->policy_list_ != 0)
00027     {
00028       ACE_DECLARE_NEW_CORBA_ENV;
00029       const CORBA::ULong len = this->policy_list_->length ();
00030       for (CORBA::ULong i = 0; i < len; ++i)
00031         {
00032           ACE_TRY
00033             {
00034               CORBA::Policy_ptr policy = (*this->policy_list_)[i];
00035               policy->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00036               ACE_TRY_CHECK;
00037             }
00038           ACE_CATCHANY
00039             {
00040               // Ignore all exceptions to allow other policies to be
00041               // destroyed.
00042             }
00043           ACE_ENDTRY;
00044         }
00045 
00046       delete this->policy_list_;
00047     }
00048 
00049   this->cleanup ();
00050 }
00051 
00052 void
00053 TAO_MProfile::cleanup (void)
00054 {
00055   if (this->pfiles_ != 0)
00056     {
00057       for (TAO_PHandle i = 0; i < this->last_; ++i)
00058         if (this->pfiles_[i])
00059           this->pfiles_[i]->_decr_refcnt ();
00060       delete [] this->pfiles_;
00061       this->pfiles_ = 0;
00062     }
00063 
00064   this->current_ = 0;
00065   this->size_ = 0;
00066   this->last_ = 0;
00067 }
00068 
00069 int
00070 TAO_MProfile::set (CORBA::ULong sz)
00071 {
00072   if (sz == 0)
00073     {
00074       this->cleanup ();
00075       return 0;
00076     }
00077 
00078   // See if we already have an existing profile list or if we need to
00079   // get ridof what we have.
00080   if (this->size_ != 0)
00081     {
00082       // Release all of our profiles.
00083 
00084       for (TAO_PHandle h = 0;
00085            h < this->size_;
00086            ++h)
00087         if (this->pfiles_[h])
00088           {
00089             this->pfiles_[h]->_decr_refcnt ();
00090             this->pfiles_[h] = 0;
00091           }
00092 
00093       // Next see if we can reuse our profile list memory
00094       if (this->size_ < sz)
00095         {
00096           // we cant reuse memory since the current array is too small!
00097           delete [] this->pfiles_;
00098 
00099           ACE_NEW_RETURN (this->pfiles_,
00100                           TAO_Profile *[sz],
00101                           -1);
00102           this->size_ = sz;
00103         }
00104       // else , leave this->size and this->pfiles alone!
00105     }
00106   else
00107     {
00108       // first time, initialize!
00109       ACE_NEW_RETURN (this->pfiles_,
00110                       TAO_Profile *[sz],
00111                       -1);
00112       this->size_ = sz;
00113     }
00114 
00115   this->last_ = 0;
00116   this->current_ = 0;
00117 
00118   for (TAO_PHandle i = 0; i != this->size_; ++i)
00119     this->pfiles_[i] = 0;
00120 
00121   return this->size_;
00122 }
00123 
00124 int
00125 TAO_MProfile::set (const TAO_MProfile &mprofile)
00126 {
00127   // NOTE: We use mprofile->last_ instead of mprofile->size_ to set
00128   // this->size_.  This is so we can use set () to trim a profile
00129   // list!!
00130 
00131   this->set (mprofile.last_);
00132 
00133   // set indexes ...
00134   this->last_ = mprofile.last_;
00135 
00136   // These are set in set (ULong);
00137   // this->current_ = 0;
00138   // this->forward_from_ = 0;
00139 
00140   // Now reference all profiles.
00141   for (TAO_PHandle h = 0; h < this->last_; ++h)
00142     {
00143       this->pfiles_[h] = mprofile.pfiles_[h];
00144       if (this->pfiles_[h] != 0)
00145         this->pfiles_[h]->_incr_refcnt ();
00146     }
00147 
00148   return 1;
00149 }
00150 
00151 // Not thread safe!
00152 int
00153 TAO_MProfile::grow (CORBA::ULong sz)
00154 {
00155   if (sz <= this->size_)
00156     return 0;
00157 
00158   // get the additional space
00159   TAO_Profile **new_pfiles = 0;
00160   TAO_Profile **old_pfiles = 0;
00161   ACE_NEW_RETURN (new_pfiles,
00162                   TAO_Profile *[sz],
00163                   -1);
00164 
00165   old_pfiles = this->pfiles_;
00166 
00167   // got it, now copy profiles
00168   for (TAO_PHandle h = 0; h < this->size_; ++h)
00169     {
00170       new_pfiles[h] = old_pfiles[h];
00171       old_pfiles[h] = 0;
00172     }
00173 
00174   this->pfiles_ = new_pfiles;
00175   this->size_ = sz;
00176   delete [] old_pfiles;
00177 
00178   return 0;
00179 }
00180 
00181 int
00182 TAO_MProfile::add_profile (TAO_Profile *pfile)
00183 {
00184   // skip by the used slots
00185   if (last_ == size_) // full!
00186     {
00187       if (this->grow (this->size_ + 1) < 0)
00188         return -1;
00189     }
00190 
00191   pfiles_[last_++] = pfile;
00192 
00193   if (pfile && pfile->_incr_refcnt () == 0)
00194     ACE_ERROR_RETURN ((LM_ERROR,
00195                        ACE_TEXT ("(%P|%t) Unable to increment reference ")
00196                        ACE_TEXT ("count in add_profile!\n")),
00197                       -1);
00198 
00199   return last_ - 1;
00200 }
00201 
00202 int
00203 TAO_MProfile::add_profiles (TAO_MProfile *pfiles)
00204 {
00205   // this->size_ == total number of profiles we can hold
00206   // this->last_ == the index of the last profile
00207   CORBA::ULong space = this->size_ - this->last_;
00208 
00209   if (space < pfiles->last_)
00210     {
00211       // we need to grow!
00212      if (this->grow (this->last_ + pfiles->last_) < 0)
00213        return -1;
00214     }
00215 
00216   // copy over profiles
00217   for (TAO_PHandle h = 0; h < pfiles->last_; ++h)
00218     {
00219       if (this->add_profile (pfiles->pfiles_[h]) < 0)
00220         return -1;
00221     }
00222   return 0;
00223 }
00224 
00225 
00226 // the layout for a full list of 7 Profiles.
00227 //
00228 // last_ == one past the last valid entry, so if the list has 2
00229 //          profiles then last_ equals 2.
00230 // current_ == index of the next profile to be returned (or one past
00231 //             the last returned.
00232 //
00233 // this->size_ = 7; current_ = 3; last_ = 7
00234 //   0, 1, 2, 3, 4, 5, 6}
00235 // { _, _, _, _, ..., _}
00236 //
00237 int
00238 TAO_MProfile::remove_profile (const TAO_Profile *pfile)
00239 {
00240   TAO_PHandle h;
00241   int found = 0;
00242   for (h = 0; h < this->last_; ++h)
00243     {
00244       if (this->pfiles_[h]->is_equivalent (pfile))
00245         { // remove it!
00246           TAO_Profile *old = this->pfiles_[h];
00247           this->pfiles_[h] = 0;
00248           old->_decr_refcnt ();
00249           // shift other profiles up one
00250           // note, if h == last_ - 1 then do nothing.
00251           for (TAO_PHandle inner = h; inner < this->last_ - 1; ++inner)
00252             {
00253               this->pfiles_[inner] = this->pfiles_[inner + 1];
00254             }
00255           // subtract 1 from last_ to indicate we have one fewer profiles
00256           this->last_--;
00257           found = 1;
00258           break;
00259         }
00260     }
00261   if ( found == 0)
00262     return -1; // profile not found.
00263   return 0;
00264 }
00265 
00266 int
00267 TAO_MProfile::remove_profiles (const TAO_MProfile *pfiles)
00268 {
00269   for (TAO_PHandle h = 0; h < pfiles->last_; ++h)
00270     {
00271       if (this->remove_profile (pfiles->pfiles_[h]) < 0)
00272         return -1;
00273     }
00274   return 0;
00275 }
00276 
00277 CORBA::Boolean
00278 TAO_MProfile::is_equivalent (const TAO_MProfile *rhs)
00279 {
00280   // Two profile lists are equivalent iff at least one of the profiles
00281   // from the first list is_equivalent to at least one of the profiles
00282   // from the second list!!
00283   for (TAO_PHandle h1 = 0; h1 < this->last_; ++h1)
00284     for (TAO_PHandle h2 = 0; h2 < rhs->last_; ++h2)
00285       if (this->pfiles_[h1]->is_equivalent (rhs->pfiles_[h2]))
00286         return 1;
00287 
00288   return 0;
00289 }
00290 
00291 CORBA::ULong
00292 TAO_MProfile::hash (CORBA::ULong max
00293                     ACE_ENV_ARG_DECL)
00294 {
00295   CORBA::ULong hashval = 0;
00296 
00297   if (this->last_ == 0)
00298     return 0;
00299 
00300   for (TAO_PHandle h = 0; h < this->last_ ; ++h)
00301     {
00302       hashval += pfiles_[h]->hash (max
00303                                    ACE_ENV_ARG_PARAMETER);
00304       ACE_CHECK_RETURN (0);
00305     }
00306 
00307   // The above hash function return an ULong between 0 and max here we
00308   // simply take the average value and round.
00309   //return hashval / this->last_;
00310   // Changed to a mod value instead of an average.
00311   return hashval % max;
00312 }
00313 
00314 void
00315 TAO_MProfile::create_policy_list (ACE_ENV_SINGLE_ARG_DECL)
00316 {
00317   ACE_NEW_THROW_EX (this->policy_list_,
00318                     CORBA::PolicyList,
00319                     CORBA::NO_MEMORY (0,
00320                                       CORBA::COMPLETED_NO)
00321                     );
00322 }
00323 
00324 void
00325 TAO_MProfile::init_policy_list (ACE_ENV_SINGLE_ARG_DECL)
00326 {
00327   // The first time this method is called
00328   // it causes the initialization of the policies
00329   // for the current profile.
00330 
00331   this->get_current_profile ()->get_policies (*this->policy_list_
00332                                               ACE_ENV_ARG_PARAMETER);
00333   ACE_CHECK;
00334 
00335   this->is_policy_list_initialized_ = 1;
00336 }
00337 
00338 CORBA::PolicyList *
00339 TAO_MProfile::policy_list (ACE_ENV_SINGLE_ARG_DECL)
00340 {
00341   if (!this->is_policy_list_initialized_)
00342     {
00343       ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX,
00344                         guard,
00345                         this->mutex_,
00346                         0);
00347 
00348       if (this->policy_list_ == 0)
00349         {
00350           this->create_policy_list (ACE_ENV_SINGLE_ARG_PARAMETER);
00351           ACE_CHECK_RETURN (0);
00352 
00353           this->init_policy_list (ACE_ENV_SINGLE_ARG_PARAMETER);
00354           ACE_CHECK_RETURN (0);
00355         }
00356     }
00357   CORBA::PolicyList *ret_val = 0;
00358   ACE_NEW_THROW_EX (ret_val,
00359                     CORBA::PolicyList (*this->policy_list_),
00360                     CORBA::NO_MEMORY (0,
00361                                       CORBA::COMPLETED_NO));
00362   ACE_CHECK_RETURN (0);
00363 
00364   return ret_val;
00365 }
00366 
00367 int
00368 TAO_MProfile::give_shared_profile (TAO_Profile *pfile)
00369 {
00370   for (unsigned i = 0; i < this->last_; i++)
00371     if (pfile->tag() == this->pfiles_[i]->tag() &&
00372         pfile->compare_key(this->pfiles_[i]))
00373       {
00374         this->pfiles_[i]->add_generic_endpoint(pfile->endpoint());
00375         pfile->_decr_refcnt();
00376         return i;
00377       }
00378   return this->give_profile(pfile,0);
00379 }
00380 
00381 
00382 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 11:54:16 2006 for TAO by doxygen 1.3.6