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