Service_Config.cpp

Go to the documentation of this file.
00001 // Service_Config.cpp,v 4.189 2006/06/20 12:40:38 jwillemsen Exp
00002 
00003 #include "ace/Service_Config.h"
00004 
00005 #if !defined (__ACE_INLINE__)
00006 #include "ace/Service_Config.inl"
00007 #endif /* __ACE_INLINE__ */
00008 
00009 #include "ace/ACE.h"
00010 #include "ace/Guard_T.h"
00011 #include "ace/Log_Msg.h"
00012 #include "ace/Service_Types.h"
00013 #include "ace/Reactor.h"
00014 #include "ace/Signal.h"
00015 #include "ace/OS_NS_stdio.h"
00016 #include "ace/OS_NS_time.h"
00017 #include "ace/OS_NS_unistd.h"
00018 #include "ace/Get_Opt.h"
00019 #include "ace/Service_Config.h"
00020 #include "ace/Static_Object_Lock.h"
00021 #if defined (ACE_OPENVMS)
00022 # include "ace/Lib_Find.h"
00023 #endif
00024 
00025 ACE_RCSID (ace,
00026            Service_Config,
00027            "Service_Config.cpp,v 4.189 2006/06/20 12:40:38 jwillemsen Exp")
00028 
00029   ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00030 
00031 #if defined (ACE_OPENVMS)
00032 ACE_Static_Svc_Registrar::ACE_Static_Svc_Registrar (const ACE_TCHAR* alloc_name,
00033                                                     ACE_SERVICE_ALLOCATOR alloc)
00034 {
00035   // register service allocator function by full name in ACE singleton registry
00036   ACE::ldregister (alloc_name, (void*)alloc);
00037 }
00038 #endif
00039 
00040 ///
00041 ACE_Service_Config_Guard::ACE_Service_Config_Guard (ACE_Service_Gestalt * psg)
00042   : saved_ (ACE_Service_Config::current ())
00043 {
00044   if (ACE::debug ())
00045     ACE_DEBUG ((LM_DEBUG,
00046                 ACE_LIB_TEXT ("(%P|%t) SCG::ctor, repo=%@ - guard with %@\n"),
00047                 this->saved_->repo_,
00048                 psg->repo_));
00049 
00050   // Modify the TSS - no locking needed
00051   if (saved_ != psg)
00052       (void)ACE_Service_Config::current (psg);
00053 }
00054 
00055 ///
00056 ACE_Service_Config_Guard::~ACE_Service_Config_Guard (void)
00057 {
00058   ACE_Service_Config::current (this->saved_);
00059 
00060   if (ACE::debug ())
00061     ACE_DEBUG ((LM_DEBUG,
00062                 ACE_LIB_TEXT ("(%P|%t) SCG::dtor, repo=%@ - un-guard\n"),
00063                 this->saved_->repo_));
00064 }
00065 
00066 
00067 ACE_ALLOC_HOOK_DEFINE (ACE_Service_Config)
00068 
00069 // Set the signal handler to point to the handle_signal() function.
00070 ACE_Sig_Adapter *ACE_Service_Config::signal_handler_ = 0;
00071 
00072 // Trigger a reconfiguration.
00073 sig_atomic_t ACE_Service_Config::reconfig_occurred_ = 0;
00074 
00075 // = Set by command-line options.
00076 
00077 /// Pathname of file to write process id.
00078 ACE_TCHAR *ACE_Service_Config::pid_file_name_ = 0;
00079 
00080 /// Shall we become a daemon process?
00081 int ACE_Service_Config::be_a_daemon_ = 0;
00082 
00083 // Number of the signal used to trigger reconfiguration.
00084 int ACE_Service_Config::signum_ = SIGHUP;
00085 
00086 
00087 void
00088 ACE_Service_Config::dump (void) const
00089 {
00090 #if defined (ACE_HAS_DUMP)
00091   ACE_TRACE ("ACE_Service_Config::dump");
00092 #endif /* ACE_HAS_DUMP */
00093 }
00094 
00095 int
00096 ACE_Service_Config::parse_args_i (int argc, ACE_TCHAR *argv[])
00097 {
00098   ACE_TRACE ("ACE_Service_Config::parse_args_i");
00099   ACE_Get_Opt getopt (argc,
00100                       argv,
00101                       ACE_LIB_TEXT ("bs:p:"),
00102                       1); // Start at argv[1].
00103 
00104   for (int c; (c = getopt ()) != -1; )
00105     switch (c)
00106       {
00107       case 'p':
00108         ACE_Service_Config::pid_file_name_ = getopt.opt_arg ();
00109         break;
00110       case 'b':
00111         ACE_Service_Config::be_a_daemon_ = 1;
00112         break;
00113       case 's':
00114         {
00115           // There's no point in dealing with this on NT since it
00116           // doesn't really support signals very well...
00117 #if !defined (ACE_LACKS_UNIX_SIGNALS)
00118           ACE_Service_Config::signum_ =
00119             ACE_OS::atoi (getopt.opt_arg ());
00120 
00121           if (ACE_Reactor::instance ()->register_handler
00122               (ACE_Service_Config::signum_,
00123                ACE_Service_Config::signal_handler_) == -1)
00124             ACE_ERROR_RETURN ((LM_ERROR,
00125                                ACE_LIB_TEXT ("cannot obtain signal handler\n")),
00126                               -1);
00127 #endif /* ACE_LACKS_UNIX_SIGNALS */
00128           break;
00129         }
00130       }
00131 
00132   return ACE_Service_Gestalt::parse_args_i (argc, argv);
00133 
00134 } /* parse_args_i () */
00135 
00136 
00137 int
00138 ACE_Service_Config::open_i (const ACE_TCHAR program_name[],
00139                             const ACE_TCHAR *logger_key,
00140                             bool ignore_static_svcs,
00141                             bool ignore_default_svc_conf_file,
00142                             bool ignore_debug_flag)
00143 {
00144   int result = 0;
00145   ACE_TRACE ("ACE_Service_Config::open_i");
00146   ACE_Log_Msg *log_msg = ACE_LOG_MSG;
00147 
00148   if (ACE::debug ())
00149     ACE_DEBUG ((LM_DEBUG,
00150                 ACE_TEXT ("(%P|%t) SC::open_i - this=%@, opened=%d, ")
00151                 ACE_TEXT ("loadstatics=%d\n"),
00152                 this, this->is_opened_, this->no_static_svcs_));
00153 
00154   // Guard against reentrant processing. For example,
00155   // if the singleton gestalt (ubergestalt) was already open,
00156   // do not open it again...
00157   // The base class open_i increments this and we are
00158   // forwarding to it, so we don't have to increment here.
00159   if (this->is_opened_ != 0)
00160     return 0;
00161 
00162   // Check for things we need to do on a per-process basis and which
00163   // may not be safe, or wise to do an a per instance basis
00164 
00165   // Override any defaults, if required
00166   this->no_static_svcs_ = ignore_static_svcs;
00167 
00168   // Become a daemon before doing anything else.
00169   if (this->be_a_daemon_)
00170     ACE::daemonize ();
00171 
00172   // Write process id to file.
00173   if (this->pid_file_name_ != 0)
00174     {
00175       FILE* pidf = ACE_OS::fopen (this->pid_file_name_,
00176                                   ACE_LIB_TEXT("w"));
00177 
00178       if (pidf != 0)
00179         {
00180           ACE_OS::fprintf (pidf,
00181                            "%ld\n",
00182                            static_cast<long> (ACE_OS::getpid()));
00183           ACE_OS::fclose (pidf);
00184         }
00185     }
00186 
00187   u_long flags = log_msg->flags ();
00188 
00189   // Only use STDERR if the caller hasn't already set the flags.
00190   if (flags == 0)
00191     flags = (u_long) ACE_Log_Msg::STDERR;
00192 
00193   const ACE_TCHAR *key = logger_key;
00194 
00195   if (key == 0 || ACE_OS::strcmp (key, ACE_DEFAULT_LOGGER_KEY) == 0)
00196     // Only use the static <logger_key_> if the caller doesn't
00197     // override it in the parameter list or if the key supplied is
00198     // equal to the default static logger key.
00199     key = this->logger_key_;
00200   else
00201     ACE_SET_BITS (flags, ACE_Log_Msg::LOGGER);
00202 
00203   if (log_msg->open (program_name,
00204                      flags,
00205                      key) == -1)
00206     result = -1;
00207   else
00208     {
00209       if (ACE::debug ())
00210         ACE_DEBUG ((LM_STARTUP,
00211                     ACE_LIB_TEXT ("starting up daemon %n\n")));
00212 
00213       // Initialize the Service Repository (this will still work if
00214       // user forgets to define an object of type ACE_Service_Config).
00215       ACE_Service_Repository::instance (ACE_Service_Config::MAX_SERVICES);
00216 
00217       // Initialize the ACE_Reactor (the ACE_Reactor should be the
00218       // same size as the ACE_Service_Repository).
00219       ACE_Reactor::instance ();
00220 
00221       // There's no point in dealing with this on NT since it doesn't
00222       // really support signals very well...
00223 #if !defined (ACE_LACKS_UNIX_SIGNALS)
00224       // Only attempt to register a signal handler for positive
00225       // signal numbers.
00226       if (ACE_Service_Config::signum_ > 0)
00227         {
00228           ACE_Sig_Set ss;
00229           ss.sig_add (ACE_Service_Config::signum_);
00230           if (ACE_Reactor::instance ()->register_handler
00231               (ss, ACE_Service_Config::signal_handler_) == -1)
00232             ACE_ERROR ((LM_ERROR,
00233                         ACE_LIB_TEXT ("can't register signal handler\n")));
00234         }
00235 #endif /* ACE_LACKS_UNIX_SIGNALS */
00236     }
00237 
00238   if (result == -1)
00239     return -1;
00240 
00241   if (this->init_svc_conf_file_queue () == -1)
00242     return -1;
00243 
00244   // Check if the default file exists before attempting to queue it
00245   // for processing
00246   if (!ignore_default_svc_conf_file)
00247     {
00248       FILE *fp = ACE_OS::fopen (ACE_DEFAULT_SVC_CONF,
00249                                 ACE_LIB_TEXT ("r"));
00250       ignore_default_svc_conf_file = (fp == 0);
00251       if (fp != 0)
00252         ACE_OS::fclose (fp);
00253     }
00254 
00255   if (!ignore_default_svc_conf_file
00256       && this->svc_conf_file_queue_->is_empty ())
00257     {
00258       // Load the default "svc.conf" entry here if there weren't
00259       // overriding -f arguments in <parse_args>.
00260       if (this->svc_conf_file_queue_->enqueue_tail
00261           (ACE_TString (ACE_DEFAULT_SVC_CONF)) == -1)
00262         {
00263           ACE_ERROR_RETURN ((LM_ERROR,
00264                              ACE_LIB_TEXT ("%p\n"),
00265                              ACE_LIB_TEXT ("enqueuing ")
00266                              ACE_DEFAULT_SVC_CONF
00267                              ACE_LIB_TEXT(" file")),
00268                             -1);
00269         }
00270     }
00271 
00272   return ACE_Service_Gestalt::open_i (program_name,
00273                                       logger_key,
00274                                       ignore_static_svcs,
00275                                       ignore_default_svc_conf_file,
00276                                       ignore_debug_flag);
00277 }
00278 
00279 /// Return the global configuration instance. Allways returns the same
00280 /// instance
00281 ACE_Service_Gestalt *
00282 ACE_Service_Config::global (void)
00283 {
00284   return ACE_Singleton<ACE_Service_Config, ACE_SYNCH_MUTEX>::instance ();
00285 }
00286 
00287 
00288 ///
00289 ACE_Service_Gestalt *
00290 ACE_Service_Config::instance (void)
00291 {
00292   return  ACE_Service_Config::current ();
00293 }
00294 
00295 
00296 // A thread-specific storage to keep a pointer to the (current) global
00297 // configuration. Using a pointer to avoid the order of initialization
00298 // debacle possible when using static class instances. The memory is
00299 // dynamicaly allocated and leaked from current()
00300 
00301 /// Provides access to the static ptr, containing the TSS
00302 /// accessor. Ensures the desired order of initialization, even when
00303 /// other static initializers need the value.
00304 ACE_Service_Config::TSS_Service_Gestalt_Ptr *& ACE_Service_Config::impl_ (void)
00305 {
00306   /// A "straight" static ptr does not work in static builds, because
00307   /// some static initializer may call current() method and assign
00308   /// value to instance_ *before* the startup code has had a chance to
00309   /// initialize it . This results in instance_ being "zeroed" out
00310   /// after it was assigned the correct value. Having a method scoped
00311   /// static guarantees that the first time the method is invoked, the
00312   /// instance_ will be initialized before returning.
00313 
00314   static TSS_Service_Gestalt_Ptr *instance_ = 0;
00315 
00316   return instance_;
00317 }
00318 
00319 /// Return the configuration instance, considered "global" in the
00320 /// current thread. This may be the same as instance(), but on some
00321 /// occasions, it may be a different one. For example,
00322 /// ACE_Service_Config_Guard provides a way of temporarily replacing
00323 /// the "current" configuration instance in the context of a thread.
00324 ACE_Service_Gestalt *
00325 ACE_Service_Config::current (void)
00326 {
00327 
00328   if (ACE_Service_Config::impl_ () != 0)
00329     {
00330       // TSS already initialized, but a new thread may need its own
00331       // ptr to the process-wide gestalt.
00332       if (ACE_TSS_GET (ACE_Service_Config::impl_ (), TSS_Resources)->ptr_ == 0)
00333         return current_i (global ());
00334 
00335       return ACE_TSS_GET (ACE_Service_Config::impl_ (), TSS_Resources)->ptr_;
00336     }
00337   else
00338     {
00339       // TSS not initialized yet - first thread to hit this, so doing
00340       // the double-checked locking thing
00341       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00342                                 *ACE_Static_Object_Lock::instance (), 0));
00343 
00344       if (ACE_Service_Config::impl_ () != 0)
00345         {
00346           // Another thread snuck in and initialized the TSS, but we
00347           // still need ow own ptr to the process-wide gestalt.
00348           if (ACE_TSS_GET (ACE_Service_Config::impl_ (), TSS_Resources)->ptr_ == 0)
00349             return current_i (global ());
00350 
00351           return ACE_TSS_GET (ACE_Service_Config::impl_ (), TSS_Resources)->ptr_;
00352         }
00353 
00354       return current_i (global ());
00355     }
00356 }
00357 
00358 /// A mutator to set the "current" (TSS) gestalt instance.
00359 ACE_Service_Gestalt*
00360 ACE_Service_Config::current (ACE_Service_Gestalt *newcurrent)
00361 {
00362    ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00363                              *ACE_Static_Object_Lock::instance (), 0));
00364 
00365   return current_i (newcurrent);
00366 }
00367 
00368 /// A private, non-locking mutator to set the "current" (TSS) gestalt instance.
00369 /// Make sure to call with the proper locks held!
00370 ACE_Service_Gestalt*
00371 ACE_Service_Config::current_i (ACE_Service_Gestalt *newcurrent)
00372 {
00373   if (ACE_Service_Config::impl_ () == 0)
00374     {
00375       ACE_NEW_RETURN (ACE_Service_Config::impl_ (), TSS_Service_Gestalt_Ptr, 0);
00376     }
00377 
00378   ACE_TSS_GET (ACE_Service_Config::impl_ (), TSS_Resources)->ptr_ = newcurrent;
00379   return newcurrent;
00380 }
00381 
00382 
00383 // This method has changed to return the gestalt instead of the
00384 // container, underlying the service repository and defined
00385 // ACE_Service_Gestalt::insert (ACE_Static_Svc_Descriptor*). This way
00386 // the existing source code can keep using
00387 // ACE_Service_Config::static_svcs(), however now it is not necessary
00388 // to expose the repository storage *and* it is much easier to debug
00389 // service registration problems.
00390 
00391 ACE_Service_Gestalt *
00392 ACE_Service_Config::static_svcs (void)
00393 {
00394   return ACE_Service_Config::current ();
00395 }
00396 
00397 ///
00398 int
00399 ACE_Service_Config::insert (ACE_Static_Svc_Descriptor* stsd)
00400 {
00401   return ACE_Service_Config::current ()->insert (stsd);
00402 }
00403 
00404 
00405 // Totally remove <svc_name> from the daemon by removing it from the
00406 // ACE_Reactor, and unlinking it if necessary.
00407 
00408 int
00409 ACE_Service_Config::remove (const ACE_TCHAR svc_name[])
00410 {
00411   ACE_TRACE ("ACE_Service_Config::remove");
00412   return ACE_Service_Repository::instance ()->remove (svc_name);
00413 }
00414 
00415 // Suspend <svc_name>.  Note that this will not unlink the service
00416 // from the daemon if it was dynamically linked, it will mark it as
00417 // being suspended in the Service Repository and call the <suspend>
00418 // member function on the appropriate <ACE_Service_Object>.  A service
00419 // can be resumed later on by calling the <resume> method...
00420 
00421 int
00422 ACE_Service_Config::suspend (const ACE_TCHAR svc_name[])
00423 {
00424   ACE_TRACE ("ACE_Service_Config::suspend");
00425   return ACE_Service_Repository::instance ()->suspend (svc_name);
00426 }
00427 
00428 // Resume a SVC_NAME that was previously suspended or has not yet
00429 // been resumed (e.g., a static service).
00430 
00431 int
00432 ACE_Service_Config::resume (const ACE_TCHAR svc_name[])
00433 {
00434   ACE_TRACE ("ACE_Service_Config::resume");
00435   return ACE_Service_Repository::instance ()->resume (svc_name);
00436 }
00437 
00438 // Initialize the Service Repository.  Note that this *must* be
00439 // performed in the constructor (rather than <open>) since otherwise
00440 // the repository will not be properly initialized to allow static
00441 // configuration of services...
00442 
00443 ACE_Service_Config::ACE_Service_Config (int ignore_static_svcs,
00444                                         size_t size,
00445                                         int signum)
00446   : ACE_Service_Gestalt (size, false, ignore_static_svcs)
00447 {
00448   ACE_TRACE ("ACE_Service_Config::ACE_Service_Config");
00449 
00450   //  this->no_static_svcs_ = (ignore_static_svcs);
00451 
00452   ACE_Service_Config::signum_ = signum;
00453 
00454   // Initialize the Service Repository.
00455   //  ACE_Service_Repository::instance (static_cast<int> (size));
00456 
00457   // Initialize the ACE_Reactor (the ACE_Reactor should be the same
00458   // size as the ACE_Service_Repository).
00459   (void)ACE_Reactor::instance ();
00460 }
00461 
00462 
00463 #if (ACE_USES_CLASSIC_SVC_CONF == 0)
00464 ACE_Service_Type *
00465 ACE_Service_Config::create_service_type  (const ACE_TCHAR *n,
00466                                           ACE_Service_Type_Impl *o,
00467                                           ACE_DLL &dll,
00468                                           int active)
00469 {
00470   ACE_Service_Type *sp = 0;
00471   ACE_NEW_RETURN (sp,
00472                   ACE_Service_Type (n, o, dll, active),
00473                   0);
00474   return sp;
00475 }
00476 #endif /* ACE_USES_CLASSIC_SVC_CONF == 0 */
00477 
00478 ACE_Service_Type_Impl *
00479 ACE_Service_Config::create_service_type_impl (const ACE_TCHAR *name,
00480                                               int type,
00481                                               void *symbol,
00482                                               u_int flags,
00483                                               ACE_Service_Object_Exterminator gobbler)
00484 {
00485   ACE_Service_Type_Impl *stp = 0;
00486 
00487   // Note, the only place we need to put a case statement.  This is
00488   // also the place where we'd put the RTTI tests, if the compiler
00489   // actually supported them!
00490 
00491   switch (type)
00492     {
00493     case ACE_Service_Type::SERVICE_OBJECT:
00494       ACE_NEW_RETURN (stp,
00495                       ACE_Service_Object_Type ((ACE_Service_Object *) symbol,
00496                                                name, flags,
00497                                                gobbler),
00498                       0);
00499       break;
00500     case ACE_Service_Type::MODULE:
00501       ACE_NEW_RETURN (stp,
00502                       ACE_Module_Type (symbol, name, flags),
00503                       0);
00504       break;
00505     case ACE_Service_Type::STREAM:
00506       ACE_NEW_RETURN (stp,
00507                       ACE_Stream_Type (symbol, name, flags),
00508                       0);
00509       break;
00510     default:
00511       ACE_ERROR ((LM_ERROR,
00512                   ACE_LIB_TEXT ("unknown case\n")));
00513       break;
00514     }
00515   return stp;
00516 
00517 }
00518 
00519 
00520 ACE_Service_Config::ACE_Service_Config (const ACE_TCHAR program_name[],
00521                                         const ACE_TCHAR *logger_key)
00522   : ACE_Service_Gestalt (ACE_Service_Repository::DEFAULT_SIZE, false)
00523 {
00524   ACE_TRACE ("ACE_Service_Config::ACE_Service_Config");
00525 
00526   if (this->open (program_name,
00527                   logger_key) == -1 && errno != ENOENT)
00528     {
00529 
00530       // Only print out an error if it wasn't the svc.conf file that was
00531       // missing.
00532       ACE_ERROR ((LM_ERROR,
00533                   ACE_LIB_TEXT ("(%P|%t) SC failed to open: %p\n"),
00534                   program_name));
00535     }
00536 }
00537 
00538 // Signal handling API to trigger dynamic reconfiguration.
00539 
00540 void
00541 ACE_Service_Config::handle_signal (int sig,
00542                                    siginfo_t *,
00543                                    ucontext_t *)
00544 {
00545 #if defined (ACE_NDEBUG)
00546   ACE_UNUSED_ARG (sig);
00547 #else  /* ! ACE_NDEBUG */
00548   ACE_ASSERT (ACE_Service_Config::signum_ == sig);
00549 #endif /* ! ACE_NDEBUG */
00550 
00551   ACE_Service_Config::reconfig_occurred_ = 1;
00552 }
00553 
00554 // Trigger the reconfiguration process.
00555 
00556 void
00557 ACE_Service_Config::reconfigure (void)
00558 {
00559   ACE_TRACE ("ACE_Service_Config::reconfigure");
00560 
00561   ACE_Service_Config::reconfig_occurred_ = 0;
00562 
00563   if (ACE::debug ())
00564     {
00565 #if !defined (ACE_NLOGGING)
00566       time_t t = ACE_OS::time (0);
00567 #endif /* ! ACE_NLOGGING */
00568       if (ACE::debug ())
00569         ACE_DEBUG ((LM_DEBUG,
00570                     ACE_LIB_TEXT ("beginning reconfiguration at %s"),
00571                     ACE_OS::ctime (&t)));
00572     }
00573   if (ACE_Service_Config::process_directives () == -1)
00574     ACE_ERROR ((LM_ERROR,
00575                 ACE_LIB_TEXT ("%p\n"),
00576                 ACE_LIB_TEXT ("process_directives")));
00577 }
00578 
00579 // Tidy up and perform last rites on a terminating ACE_Service_Config.
00580 int
00581 ACE_Service_Config::close (void)
00582 {
00583   return ACE_Service_Config::current ()->close ();
00584 }
00585 
00586 int
00587 ACE_Service_Config::close_svcs (void)
00588 {
00589   ACE_TRACE ("ACE_Service_Config::close_svcs");
00590 
00591   ACE_Service_Repository::close_singleton ();
00592 
00593   return 0;
00594 }
00595 
00596 int
00597 ACE_Service_Config::fini_svcs (void)
00598 {
00599   ACE_TRACE ("ACE_Service_Config::fini_svcs");
00600 
00601   // Clear the LM_DEBUG bit from log messages if appropriate
00602   if (ACE::debug ())
00603     ACE_Log_Msg::disable_debug_messages ();
00604 
00605   int result = 0;
00606   if (ACE_Service_Repository::instance () != 0)
00607     result = ACE_Service_Repository::instance ()->fini ();
00608 
00609   if (ACE::debug ())
00610     ACE_Log_Msg::enable_debug_messages ();
00611 
00612   return result;
00613 }
00614 
00615 // Perform user-specified close activities and remove dynamic memory.
00616 
00617 ACE_Service_Config::~ACE_Service_Config (void)
00618 {
00619   ACE_TRACE ("ACE_Service_Config::~ACE_Service_Config");
00620 }
00621 
00622 // ************************************************************
00623 
00624 /* static */
00625 int
00626 ACE_Service_Config::reconfig_occurred (void)
00627 {
00628   ACE_TRACE ("ACE_Service_Config::reconfig_occurred");
00629   return ACE_Service_Config::reconfig_occurred_ != 0;
00630 }
00631 
00632 void
00633 ACE_Service_Config::reconfig_occurred (int config_occurred)
00634 {
00635   ACE_TRACE ("ACE_Service_Config::reconfig_occurred");
00636   ACE_Service_Config::reconfig_occurred_ = config_occurred;
00637 }
00638 
00639 // ************************************************************
00640 
00641 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:42:02 2006 for ACE by doxygen 1.3.6