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 90337 2010-05-28 20:00:49Z cbeaulac $")
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 *
00041 ACE_Service_Repository::instance (size_t size)
00042 {
00043 ACE_TRACE ("ACE_Service_Repository::instance");
00044
00045 if (ACE_Service_Repository::svc_rep_ == 0)
00046 {
00047
00048 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00049 *ACE_Static_Object_Lock::instance (), 0));
00050 if (ACE_Service_Repository::svc_rep_ == 0)
00051 {
00052 if (ACE_Object_Manager::starting_up () ||
00053 !ACE_Object_Manager::shutting_down ())
00054 {
00055 ACE_NEW_RETURN (ACE_Service_Repository::svc_rep_,
00056 ACE_Service_Repository (size),
00057 0);
00058 ACE_Service_Repository::delete_svc_rep_ = true;
00059 }
00060 }
00061 }
00062
00063 return ACE_Service_Repository::svc_rep_;
00064 }
00065
00066 ACE_Service_Repository *
00067 ACE_Service_Repository::instance (ACE_Service_Repository *s)
00068 {
00069 ACE_TRACE ("ACE_Service_Repository::instance");
00070 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00071 *ACE_Static_Object_Lock::instance (), 0));
00072
00073 ACE_Service_Repository *t = ACE_Service_Repository::svc_rep_;
00074
00075 ACE_Service_Repository::delete_svc_rep_ = false;
00076
00077 ACE_Service_Repository::svc_rep_ = s;
00078 return t;
00079 }
00080
00081 void
00082 ACE_Service_Repository::close_singleton (void)
00083 {
00084 ACE_TRACE ("ACE_Service_Repository::close_singleton");
00085
00086 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00087 *ACE_Static_Object_Lock::instance ()));
00088
00089 if (ACE_Service_Repository::delete_svc_rep_)
00090 {
00091 delete ACE_Service_Repository::svc_rep_;
00092 ACE_Service_Repository::svc_rep_ = 0;
00093 ACE_Service_Repository::delete_svc_rep_ = false;
00094 }
00095 }
00096
00097
00098 int
00099 ACE_Service_Repository::open (size_t size)
00100 {
00101 ACE_TRACE ("ACE_Service_Repository::open");
00102
00103
00104 array_type local_array (size);
00105 this->service_array_.swap (local_array);
00106
00107 return 0;
00108 }
00109
00110 ACE_Service_Repository::ACE_Service_Repository (size_t size)
00111 : service_array_ (size)
00112 {
00113 ACE_TRACE ("ACE_Service_Repository::ACE_Service_Repository");
00114 }
00115
00116
00117
00118
00119 int
00120 ACE_Service_Repository::fini (void)
00121 {
00122 ACE_TRACE ("ACE_Service_Repository::fini");
00123 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00124
00125 int retval = 0;
00126
00127
00128
00129
00130
00131 #ifndef ACE_NLOGGING
00132 if (ACE::debug ())
00133 {
00134 for (size_t i = this->service_array_.size (); i-- != 0;)
00135 {
00136 ACE_Service_Type *s =
00137 const_cast<ACE_Service_Type *> (this->service_array_[i]);
00138 if (s == 0)
00139 ACE_DEBUG ((LM_DEBUG,
00140 ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] -> 0\n"),
00141 this,
00142 i));
00143 }
00144 }
00145 #endif
00146
00147
00148
00149 for (size_t i = this->service_array_.size (); i-- != 0;)
00150 {
00151
00152 ACE_Service_Type *s =
00153 const_cast<ACE_Service_Type *> (this->service_array_[i]);
00154
00155 if (s != 0 &&
00156 s->type () != 0 &&
00157 (s->type ()->service_type () != ACE_Service_Type::MODULE))
00158 {
00159 #ifndef ACE_NLOGGING
00160 if (ACE::debug ())
00161 {
00162 ACE_DEBUG ((LM_DEBUG,
00163 ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ")
00164 ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"),
00165 this,
00166 i,
00167 s->name (),
00168 s->type (),
00169 (s->type () != 0) ? s->type ()->object () : 0,
00170 s->active ()));
00171 }
00172 #endif
00173
00174
00175 retval += s->fini ();
00176 }
00177 }
00178
00179
00180
00181 for (size_t i = this->service_array_.size (); i-- != 0;)
00182 {
00183
00184 ACE_Service_Type *s =
00185 const_cast<ACE_Service_Type *> (this->service_array_[i]);
00186
00187 if (s != 0 &&
00188 s->type () != 0 &&
00189 (s->type ()->service_type () == ACE_Service_Type::MODULE))
00190 {
00191 #ifndef ACE_NLOGGING
00192 if (ACE::debug ())
00193 {
00194 ACE_DEBUG ((LM_DEBUG,
00195 ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ")
00196 ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"),
00197 this,
00198 i,
00199 s->name (),
00200 s->type (),
00201 (s->type () != 0) ? s->type ()->object () : 0,
00202 s->active ()));
00203 }
00204 #endif
00205
00206 retval += s->fini ();
00207 }
00208 }
00209 return (retval == 0) ? 0 : -1;
00210 }
00211
00212
00213
00214 int
00215 ACE_Service_Repository::close (void)
00216 {
00217 ACE_TRACE ("ACE_Service_Repository::close");
00218 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00219
00220 #ifndef ACE_NLOGGING
00221 if(ACE::debug ())
00222 ACE_DEBUG ((LM_DEBUG,
00223 ACE_TEXT ("ACE (%P|%t) SR::close - repo=%@, size=%d\n"),
00224 this,
00225 this->service_array_.size()));
00226 #endif
00227
00228
00229
00230 for (size_t i = this->service_array_.size(); i-- != 0; )
00231 {
00232
00233 ACE_Service_Type *s =
00234 const_cast<ACE_Service_Type *> (this->service_array_[i]);
00235
00236 #ifndef ACE_NLOGGING
00237 if(ACE::debug ())
00238 {
00239 if (s == 0)
00240 ACE_DEBUG ((LM_DEBUG,
00241 ACE_TEXT ("ACE (%P|%t) SR::close - repo=%@ [%d] -> 0\n"),
00242 this,
00243 i));
00244 else
00245 ACE_DEBUG ((LM_DEBUG,
00246 ACE_TEXT ("ACE (%P|%t) SR::close - repo=%@ [%d], name=%s, object=%@\n"),
00247 this,
00248 i,
00249 s->name (),
00250 s));
00251 }
00252 #endif
00253 delete s;
00254 }
00255
00256 this->service_array_.clear ();
00257
00258 return 0;
00259 }
00260
00261 ACE_Service_Repository::~ACE_Service_Repository (void)
00262 {
00263 ACE_TRACE ("ACE_Service_Repository::~ACE_Service_Repository");
00264 #ifndef ACE_NLOGGING
00265 if(ACE::debug ())
00266 ACE_DEBUG ((LM_DEBUG, "ACE (%P|%t) SR::<dtor>, this=%@\n", this));
00267 #endif
00268 this->close ();
00269 }
00270
00271
00272
00273
00274
00275
00276
00277 int
00278 ACE_Service_Repository::find_i (const ACE_TCHAR name[],
00279 size_t &slot,
00280 const ACE_Service_Type **srp,
00281 bool ignore_suspended) const
00282 {
00283 ACE_TRACE ("ACE_Service_Repository::find_i");
00284 size_t i = 0;
00285 array_type::const_iterator element = this->service_array_.end ();
00286
00287 for (i = 0; i < this->service_array_.size(); i++)
00288 {
00289 array_type::const_iterator iter = this->service_array_.find (i);
00290 if (iter != this->service_array_.end ()
00291 && (*iter).second != 0
00292 && ACE_OS::strcmp (name, (*iter).second->name ()) == 0)
00293 {
00294 element = iter;
00295 break;
00296 }
00297 }
00298
00299 if (element != this->service_array_.end ())
00300 {
00301 slot = i;
00302 if ((*element).second->fini_called ())
00303 {
00304 if (srp != 0)
00305 *srp = 0;
00306 return -1;
00307 }
00308
00309 if (srp != 0)
00310 *srp = (*element).second;
00311
00312 if (ignore_suspended
00313 && (*element).second->active () == 0)
00314 return -2;
00315
00316 return 0;
00317 }
00318
00319 return -1;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329 int
00330 ACE_Service_Repository::relocate_i (size_t begin,
00331 size_t end,
00332 const ACE_DLL& adll)
00333 {
00334 ACE_SHLIB_HANDLE new_handle = adll.get_handle (0);
00335
00336 for (size_t i = begin; i < end; i++)
00337 {
00338 ACE_Service_Type *type =
00339 const_cast<ACE_Service_Type *> (this->service_array_[i]);
00340
00341 ACE_SHLIB_HANDLE old_handle = (type == 0) ? ACE_SHLIB_INVALID_HANDLE
00342 : type->dll ().get_handle (0);
00343
00344 #ifndef ACE_NLOGGING
00345 if (ACE::debug ())
00346 {
00347 if (type == 0)
00348 ACE_DEBUG ((LM_DEBUG,
00349 ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d]")
00350 ACE_TEXT (": skipping empty slot\n"),
00351 this,
00352 i));
00353 else
00354 ACE_DEBUG ((LM_DEBUG,
00355 ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d]")
00356 ACE_TEXT (": trying name=%s, handle: %d -> %d\n"),
00357 this,
00358 i,
00359 type->name (),
00360 old_handle,
00361 new_handle));
00362 }
00363 #endif
00364
00365 if (type != 0
00366 && old_handle == ACE_SHLIB_INVALID_HANDLE
00367 && new_handle != old_handle)
00368 {
00369 #ifndef ACE_NLOGGING
00370 if (ACE::debug ())
00371 ACE_DEBUG ((LM_DEBUG,
00372 ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d]")
00373 ACE_TEXT (": relocating name=%s, handle: %d -> %d\n"),
00374 this,
00375 i,
00376 type->name (),
00377 old_handle,
00378 new_handle));
00379 #endif
00380 type->dll (adll);
00381 }
00382 }
00383
00384 return 0;
00385 }
00386
00387 int
00388 ACE_Service_Repository::find (const ACE_TCHAR name[],
00389 const ACE_Service_Type **srp,
00390 bool ignore_suspended) const
00391 {
00392 ACE_TRACE ("ACE_Service_Repository::find");
00393 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00394 size_t ignore_location = 0;
00395 return this->find_i (name, ignore_location, srp, ignore_suspended);
00396 }
00397
00398
00399
00400
00401
00402 int
00403 ACE_Service_Repository::insert (const ACE_Service_Type *sr)
00404 {
00405 ACE_TRACE ("ACE_Service_Repository::insert");
00406
00407 size_t i = 0;
00408 int return_value = -1;
00409 ACE_Service_Type const *s = 0;
00410
00411
00412
00413 {
00414
00415 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00416 ace_mon,
00417 this->lock_,
00418 -1));
00419
00420 return_value = find_i (sr->name (), i, &s, false);
00421
00422
00423 if (s != 0)
00424 {
00425 this->service_array_[i] = sr;
00426 }
00427 else
00428 {
00429
00430
00431
00432
00433
00434
00435 if (i < this->service_array_.size ())
00436 i = this->service_array_.size ();
00437
00438 this->service_array_[i] = sr;
00439 return_value = 0;
00440 }
00441 }
00442 #ifndef ACE_NLOGGING
00443 if (ACE::debug ())
00444 ACE_DEBUG ((LM_DEBUG,
00445 ACE_TEXT ("ACE (%P|%t) SR::insert - repo=%@ [%d],")
00446 ACE_TEXT (" name=%s (%C) (type=%@, object=%@, active=%d)\n"),
00447 this,
00448 i,
00449 sr->name(),
00450 (return_value == 0 ? ((s==0) ? "new" : "replacing") : "failed"),
00451 sr->type (),
00452 (sr->type () != 0) ? sr->type ()->object () : 0,
00453 sr->active ()));
00454 #endif
00455
00456
00457
00458 delete s;
00459
00460 if (return_value == -1)
00461 ACE_OS::last_error (ENOSPC);
00462
00463 return return_value;
00464 }
00465
00466
00467 int
00468 ACE_Service_Repository::resume (const ACE_TCHAR name[],
00469 const ACE_Service_Type **srp)
00470 {
00471 ACE_TRACE ("ACE_Service_Repository::resume");
00472 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00473
00474 size_t i = 0;
00475 if (-1 == this->find_i (name, i, srp, 0))
00476 return -1;
00477
00478 return this->service_array_[i]->resume ();
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_array_[i]->suspend ();
00494 }
00495
00496
00497
00498
00499
00500 int
00501 ACE_Service_Repository::remove (const ACE_TCHAR name[], ACE_Service_Type **ps)
00502 {
00503 ACE_TRACE ("ACE_Service_Repository::remove");
00504 ACE_Service_Type *s = 0;
00505 {
00506 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00507
00508
00509 if (this->remove_i (name, &s) == -1)
00510 return -1;
00511 }
00512
00513 if (ps != 0)
00514 *ps = s;
00515 else
00516 delete s;
00517 return 0;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 int
00541 ACE_Service_Repository::remove_i (const ACE_TCHAR name[], ACE_Service_Type **ps)
00542 {
00543 size_t i = 0;
00544 if (-1 == this->find_i (name, i, 0, false))
00545 return -1;
00546
00547
00548 *ps = const_cast<ACE_Service_Type *> (this->service_array_[i]);
00549
00550 #ifndef ACE_NLOGGING
00551 if (ACE::debug ())
00552 ACE_DEBUG ((LM_DEBUG,
00553 ACE_TEXT ("ACE (%P|%t) SR::remove_i - repo=%@ [%d],")
00554 ACE_TEXT (" name=%s (removed) (type=%@, active=%d)\n"),
00555 this,
00556 i,
00557 name,
00558 *ps,
00559 (*ps)->active ()));
00560 #endif
00561
00562 this->service_array_[i] = 0;
00563 return 0;
00564 }
00565
00566 ACE_ALLOC_HOOK_DEFINE(ACE_Service_Repository_Iterator)
00567
00568 void
00569 ACE_Service_Repository_Iterator::dump (void) const
00570 {
00571 #if defined (ACE_HAS_DUMP)
00572 ACE_TRACE ("ACE_Service_Repository_Iterator::dump");
00573 #endif
00574 }
00575
00576
00577
00578
00579 ACE_Service_Repository_Iterator::ACE_Service_Repository_Iterator
00580 (ACE_Service_Repository &sr, bool ignored_suspended)
00581 : svc_rep_ (sr),
00582 next_ (0),
00583 ignore_suspended_ (ignored_suspended)
00584 {
00585 while (!(done() || valid()))
00586 this->next_++;
00587 }
00588
00589
00590
00591 int
00592 ACE_Service_Repository_Iterator::next (const ACE_Service_Type *&sr)
00593 {
00594 ACE_TRACE ("ACE_Service_Repository_Iterator::next");
00595
00596 if (done ())
00597 return 0;
00598
00599 sr = this->svc_rep_.service_array_[this->next_];
00600 return 1;
00601 }
00602
00603
00604
00605
00606
00607 int
00608 ACE_Service_Repository_Iterator::advance (void)
00609 {
00610 ACE_TRACE ("ACE_Service_Repository_Iterator::advance");
00611
00612 if (done()) return 0;
00613
00614 do this->next_++; while (!(done () || valid ()));
00615
00616 return !done();
00617 }
00618
00619 bool
00620 ACE_Service_Repository_Iterator::valid (void) const
00621 {
00622 ACE_TRACE ("ACE_Service_Repository_Iterator::valid");
00623 if (!this->ignore_suspended_)
00624 return (this->svc_rep_.service_array_[this->next_] != 0);
00625
00626 return (this->svc_rep_.service_array_[this->next_] != 0
00627 && this->svc_rep_.service_array_[this->next_]->active ());
00628 }
00629
00630 ACE_END_VERSIONED_NAMESPACE_DECL