00001
00002
00003 #include "ace/Service_Config.h"
00004
00005 #if !defined (__ACE_INLINE__)
00006 #include "ace/Service_Config.inl"
00007 #endif
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
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
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
00070 ACE_Sig_Adapter *ACE_Service_Config::signal_handler_ = 0;
00071
00072
00073 sig_atomic_t ACE_Service_Config::reconfig_occurred_ = 0;
00074
00075
00076
00077
00078 ACE_TCHAR *ACE_Service_Config::pid_file_name_ = 0;
00079
00080
00081 int ACE_Service_Config::be_a_daemon_ = 0;
00082
00083
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
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);
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
00116
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
00128 break;
00129 }
00130 }
00131
00132 return ACE_Service_Gestalt::parse_args_i (argc, argv);
00133
00134 }
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
00155
00156
00157
00158
00159 if (this->is_opened_ != 0)
00160 return 0;
00161
00162
00163
00164
00165
00166 this->no_static_svcs_ = ignore_static_svcs;
00167
00168
00169 if (this->be_a_daemon_)
00170 ACE::daemonize ();
00171
00172
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
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
00197
00198
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
00214
00215 ACE_Service_Repository::instance (ACE_Service_Config::MAX_SERVICES);
00216
00217
00218
00219 ACE_Reactor::instance ();
00220
00221
00222
00223 #if !defined (ACE_LACKS_UNIX_SIGNALS)
00224
00225
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
00236 }
00237
00238 if (result == -1)
00239 return -1;
00240
00241 if (this->init_svc_conf_file_queue () == -1)
00242 return -1;
00243
00244
00245
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
00259
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
00280
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
00297
00298
00299
00300
00301
00302
00303
00304 ACE_Service_Config::TSS_Service_Gestalt_Ptr *& ACE_Service_Config::impl_ (void)
00305 {
00306
00307
00308
00309
00310
00311
00312
00313
00314 static TSS_Service_Gestalt_Ptr *instance_ = 0;
00315
00316 return instance_;
00317 }
00318
00319
00320
00321
00322
00323
00324 ACE_Service_Gestalt *
00325 ACE_Service_Config::current (void)
00326 {
00327
00328 if (ACE_Service_Config::impl_ () != 0)
00329 {
00330
00331
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
00340
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
00347
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
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
00369
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
00384
00385
00386
00387
00388
00389
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
00406
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
00416
00417
00418
00419
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
00429
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
00439
00440
00441
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
00451
00452 ACE_Service_Config::signum_ = signum;
00453
00454
00455
00456
00457
00458
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
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
00488
00489
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
00531
00532 ACE_ERROR ((LM_ERROR,
00533 ACE_LIB_TEXT ("(%P|%t) SC failed to open: %p\n"),
00534 program_name));
00535 }
00536 }
00537
00538
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
00548 ACE_ASSERT (ACE_Service_Config::signum_ == sig);
00549 #endif
00550
00551 ACE_Service_Config::reconfig_occurred_ = 1;
00552 }
00553
00554
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
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
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
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
00616
00617 ACE_Service_Config::~ACE_Service_Config (void)
00618 {
00619 ACE_TRACE ("ACE_Service_Config::~ACE_Service_Config");
00620 }
00621
00622
00623
00624
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