MProfile.cpp

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

Generated on Tue Feb 2 17:37:52 2010 for TAO by  doxygen 1.4.7