00001 
00002 
00003 #include "ace/Service_Repository.h"
00004 
00005 #if !defined (__ACE_INLINE__)
00006 #include "ace/Service_Repository.inl"
00007 #endif 
00008 
00009 #include "ace/Service_Types.h"
00010 #include "ace/Object_Manager.h"
00011 #include "ace/Log_Msg.h"
00012 #include "ace/ACE.h"
00013 #include "ace/OS_NS_unistd.h"
00014 #include "ace/OS_NS_errno.h"
00015 #include "ace/OS_NS_string.h"
00016 
00017 ACE_RCSID (ace,
00018            Service_Repository,
00019            "$Id: Service_Repository.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00020 
00021   ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00022 
00023 ACE_ALLOC_HOOK_DEFINE(ACE_Service_Repository)
00024 
00025 
00026 ACE_Service_Repository *ACE_Service_Repository::svc_rep_ = 0;
00027 
00028 
00029 
00030 int ACE_Service_Repository::delete_svc_rep_ = 0;
00031 
00032 void
00033 ACE_Service_Repository::dump (void) const
00034 {
00035 #if defined (ACE_HAS_DUMP)
00036   ACE_TRACE ("ACE_Service_Repository::dump");
00037 #endif 
00038 }
00039 
00040 ACE_Service_Repository::ACE_Service_Repository (void)
00041   : service_vector_ (0),
00042     current_size_ (0),
00043     total_size_ (0)
00044 {
00045   ACE_TRACE ("ACE_Service_Repository::ACE_Service_Repository");
00046 }
00047 
00048 ACE_Service_Repository *
00049 ACE_Service_Repository::instance (size_t size )
00050 {
00051   ACE_TRACE ("ACE_Service_Repository::instance");
00052 
00053   if (ACE_Service_Repository::svc_rep_ == 0)
00054     {
00055       
00056       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00057                                 *ACE_Static_Object_Lock::instance (), 0));
00058       if (ACE_Service_Repository::svc_rep_ == 0)
00059         {
00060           if (ACE_Object_Manager::starting_up () ||
00061               !ACE_Object_Manager::shutting_down ())
00062             {
00063               ACE_NEW_RETURN (ACE_Service_Repository::svc_rep_,
00064                               ACE_Service_Repository (size),
00065                               0);
00066               ACE_Service_Repository::delete_svc_rep_ = 1;
00067             }
00068         }
00069     }
00070 
00071   return ACE_Service_Repository::svc_rep_;
00072 }
00073 
00074 ACE_Service_Repository *
00075 ACE_Service_Repository::instance (ACE_Service_Repository *s)
00076 {
00077   ACE_TRACE ("ACE_Service_Repository::instance");
00078   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00079                             *ACE_Static_Object_Lock::instance (), 0));
00080 
00081   ACE_Service_Repository *t = ACE_Service_Repository::svc_rep_;
00082   
00083   ACE_Service_Repository::delete_svc_rep_ = 0;
00084 
00085   ACE_Service_Repository::svc_rep_ = s;
00086   return t;
00087 }
00088 
00089 void
00090 ACE_Service_Repository::close_singleton (void)
00091 {
00092   ACE_TRACE ("ACE_Service_Repository::close_singleton");
00093 
00094   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00095                      *ACE_Static_Object_Lock::instance ()));
00096 
00097   if (ACE_Service_Repository::delete_svc_rep_)
00098     {
00099       delete ACE_Service_Repository::svc_rep_;
00100       ACE_Service_Repository::svc_rep_ = 0;
00101       ACE_Service_Repository::delete_svc_rep_ = 0;
00102     }
00103 }
00104 
00105 
00106 
00107 int
00108 ACE_Service_Repository::open (size_t size)
00109 {
00110   ACE_TRACE ("ACE_Service_Repository::open");
00111 
00112   ACE_Service_Type **temp;
00113 
00114   ACE_NEW_RETURN (temp,
00115                   ACE_Service_Type *[size],
00116                   -1);
00117 
00118   this->service_vector_ = const_cast<const ACE_Service_Type **> (temp);
00119   this->total_size_ = size;
00120   return 0;
00121 }
00122 
00123 ACE_Service_Repository::ACE_Service_Repository (size_t size)
00124   : current_size_ (0)
00125 {
00126   ACE_TRACE ("ACE_Service_Repository::ACE_Service_Repository");
00127 
00128   if (this->open (size) == -1)
00129     ACE_ERROR ((LM_ERROR,
00130                 ACE_TEXT ("%p\n"),
00131                 ACE_TEXT ("ACE_Service_Repository")));
00132 }
00133 
00134 
00135 
00136 int
00137 ACE_Service_Repository::fini (void)
00138 {
00139   ACE_TRACE ("ACE_Service_Repository::fini");
00140   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00141   int retval = 0;
00142 
00143   if (this->service_vector_ != 0)
00144     {
00145       
00146       
00147       
00148       
00149       
00150       
00151 
00152       
00153       
00154       
00155       for (size_t i = this->current_size_; i-- != 0; )
00156         {
00157           ACE_Service_Type *s =
00158             const_cast<ACE_Service_Type *> (this->service_vector_[i]);
00159 
00160 #ifndef ACE_NLOGGING
00161           if (ACE::debug ())
00162               ACE_DEBUG ((LM_DEBUG,
00163                           ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d), ")
00164                           ACE_TEXT ("name=%s, type=%@, impl=%@, object=%@, active=%d\n"),
00165                           this, i, this->total_size_, s->name(), s->type (),
00166                           (s->type () != 0) ? s->type ()->object () : 0,
00167                           s->active ()));
00168 #endif
00169 
00170           
00171           int ret = s->fini ();
00172           retval += ret;
00173         }
00174     }
00175 
00176   return (retval == 0) ? 0 : -1;
00177 }
00178 
00179 
00180 
00181 int
00182 ACE_Service_Repository::close (void)
00183 {
00184   ACE_TRACE ("ACE_Service_Repository::close");
00185   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00186 
00187   if (this->service_vector_ != 0)
00188     {
00189       
00190       
00191       
00192       
00193       
00194 
00195 #ifndef ACE_NLOGGING
00196       if(ACE::debug ())
00197         ACE_DEBUG ((LM_DEBUG,
00198                     ACE_TEXT ("(%P|%t) SR::close, this=%@, size=%d\n"),
00199                     this,
00200                     this->current_size_));
00201 #endif
00202 
00203       
00204       
00205       
00206       for (size_t i = this->current_size_; i-- != 0; )
00207         {
00208 
00209 #ifndef ACE_NLOGGING
00210           if(ACE::debug ())
00211             ACE_DEBUG ((LM_DEBUG,
00212                         ACE_TEXT ("(%P|%t) SR::close, this=%@, delete so[%d]=%@ (%s)\n"),
00213                         this, i,
00214                         this->service_vector_[i],
00215                         this->service_vector_[i]->name ()));
00216 #endif
00217 
00218           ACE_Service_Type *s = const_cast<ACE_Service_Type *> (this->service_vector_[i]);
00219           --this->current_size_;
00220           delete s;
00221         }
00222 
00223       delete [] this->service_vector_;
00224       this->service_vector_ = 0;
00225       this->current_size_ = 0;
00226     }
00227 
00228   return 0;
00229 }
00230 
00231 ACE_Service_Repository::~ACE_Service_Repository (void)
00232 {
00233   ACE_TRACE ("ACE_Service_Repository::~ACE_Service_Repository");
00234 #ifndef ACE_NLOGGING
00235   if(ACE::debug ())
00236     ACE_DEBUG ((LM_DEBUG, "(%P|%t) SR::<dtor>, this=%@\n", this));
00237 #endif
00238   this->close ();
00239 }
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 int
00249 ACE_Service_Repository::find_i (const ACE_TCHAR name[],
00250                                 size_t &slot,
00251                                 const ACE_Service_Type **srp,
00252                                 bool ignore_suspended) const
00253 {
00254   ACE_TRACE ("ACE_Service_Repository::find_i");
00255   size_t i;
00256 
00257   for (i = 0; i < this->current_size_; i++)
00258     if (ACE_OS::strcmp (name,
00259                         this->service_vector_[i]->name ()) == 0)
00260       break;
00261 
00262   if (i < this->current_size_)
00263     {
00264       slot = i;
00265       if (this->service_vector_[i]->fini_called ())
00266         {
00267           if (srp != 0)
00268             *srp = 0;
00269           return -1;
00270         }
00271 
00272       if (srp != 0)
00273         *srp = this->service_vector_[i];
00274       if (ignore_suspended
00275           && this->service_vector_[i]->active () == 0)
00276         return -2;
00277       return 0;
00278     }
00279   else
00280     return -1;
00281 }
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 int
00292 ACE_Service_Repository::relocate_i (size_t begin,
00293                                     size_t end,
00294                                     const ACE_DLL& adll,
00295                                     bool static_only)
00296 {
00297   ACE_SHLIB_HANDLE new_handle = adll.get_handle (0);
00298 
00299   for (size_t i = begin; i < end; i++)
00300     {
00301       ACE_Service_Type *type =
00302         const_cast<ACE_Service_Type *> (this->service_vector_[i]);
00303 
00304       ACE_SHLIB_HANDLE old_handle =  type->dll ().get_handle (0);
00305       if (static_only && old_handle != ACE_SHLIB_INVALID_HANDLE)
00306         continue;
00307 
00308 #ifndef ACE_NLOGGING
00309     if (ACE::debug ())
00310         ACE_DEBUG ((LM_DEBUG,
00311                     ACE_TEXT ("ACE (%P|%t) SR::relocate, repo=%@ [%d] (size=%d): name=%s - DLL from=%d to=%d\n"),
00312                     this, i, this->total_size_, type->name (),
00313                     old_handle,
00314                     new_handle));
00315 #else
00316   ACE_UNUSED_ARG (new_handle);
00317 #endif
00318       type->dll (adll);
00319     }
00320 
00321   return 0;
00322 }
00323 
00324 int
00325 ACE_Service_Repository::find (const ACE_TCHAR name[],
00326                               const ACE_Service_Type **srp,
00327                               bool ignore_suspended) const
00328 {
00329   ACE_TRACE ("ACE_Service_Repository::find");
00330   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00331   size_t ignore_location = 0;
00332   return this->find_i (name, ignore_location, srp, ignore_suspended);
00333 }
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 int
00342 ACE_Service_Repository::insert (const ACE_Service_Type *sr)
00343 {
00344   ACE_TRACE ("ACE_Service_Repository::insert");
00345 
00346   int return_value = -1;
00347   ACE_Service_Type *s = 0;
00348   size_t i = 0;
00349 
00350   {
00351     
00352     ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00353 
00354     
00355     for (i = 0; i < this->current_size_; i++)
00356       if (ACE_OS::strcmp (sr->name (),
00357                           this->service_vector_[i]->name ()) == 0)
00358         break;
00359 
00360     
00361     if (i < this->current_size_)
00362       {
00363         return_value = 0;
00364         
00365         if (sr != this->service_vector_[i])
00366           {
00367             s = const_cast<ACE_Service_Type *> (this->service_vector_[i]);
00368             this->service_vector_[i] = sr;
00369           }
00370       }
00371     
00372     else if (i < this->total_size_)
00373       {
00374         this->service_vector_[i] = sr;
00375         this->current_size_++;
00376         return_value = 0;
00377       }
00378 
00379 #ifndef ACE_NLOGGING
00380     if (ACE::debug ())
00381       ACE_DEBUG ((LM_DEBUG,
00382                   ACE_TEXT ("ACE (%P|%t) SR::insert")
00383                   ACE_TEXT (" - repo=%@ [%d] (%d), name=%s")
00384                   ACE_TEXT (", type=%@, object=%@, active=%d\n"),
00385                   this, i, this->total_size_, sr->name(), sr->type (),
00386                   (sr->type () != 0) ? sr->type ()->object () : 0,
00387                   sr->active ()));
00388 #endif
00389   }
00390 
00391   
00392   if (s != 0)
00393     {
00394 #ifndef ACE_NLOGGING
00395       if (ACE::debug ())
00396         ACE_DEBUG ((LM_DEBUG,
00397                     ACE_TEXT ("ACE (%P|%t) SR::insert")
00398                     ACE_TEXT (" - destroying (replacing), repo=%@ [%d] (%d), name=%s")
00399                     ACE_TEXT (", type=%@, object=%@, active=%d\n"),
00400                     this, i, this->total_size_, s->name(), s->type (),
00401                     (s->type () != 0) ? s->type ()->object () : 0,
00402                     s->active ()));
00403 #endif
00404       delete s;
00405     }
00406 
00407   if (return_value == -1)
00408     ACE_OS::last_error (ENOSPC);
00409 
00410   return return_value;
00411 }
00412 
00413 
00414 
00415 int
00416 ACE_Service_Repository::resume (const ACE_TCHAR name[],
00417                                 const ACE_Service_Type **srp)
00418 {
00419   ACE_TRACE ("ACE_Service_Repository::resume");
00420   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00421 
00422   size_t i = 0;
00423   if (-1 == this->find_i (name, i, srp, 0))
00424     return -1;
00425 
00426   return this->service_vector_[i]->resume ();
00427 }
00428 
00429 
00430 
00431 
00432 int
00433 ACE_Service_Repository::suspend (const ACE_TCHAR name[],
00434                                  const ACE_Service_Type **srp)
00435 {
00436   ACE_TRACE ("ACE_Service_Repository::suspend");
00437   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00438   size_t i = 0;
00439   if (-1 == this->find_i (name, i, srp, 0))
00440     return -1;
00441 
00442   return this->service_vector_[i]->suspend ();
00443 }
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 int
00452 ACE_Service_Repository::remove (const ACE_TCHAR name[], ACE_Service_Type **ps)
00453 {
00454   ACE_TRACE ("ACE_Service_Repository::remove");
00455   ACE_Service_Type *s = 0;
00456   {
00457     ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00458 
00459     
00460     if (this->remove_i (name, &s) == -1)
00461       return -1;
00462   }
00463 
00464   if (ps != 0)
00465     *ps = s;
00466   else
00467     delete s;
00468   return 0;
00469 }
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494 int
00495 ACE_Service_Repository::remove_i (const ACE_TCHAR name[], ACE_Service_Type **ps)
00496 {
00497   size_t i = 0;
00498   if (-1 == this->find_i (name, i, 0, false))
00499     return -1;    
00500 
00501   
00502   *ps = const_cast<ACE_Service_Type *> (this->service_vector_[i]);
00503 
00504   
00505   --this->current_size_;
00506   for (size_t j = i; j < this->current_size_; j++)
00507     this->service_vector_[j] = this->service_vector_[j+1];
00508 
00509   return 0;
00510 }
00511 
00512 ACE_ALLOC_HOOK_DEFINE(ACE_Service_Repository_Iterator)
00513 
00514 void
00515 ACE_Service_Repository_Iterator::dump (void) const
00516 {
00517 #if defined (ACE_HAS_DUMP)
00518   ACE_TRACE ("ACE_Service_Repository_Iterator::dump");
00519 #endif 
00520 }
00521 
00522 
00523 
00524 
00525 
00526 
00527 ACE_Service_Repository_Iterator::ACE_Service_Repository_Iterator
00528   (ACE_Service_Repository &sr, int ignr_suspended)
00529   : svc_rep_ (sr),
00530     next_ (0),
00531     ignore_suspended_ (ignr_suspended)
00532 {
00533   while (!(done() || valid()))
00534     this->next_++;
00535 }
00536 
00537 
00538 
00539 
00540 int
00541 ACE_Service_Repository_Iterator::next (const ACE_Service_Type *&sr)
00542 {
00543   ACE_TRACE ("ACE_Service_Repository_Iterator::next");
00544 
00545   if (done ())
00546     return 0;
00547 
00548   sr = this->svc_rep_.service_vector_[this->next_];
00549   return 1;
00550 }
00551 
00552 
00553 
00554 
00555 
00556 
00557 int
00558 ACE_Service_Repository_Iterator::advance (void)
00559 {
00560   ACE_TRACE ("ACE_Service_Repository_Iterator::advance");
00561 
00562   if (done()) return 0;
00563 
00564   do this->next_++; while (!(done () || valid ()));
00565 
00566   return !done();
00567 }
00568 
00569 bool
00570 ACE_Service_Repository_Iterator::valid (void) const
00571 {
00572   ACE_TRACE ("ACE_Service_Repository_Iterator::valid");
00573   return (this->ignore_suspended_ == 0
00574           || this->svc_rep_.service_vector_[this->next_]->active ());
00575 }
00576 
00577 ACE_END_VERSIONED_NAMESPACE_DECL