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 81388 2008-04-23 14:02:05Z 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 bool ACE_Service_Repository::delete_svc_rep_ = false;
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_ = true;
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_ = false;
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_ = false;
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 = 0;
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
00142 if (this->service_vector_ == 0)
00143 return 0;
00144
00145 int retval = 0;
00146
00147
00148
00149
00150 for (size_t i = this->current_size_; i-- != 0; )
00151 {
00152
00153 ACE_Service_Type *s =
00154 const_cast<ACE_Service_Type *> (this->service_vector_[i]);
00155
00156 #ifndef ACE_NLOGGING
00157 if (ACE::debug ())
00158 {
00159 if (s != 0)
00160 ACE_DEBUG ((LM_DEBUG,
00161 ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d), ")
00162 ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"),
00163 this,
00164 i,
00165 this->total_size_,
00166 s->name(),
00167 s->type (),
00168 (s->type () != 0) ? s->type ()->object () : 0,
00169 s->active ()));
00170 else
00171 ACE_DEBUG ((LM_DEBUG,
00172 ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d) -> 0\n"),
00173 this,
00174 i,
00175 this->total_size_));
00176 }
00177 #endif
00178
00179
00180 if (s != 0)
00181 retval += s->fini ();
00182 }
00183
00184 return (retval == 0) ? 0 : -1;
00185 }
00186
00187
00188
00189 int
00190 ACE_Service_Repository::close (void)
00191 {
00192 ACE_TRACE ("ACE_Service_Repository::close");
00193 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00194
00195 if (this->service_vector_ == 0)
00196 return 0;
00197
00198 #ifndef ACE_NLOGGING
00199 if(ACE::debug ())
00200 ACE_DEBUG ((LM_DEBUG,
00201 ACE_TEXT ("(%P|%t) SR::close - repo=%@, size=%d\n"),
00202 this,
00203 this->current_size_));
00204 #endif
00205
00206
00207
00208 for (size_t i = this->current_size_; i-- != 0; )
00209 {
00210
00211 ACE_Service_Type *s =
00212 const_cast<ACE_Service_Type *> (this->service_vector_[i]);
00213
00214 #ifndef ACE_NLOGGING
00215 if(ACE::debug ())
00216 {
00217 if (s == 0)
00218 ACE_DEBUG ((LM_DEBUG,
00219 ACE_TEXT ("(%P|%t) SR::close - repo=%@ [%d] -> 0\n"),
00220 this,
00221 i));
00222 else
00223 ACE_DEBUG ((LM_DEBUG,
00224 ACE_TEXT ("(%P|%t) SR::close - repo=%@ [%d], name=%s, object=%@\n"),
00225 this,
00226 i,
00227 s->name (),
00228 s));
00229 }
00230 #endif
00231 --this->current_size_;
00232 delete s;
00233 }
00234
00235 delete [] this->service_vector_;
00236 this->service_vector_ = 0;
00237 this->current_size_ = 0;
00238
00239 return 0;
00240 }
00241
00242 ACE_Service_Repository::~ACE_Service_Repository (void)
00243 {
00244 ACE_TRACE ("ACE_Service_Repository::~ACE_Service_Repository");
00245 #ifndef ACE_NLOGGING
00246 if(ACE::debug ())
00247 ACE_DEBUG ((LM_DEBUG, "(%P|%t) SR::<dtor>, this=%@\n", this));
00248 #endif
00249 this->close ();
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259 int
00260 ACE_Service_Repository::find_i (const ACE_TCHAR name[],
00261 size_t &slot,
00262 const ACE_Service_Type **srp,
00263 bool ignore_suspended) const
00264 {
00265 ACE_TRACE ("ACE_Service_Repository::find_i");
00266 size_t i;
00267
00268 for (i = 0; i < this->current_size_; i++)
00269 {
00270 if (this->service_vector_[i] != 0
00271 && ACE_OS::strcmp (name,
00272 this->service_vector_[i]->name ()) == 0)
00273 break;
00274 }
00275
00276 if (i < this->current_size_)
00277 {
00278 slot = i;
00279 if (this->service_vector_[i]->fini_called ())
00280 {
00281 if (srp != 0)
00282 *srp = 0;
00283 return -1;
00284 }
00285
00286 if (srp != 0)
00287 *srp = this->service_vector_[i];
00288
00289 if (ignore_suspended
00290 && this->service_vector_[i]->active () == 0)
00291 return -2;
00292
00293 return 0;
00294 }
00295
00296 return -1;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 int
00308 ACE_Service_Repository::relocate_i (size_t begin,
00309 size_t end,
00310 const ACE_DLL& adll)
00311 {
00312 ACE_SHLIB_HANDLE new_handle = adll.get_handle (0);
00313
00314 for (size_t i = begin; i < end; i++)
00315 {
00316 ACE_Service_Type *type =
00317 const_cast<ACE_Service_Type *> (this->service_vector_[i]);
00318
00319 ACE_SHLIB_HANDLE old_handle = (type == 0) ? ACE_SHLIB_INVALID_HANDLE
00320 : type->dll ().get_handle (0);
00321
00322 #ifndef ACE_NLOGGING
00323 if (ACE::debug ())
00324 {
00325 if (type == 0)
00326 ACE_DEBUG ((LM_DEBUG,
00327 ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d] (size=%d)")
00328 ACE_TEXT (": skipping empty slot\n"),
00329 this,
00330 i,
00331 this->total_size_));
00332 else
00333 ACE_DEBUG ((LM_DEBUG,
00334 ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d] (size=%d)")
00335 ACE_TEXT (": trying name=%s, handle: %d -> %d\n"),
00336 this,
00337 i,
00338 this->total_size_,
00339 type->name (),
00340 old_handle,
00341 new_handle));
00342 }
00343 #endif
00344
00345 if (type != 0
00346 && old_handle == ACE_SHLIB_INVALID_HANDLE
00347 && new_handle != old_handle)
00348 {
00349 #ifndef ACE_NLOGGING
00350 if (ACE::debug ())
00351 ACE_DEBUG ((LM_DEBUG,
00352 ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d] (size=%d)")
00353 ACE_TEXT (": relocating name=%s, handle: %d -> %d\n"),
00354 this,
00355 i,
00356 this->total_size_,
00357 type->name (),
00358 old_handle,
00359 new_handle));
00360 #endif
00361 type->dll (adll);
00362 }
00363 }
00364
00365 return 0;
00366 }
00367
00368 int
00369 ACE_Service_Repository::find (const ACE_TCHAR name[],
00370 const ACE_Service_Type **srp,
00371 bool ignore_suspended) const
00372 {
00373 ACE_TRACE ("ACE_Service_Repository::find");
00374 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00375 size_t ignore_location = 0;
00376 return this->find_i (name, ignore_location, srp, ignore_suspended);
00377 }
00378
00379
00380
00381
00382
00383
00384 int
00385 ACE_Service_Repository::insert (const ACE_Service_Type *sr)
00386 {
00387 ACE_TRACE ("ACE_Service_Repository::insert");
00388
00389 size_t i = 0;
00390 int return_value = -1;
00391 ACE_Service_Type const *s = 0;
00392
00393
00394
00395 {
00396
00397 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00398 ace_mon,
00399 this->lock_,
00400 -1));
00401
00402 return_value = find_i (sr->name (), i, &s, false);
00403
00404
00405 if (s != 0)
00406 {
00407 this->service_vector_[i] = sr;
00408 }
00409 else
00410 {
00411
00412
00413
00414
00415
00416
00417 if (i < this->current_size_)
00418 i = this->current_size_;
00419
00420 if (i < this->total_size_)
00421 {
00422 this->service_vector_[i] = sr;
00423 this->current_size_++;
00424 return_value = 0;
00425 }
00426 else
00427 {
00428 return_value = -1;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438 }
00439 }
00440 #ifndef ACE_NLOGGING
00441 if (ACE::debug ())
00442 ACE_DEBUG ((LM_DEBUG,
00443 ACE_TEXT ("ACE (%P|%t) SR::insert - repo=%@ [%d] (%d),")
00444 ACE_TEXT (" name=%s (%s) (type=%@, object=%@, active=%d)\n"),
00445 this,
00446 i,
00447 this->total_size_,
00448 sr->name(),
00449 (return_value == 0 ? ((s==0) ? "new" : "replacing") : "failed"),
00450 sr->type (),
00451 (sr->type () != 0) ? sr->type ()->object () : 0,
00452 sr->active ()));
00453 #endif
00454
00455
00456
00457 delete s;
00458
00459 if (return_value == -1)
00460 ACE_OS::last_error (ENOSPC);
00461
00462 return return_value;
00463 }
00464
00465
00466 int
00467 ACE_Service_Repository::resume (const ACE_TCHAR name[],
00468 const ACE_Service_Type **srp)
00469 {
00470 ACE_TRACE ("ACE_Service_Repository::resume");
00471 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00472
00473 size_t i = 0;
00474 if (-1 == this->find_i (name, i, srp, 0))
00475 return -1;
00476
00477 return this->service_vector_[i]->resume ();
00478 }
00479
00480
00481
00482
00483 int
00484 ACE_Service_Repository::suspend (const ACE_TCHAR name[],
00485 const ACE_Service_Type **srp)
00486 {
00487 ACE_TRACE ("ACE_Service_Repository::suspend");
00488 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00489 size_t i = 0;
00490 if (-1 == this->find_i (name, i, srp, 0))
00491 return -1;
00492
00493 return this->service_vector_[i]->suspend ();
00494 }
00495
00496
00497
00498
00499
00500
00501
00502 int
00503 ACE_Service_Repository::remove (const ACE_TCHAR name[], ACE_Service_Type **ps)
00504 {
00505 ACE_TRACE ("ACE_Service_Repository::remove");
00506 ACE_Service_Type *s = 0;
00507 {
00508 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00509
00510
00511 if (this->remove_i (name, &s) == -1)
00512 return -1;
00513 }
00514
00515 if (ps != 0)
00516 *ps = s;
00517 else
00518 delete s;
00519 return 0;
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 int
00543 ACE_Service_Repository::remove_i (const ACE_TCHAR name[], ACE_Service_Type **ps)
00544 {
00545 size_t i = 0;
00546 if (-1 == this->find_i (name, i, 0, false))
00547 return -1;
00548
00549
00550 *ps = const_cast<ACE_Service_Type *> (this->service_vector_[i]);
00551
00552 #ifndef ACE_NLOGGING
00553 if (ACE::debug ())
00554 ACE_DEBUG ((LM_DEBUG,
00555 ACE_TEXT ("ACE (%P|%t) SR::remove_i - repo=%@ [%d] (%d),")
00556 ACE_TEXT (" name=%s (removed) (type=%@, active=%d)\n"),
00557 this,
00558 i,
00559 this->total_size_,
00560 name,
00561 *ps,
00562 (*ps)->active ()));
00563 #endif
00564
00565 this->service_vector_[i] = 0;
00566 return 0;
00567 }
00568
00569 ACE_ALLOC_HOOK_DEFINE(ACE_Service_Repository_Iterator)
00570
00571 void
00572 ACE_Service_Repository_Iterator::dump (void) const
00573 {
00574 #if defined (ACE_HAS_DUMP)
00575 ACE_TRACE ("ACE_Service_Repository_Iterator::dump");
00576 #endif
00577 }
00578
00579
00580
00581
00582
00583
00584 ACE_Service_Repository_Iterator::ACE_Service_Repository_Iterator
00585 (ACE_Service_Repository &sr, int ignr_suspended)
00586 : svc_rep_ (sr),
00587 next_ (0),
00588 ignore_suspended_ (ignr_suspended)
00589 {
00590 while (!(done() || valid()))
00591 this->next_++;
00592 }
00593
00594
00595
00596
00597 int
00598 ACE_Service_Repository_Iterator::next (const ACE_Service_Type *&sr)
00599 {
00600 ACE_TRACE ("ACE_Service_Repository_Iterator::next");
00601
00602 if (done ())
00603 return 0;
00604
00605 sr = this->svc_rep_.service_vector_[this->next_];
00606 return 1;
00607 }
00608
00609
00610
00611
00612
00613
00614 int
00615 ACE_Service_Repository_Iterator::advance (void)
00616 {
00617 ACE_TRACE ("ACE_Service_Repository_Iterator::advance");
00618
00619 if (done()) return 0;
00620
00621 do this->next_++; while (!(done () || valid ()));
00622
00623 return !done();
00624 }
00625
00626 bool
00627 ACE_Service_Repository_Iterator::valid (void) const
00628 {
00629 ACE_TRACE ("ACE_Service_Repository_Iterator::valid");
00630 if (!this->ignore_suspended_)
00631 return (this->svc_rep_.service_vector_[this->next_] != 0);
00632
00633 return (this->svc_rep_.service_vector_[this->next_] != 0
00634 && this->svc_rep_.service_vector_[this->next_]->active ());
00635 }
00636
00637 ACE_END_VERSIONED_NAMESPACE_DECL