Log_Msg.cpp

Go to the documentation of this file.
00001 // Log_Msg.cpp,v 4.330 2006/05/30 12:15:03 jwillemsen Exp
00002 
00003 // We need this to get the status of ACE_NTRACE...
00004 #include "ace/config-all.h"
00005 
00006 // Turn off tracing for the duration of this file.
00007 #if defined (ACE_NTRACE)
00008 # undef ACE_NTRACE
00009 #endif /* ACE_NTRACE */
00010 #define ACE_NTRACE 1
00011 
00012 #include "ace/ACE.h"
00013 #include "ace/Thread_Manager.h"
00014 #include "ace/Guard_T.h"
00015 #include "ace/OS_NS_stdio.h"
00016 #include "ace/OS_NS_string.h"
00017 #include "ace/OS_NS_errno.h"
00018 #include "ace/OS_NS_sys_time.h"
00019 #include "ace/OS_NS_wchar.h"
00020 #include "ace/OS_NS_signal.h"
00021 #include "ace/OS_NS_unistd.h"
00022 
00023 #if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE != 0)
00024 # include "ace/Object_Manager_Base.h"
00025 #endif /* ! ACE_MT_SAFE */
00026 
00027 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
00028 // FUZZ: disable check_for_streams_include
00029 # include "ace/streams.h"
00030 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
00031 
00032 #if defined (ACE_HAS_TRACE)
00033 # include "ace/Trace.h"
00034 #endif /* ACE_HAS_TRACE */
00035 
00036 #include "ace/Log_Msg.h"
00037 #include "ace/Log_Msg_Callback.h"
00038 #include "ace/Log_Msg_IPC.h"
00039 #include "ace/Log_Msg_NT_Event_Log.h"
00040 #include "ace/Log_Msg_UNIX_Syslog.h"
00041 #include "ace/Log_Record.h"
00042 #include "ace/Recursive_Thread_Mutex.h"
00043 
00044 ACE_RCSID(ace, Log_Msg, "Log_Msg.cpp,v 4.330 2006/05/30 12:15:03 jwillemsen Exp")
00045 
00046 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00047 
00048 ACE_ALLOC_HOOK_DEFINE(ACE_Log_Msg)
00049 
00050 // only used here...  dhinton
00051 #if defined (ACE_HAS_SYS_SIGLIST)
00052 # if !defined (_sys_siglist)
00053 #   define _sys_siglist sys_siglist
00054 # endif /* !defined (sys_siglist) */
00055 //extern char **_sys_siglist;
00056 #endif /* ACE_HAS_SYS_SIGLIST */
00057 
00058 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00059   int ACE_Log_Msg::key_created_ = 0;
00060 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
00061     defined (ACE_HAS_TSS_EMULATION)
00062 
00063 static ACE_thread_key_t the_log_msg_tss_key = 0;
00064 
00065 ACE_thread_key_t *log_msg_tss_key (void)
00066 {
00067   return &the_log_msg_tss_key;
00068 }
00069 
00070 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
00071 #endif /* ACE_MT_SAFE */
00072 
00073 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP)
00074 #  define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_NT_Event_Log
00075 #elif !defined (ACE_LACKS_UNIX_SYSLOG) && !defined (ACE_HAS_WINCE)
00076 #  define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_UNIX_Syslog
00077 #else
00078 #  define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_IPC
00079 #endif /* ! ACE_WIN32 */
00080 
00081 // When doing ACE_OS::s[n]printf() calls in log(), we need to update
00082 // the space remaining in the output buffer based on what's returned from
00083 // the output function. If we could rely on more modern compilers, this
00084 // would be in an unnamed namespace, but it's a macro instead.
00085 // count is a size_t, len is an int and assumed to be non-negative.
00086 #define ACE_UPDATE_COUNT(COUNT, LEN) \
00087    do { if (static_cast<size_t> (LEN) > COUNT) COUNT = 0; \
00088      else COUNT -= static_cast<size_t> (LEN); \
00089    } while (0)
00090 
00091 /// Instance count for Log_Msg - used to know when dynamically
00092 /// allocated storage (program name and host name) can be safely
00093 /// deleted.
00094 int ACE_Log_Msg::instance_count_ = 0;
00095 
00096 /**
00097  * @class ACE_Log_Msg_Manager
00098  *
00099  * @brief Synchronize output operations.
00100  *
00101  * Provides global point of contact for all ACE_Log_Msg instances
00102  * in a process.
00103  *
00104  * For internal use by ACE, only!
00105  */
00106 class ACE_Log_Msg_Manager
00107 {
00108 public:
00109   static ACE_Log_Msg_Backend *log_backend_;
00110   static ACE_Log_Msg_Backend *custom_backend_;
00111 
00112   static u_long log_backend_flags_;
00113 
00114   static int init_backend (const u_long *flags = 0);
00115 
00116 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00117   static void close (void);
00118 
00119   static ACE_Recursive_Thread_Mutex *get_lock (void);
00120 
00121 private:
00122   static ACE_Recursive_Thread_Mutex *lock_;
00123 #endif /* ! ACE_MT_SAFE */
00124 };
00125 
00126 ACE_Log_Msg_Backend *ACE_Log_Msg_Manager::log_backend_ = 0;
00127 ACE_Log_Msg_Backend *ACE_Log_Msg_Manager::custom_backend_ = 0;
00128 
00129 u_long ACE_Log_Msg_Manager::log_backend_flags_ = 0;
00130 
00131 int ACE_Log_Msg_Manager::init_backend (const u_long *flags)
00132 {
00133   // If flags have been supplied, and they are different from the flags
00134   // we had last time, then we may have to re-create the backend as a
00135   // different type.
00136   if (flags)
00137     {
00138       // Sanity check for custom backend.
00139       if (ACE_BIT_ENABLED (*flags, ACE_Log_Msg::CUSTOM) &&
00140           ACE_Log_Msg_Manager::custom_backend_ == 0)
00141         {
00142           return -1;
00143         }
00144 
00145       if ((ACE_BIT_ENABLED (*flags, ACE_Log_Msg::SYSLOG)
00146             && ACE_BIT_DISABLED (ACE_Log_Msg_Manager::log_backend_flags_, ACE_Log_Msg::SYSLOG))
00147           || (ACE_BIT_DISABLED (*flags, ACE_Log_Msg::SYSLOG)
00148             && ACE_BIT_ENABLED (ACE_Log_Msg_Manager::log_backend_flags_, ACE_Log_Msg::SYSLOG)))
00149         {
00150           delete ACE_Log_Msg_Manager::log_backend_;
00151           ACE_Log_Msg_Manager::log_backend_ = 0;
00152         }
00153 
00154       ACE_Log_Msg_Manager::log_backend_flags_ = *flags;
00155     }
00156 
00157   if (ACE_Log_Msg_Manager::log_backend_ == 0)
00158     {
00159       ACE_NO_HEAP_CHECK;
00160 
00161 #if (defined (WIN32) || !defined (ACE_LACKS_UNIX_SYSLOG)) && !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP)
00162       // Allocate the ACE_Log_Msg_Backend instance.
00163       if (ACE_BIT_ENABLED (ACE_Log_Msg_Manager::log_backend_flags_, ACE_Log_Msg::SYSLOG))
00164         ACE_NEW_RETURN (ACE_Log_Msg_Manager::log_backend_,
00165                         ACE_LOG_MSG_SYSLOG_BACKEND,
00166                         -1);
00167       else
00168 #endif /* defined (WIN32) && !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP) */
00169         ACE_NEW_RETURN (ACE_Log_Msg_Manager::log_backend_,
00170                         ACE_Log_Msg_IPC,
00171                         -1);
00172     }
00173 
00174   return 0;
00175 }
00176 
00177 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00178 ACE_Recursive_Thread_Mutex *ACE_Log_Msg_Manager::lock_ = 0;
00179 
00180 ACE_Recursive_Thread_Mutex *
00181 ACE_Log_Msg_Manager::get_lock (void)
00182 {
00183   // This function is called by the first thread to create an ACE_Log_Msg
00184   // instance.  It makes the call while holding a mutex, so we don't have
00185   // to grab another one here.
00186 
00187   if (ACE_Log_Msg_Manager::lock_ == 0)
00188     {
00189       ACE_NO_HEAP_CHECK;
00190 
00191       ACE_NEW_RETURN (ACE_Log_Msg_Manager::lock_,
00192                       ACE_Recursive_Thread_Mutex,
00193                       0);
00194     }
00195 
00196   if (init_backend () == -1)
00197     return 0;
00198 
00199   return ACE_Log_Msg_Manager::lock_;
00200 }
00201 
00202 void
00203 ACE_Log_Msg_Manager::close (void)
00204 {
00205 #if defined (ACE_HAS_STHREADS) && ! defined (ACE_HAS_TSS_EMULATION) && ! defined (ACE_HAS_EXCEPTIONS)
00206   // Delete the (main thread's) Log_Msg instance.  I think that this
00207   // is only "necessary" if exception handling is not enabled.
00208   // Without exception handling, main thread TSS destructors don't
00209   // seem to be called.  It's not really necessary anyways, because
00210   // this one leak is harmless on Solaris.
00211   delete ACE_Log_Msg::instance ();
00212 #endif /* ACE_HAS_STHREADS && ! TSS_EMULATION && ! ACE_HAS_EXCEPTIONS */
00213 
00214   // Ugly, ugly, but don't know a better way.
00215   delete ACE_Log_Msg_Manager::lock_;
00216   ACE_Log_Msg_Manager::lock_ = 0;
00217 
00218   delete ACE_Log_Msg_Manager::log_backend_;
00219   ACE_Log_Msg_Manager::log_backend_ = 0;
00220 
00221   // we are never responsible for custom backend
00222   ACE_Log_Msg_Manager::custom_backend_ = 0;
00223 }
00224 
00225 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
00226      defined (ACE_HAS_TSS_EMULATION)
00227 /* static */
00228 #  if defined (ACE_HAS_THR_C_DEST)
00229 #   define LOCAL_EXTERN_PREFIX extern "C"
00230 #  else
00231 #   define LOCAL_EXTERN_PREFIX
00232 #  endif /* ACE_HAS_THR_C_DEST */
00233 LOCAL_EXTERN_PREFIX
00234 void
00235 ACE_TSS_CLEANUP_NAME (void *ptr)
00236 {
00237 #if !defined(ACE_USE_ONE_SHOT_AT_THREAD_EXIT)
00238   // Delegate to thr_desc if this not has terminated
00239   ACE_Log_Msg* log_msg = (ACE_Log_Msg*) ptr;
00240   if (log_msg->thr_desc()!=0)
00241    log_msg->thr_desc()->log_msg_cleanup(log_msg);
00242   else
00243 #endif /* !ACE_USE_ONE_SHOT_AT_THREAD_EXIT */
00244   delete (ACE_Log_Msg *) ptr;
00245 }
00246 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
00247 #endif /* ! ACE_MT_SAFE */
00248 
00249 /* static */
00250 int
00251 ACE_Log_Msg::exists (void)
00252 {
00253 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00254 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
00255      defined (ACE_HAS_TSS_EMULATION)
00256   ACE_Log_Msg *tss_log_msg = 0;
00257 
00258   // Get the tss_log_msg from thread-specific storage.
00259   return key_created_
00260     && ACE_Thread::getspecific (*(log_msg_tss_key ()),
00261                                 reinterpret_cast<void **> (&tss_log_msg)) != -1
00262     && tss_log_msg;
00263 # else
00264 #   error "Platform must support thread-specific storage if threads are used."
00265 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
00266 #else  /* ! ACE_MT_SAFE */
00267   return 1;
00268 #endif /* ! ACE_MT_SAFE */
00269 }
00270 
00271 ACE_Log_Msg *
00272 ACE_Log_Msg::instance (void)
00273 {
00274 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00275 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
00276      defined (ACE_HAS_TSS_EMULATION)
00277   // TSS Singleton implementation.
00278 
00279   if (key_created_ == 0)
00280     {
00281       ACE_thread_mutex_t *lock =
00282         reinterpret_cast<ACE_thread_mutex_t *> (
00283           ACE_OS_Object_Manager::preallocated_object
00284             [ACE_OS_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK]);
00285 
00286       if (1 == ACE_OS_Object_Manager::starting_up())
00287         //This function is called before ACE_OS_Object_Manager is
00288         //initialized.  So the lock might not be valid.  Assume it's
00289         //single threaded and so don't need the lock.
00290         ;
00291       else
00292         ACE_OS::thread_mutex_lock (lock);
00293 
00294       if (key_created_ == 0)
00295         {
00296           // Allocate the Singleton lock.
00297           ACE_Log_Msg_Manager::get_lock ();
00298 
00299           {
00300             ACE_NO_HEAP_CHECK;
00301             if (ACE_Thread::keycreate (log_msg_tss_key (),
00302                                        &ACE_TSS_CLEANUP_NAME) != 0)
00303               {
00304                 if (1 == ACE_OS_Object_Manager::starting_up())
00305                   //This function is called before ACE_OS_Object_Manager is
00306                   //initialized.  So the lock might not be valid.  Assume it's
00307                   //single threaded and so don't need the lock.
00308                   ;
00309                 else
00310                 ACE_OS::thread_mutex_unlock (lock);
00311                 return 0; // Major problems, this should *never* happen!
00312               }
00313           }
00314 
00315           key_created_ = 1;
00316         }
00317 
00318       if (1 == ACE_OS_Object_Manager::starting_up())
00319         //This function is called before ACE_OS_Object_Manager is
00320         //initialized.  So the lock might not be valid.  Assume it's
00321         //single threaded and so don't need the lock.
00322         ;
00323       else
00324         ACE_OS::thread_mutex_unlock (lock);
00325     }
00326 
00327   ACE_Log_Msg *tss_log_msg = 0;
00328 
00329   // Get the tss_log_msg from thread-specific storage.
00330   if (ACE_Thread::getspecific (*(log_msg_tss_key ()),
00331                                reinterpret_cast<void **> (&tss_log_msg)) == -1)
00332     return 0; // This should not happen!
00333 
00334   // Check to see if this is the first time in for this thread.
00335   if (tss_log_msg == 0)
00336     {
00337       // Allocate memory off the heap and store it in a pointer in
00338       // thread-specific storage (on the stack...).  Stop heap
00339       // checking, the memory will always be freed by the thread
00340       // rundown because of the TSS callback set up when the key was
00341       // created. This prevents from getting these blocks reported as
00342       // memory leaks.
00343       {
00344         ACE_NO_HEAP_CHECK;
00345 
00346         ACE_NEW_RETURN (tss_log_msg,
00347                         ACE_Log_Msg,
00348                         0);
00349         // Store the dynamically allocated pointer in thread-specific
00350         // storage.  It gets deleted via the ACE_TSS_cleanup function
00351         // when the thread terminates.
00352 
00353         if (ACE_Thread::setspecific (*(log_msg_tss_key()),
00354                                      reinterpret_cast<void *> (tss_log_msg))
00355             != 0)
00356           return 0; // Major problems, this should *never* happen!
00357       }
00358     }
00359 
00360   return tss_log_msg;
00361 # else
00362 #  error "Platform must support thread-specific storage if threads are used."
00363 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
00364 #else  /* ! ACE_MT_SAFE */
00365   // We don't have threads, we cannot call
00366   // ACE_Log_Msg_Manager::get_lock () to initialize the logger
00367   // callback, so instead we do it here.
00368   if (ACE_Log_Msg_Manager::init_backend () == -1)
00369     return 0;
00370 
00371   // Singleton implementation.
00372   static ACE_Cleanup_Adapter<ACE_Log_Msg> *log_msg = 0;
00373   if (log_msg == 0)
00374     {
00375       ACE_NEW_RETURN (log_msg, ACE_Cleanup_Adapter<ACE_Log_Msg>, 0);
00376       // Register the instance for destruction at program termination.
00377       ACE_Object_Manager::at_exit (log_msg);
00378     }
00379 
00380   return &log_msg->object ();
00381 #endif /* ! ACE_MT_SAFE */
00382 }
00383 
00384 // Not inlined to help prevent having to include OS.h just to
00385 // get ACE_DEBUG, et al, macros.
00386 int
00387 ACE_Log_Msg::last_error_adapter (void)
00388 {
00389   return ACE_OS::last_error ();
00390 }
00391 
00392 // Sets the flag in the default priority mask used to initialize
00393 // ACE_Log_Msg instances, as well as the current per-thread instance.
00394 
00395 void
00396 ACE_Log_Msg::enable_debug_messages (ACE_Log_Priority priority)
00397 {
00398   ACE_SET_BITS (ACE_Log_Msg::default_priority_mask_, priority);
00399   ACE_Log_Msg *i = ACE_Log_Msg::instance ();
00400   i->priority_mask (i->priority_mask () | priority);
00401 }
00402 
00403 // Clears the flag in the default priority mask used to initialize
00404 // ACE_Log_Msg instances, as well as the current per-thread instance.
00405 
00406 void
00407 ACE_Log_Msg::disable_debug_messages (ACE_Log_Priority priority)
00408 {
00409   ACE_CLR_BITS (ACE_Log_Msg::default_priority_mask_, priority);
00410   ACE_Log_Msg *i = ACE_Log_Msg::instance ();
00411   i->priority_mask (i->priority_mask () & ~priority);
00412 }
00413 
00414 const ACE_TCHAR *
00415 ACE_Log_Msg::program_name (void)
00416 {
00417   return ACE_Log_Msg::program_name_;
00418 }
00419 
00420 /// Name of the local host.
00421 const ACE_TCHAR *ACE_Log_Msg::local_host_ = 0;
00422 
00423 /// Records the program name.
00424 const ACE_TCHAR *ACE_Log_Msg::program_name_ = 0;
00425 
00426 /// Default is to use stderr.
00427 u_long ACE_Log_Msg::flags_ = ACE_Log_Msg::STDERR;
00428 
00429 /// Process id of the current process.
00430 pid_t ACE_Log_Msg::pid_ = -1;
00431 
00432 /// Current offset of msg_[].
00433 long ACE_Log_Msg::msg_off_ = 0;
00434 
00435 /// Default per-thread priority mask
00436 /// By default, no priorities are enabled.
00437 u_long ACE_Log_Msg::default_priority_mask_ = 0;
00438 
00439 /// Default per-process priority mask
00440 /// By default, all priorities are enabled.
00441 u_long ACE_Log_Msg::process_priority_mask_ = LM_SHUTDOWN
00442                                              | LM_TRACE
00443                                              | LM_DEBUG
00444                                              | LM_INFO
00445                                              | LM_NOTICE
00446                                              | LM_WARNING
00447                                              | LM_STARTUP
00448                                              | LM_ERROR
00449                                              | LM_CRITICAL
00450                                              | LM_ALERT
00451                                              | LM_EMERGENCY;
00452 
00453 void
00454 ACE_Log_Msg::close (void)
00455 {
00456   // This call needs to go here to avoid memory leaks.
00457   ACE_MT (ACE_Log_Msg_Manager::close ());
00458 
00459   // Please note that this will be called by a statement that is
00460   // harded coded into the ACE_Object_Manager's shutdown sequence, in
00461   // its destructor.
00462 
00463 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && \
00464     (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
00465      defined (ACE_HAS_TSS_EMULATION))
00466 
00467      if (key_created_ == 1)
00468        {
00469          ACE_thread_mutex_t *lock =
00470            reinterpret_cast<ACE_thread_mutex_t *> (
00471              ACE_OS_Object_Manager::preallocated_object
00472              [ACE_OS_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK]);
00473          ACE_OS::thread_mutex_lock (lock);
00474 
00475          if (key_created_ == 1)
00476            {
00477              // The same as the ACE_TSS_Cleanup's own key doesn't get
00478              // detached, the log_msg_tss_key_ won't get detached
00479              // until ACE_TSS_Cleanup::free_all_keys_left, so it will
00480              // be in the ACE_TSS_Cleanup::table_.  However, there's
00481              // no resource associated with it, so we don't need to
00482              // keyfree it.  The dynamic memory associated with it was
00483              // already deleted by ACE_TSS_Cleanup::exit (), so we
00484              // don't want to access it again.
00485              key_created_ = 0;
00486 #ifdef ACE_HAS_BROKEN_THREAD_KEYFREE
00487              // for some systems, e.g. LynxOS, we need to ensure that
00488              // any registered thread destructor action for this thread
00489              // is disabled. Otherwise in the event of a dynamic library
00490              // unload of libACE, by a program not linked with libACE,
00491              // ACE_TSS_cleanup will be invoked after libACE has been unloaded.
00492 
00493              ACE_Log_Msg *tss_log_msg = 0;
00494 
00495              // Get the tss_log_msg from thread-specific storage.
00496              if ( ACE_Thread::getspecific (*(log_msg_tss_key ()),
00497                            ACE_reinterpret_cast (void **, &tss_log_msg)) != -1
00498                   && tss_log_msg)
00499              {
00500                // we haven't been cleaned up
00501                ACE_TSS_cleanup(tss_log_msg);
00502 
00503                if ( ACE_Thread::setspecific( (*log_msg_tss_key()),
00504                                              (void *)NULL ) != 0 )
00505                {
00506                   ACE_DEBUG ((LM_DEBUG,
00507                               ACE_LIB_TEXT ("(%P|%t) ACE_Log_Msg::close failed to ACE_Thread::setspecific to NULL\n")));
00508                }
00509 
00510              }
00511 #endif /* ACE_HAS_BROKEN_THREAD_KEYFREE */
00512            }
00513 
00514          ACE_OS::thread_mutex_unlock (lock);
00515        }
00516 #endif /* (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION) && ACE_MT_SAFE */
00517 }
00518 
00519 void
00520 ACE_Log_Msg::sync_hook (const ACE_TCHAR *prg_name)
00521 {
00522   ACE_LOG_MSG->sync (prg_name);
00523 }
00524 
00525 ACE_OS_Thread_Descriptor *
00526 ACE_Log_Msg::thr_desc_hook (void)
00527 {
00528   return ACE_LOG_MSG->thr_desc ();
00529 }
00530 
00531 // Call after a fork to resynchronize the PID and PROGRAM_NAME
00532 // variables.
00533 void
00534 ACE_Log_Msg::sync (const ACE_TCHAR *prog_name)
00535 {
00536   ACE_TRACE ("ACE_Log_Msg::sync");
00537 
00538   if (prog_name)
00539     {
00540       // Must free if already allocated!!!
00541       ACE_OS::free ((void *) ACE_Log_Msg::program_name_);
00542 
00543       // Stop heap checking, block will be freed by the destructor when
00544       // the last ACE_Log_Msg instance is deleted.
00545       // Heap checking state will be restored when the block is left.
00546       {
00547         ACE_NO_HEAP_CHECK;
00548 
00549         ACE_Log_Msg::program_name_ = ACE_OS::strdup (prog_name);
00550       }
00551     }
00552 
00553   ACE_Log_Msg::pid_ = ACE_OS::getpid ();
00554   ACE_Log_Msg::msg_off_ = 0;
00555 }
00556 
00557 u_long
00558 ACE_Log_Msg::flags (void)
00559 {
00560   ACE_TRACE ("ACE_Log_Msg::flags");
00561   u_long result;
00562   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00563                             *ACE_Log_Msg_Manager::get_lock (), 0));
00564 
00565   result = ACE_Log_Msg::flags_;
00566   return result;
00567 }
00568 
00569 void
00570 ACE_Log_Msg::set_flags (u_long flgs)
00571 {
00572   ACE_TRACE ("ACE_Log_Msg::set_flags");
00573   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00574                      *ACE_Log_Msg_Manager::get_lock ()));
00575 
00576   ACE_SET_BITS (ACE_Log_Msg::flags_, flgs);
00577 }
00578 
00579 void
00580 ACE_Log_Msg::clr_flags (u_long flgs)
00581 {
00582   ACE_TRACE ("ACE_Log_Msg::clr_flags");
00583   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00584                      *ACE_Log_Msg_Manager::get_lock ()));
00585 
00586   ACE_CLR_BITS (ACE_Log_Msg::flags_, flgs);
00587 }
00588 
00589 int
00590 ACE_Log_Msg::acquire (void)
00591 {
00592   ACE_TRACE ("ACE_Log_Msg::acquire");
00593 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00594   return ACE_Log_Msg_Manager::get_lock ()->acquire ();
00595 #else  /* ! ACE_MT_SAFE */
00596   return 0;
00597 #endif /* ! ACE_MT_SAFE */
00598 }
00599 
00600 u_long
00601 ACE_Log_Msg::priority_mask (u_long n_mask, MASK_TYPE mask_type)
00602 {
00603   u_long o_mask;
00604 
00605   if (mask_type == THREAD)
00606     {
00607       o_mask = this->priority_mask_;
00608       this->priority_mask_ = n_mask;
00609     }
00610   else
00611     {
00612       o_mask = ACE_Log_Msg::process_priority_mask_;
00613       ACE_Log_Msg::process_priority_mask_ = n_mask;
00614     }
00615 
00616   return o_mask;
00617 }
00618 
00619 u_long
00620 ACE_Log_Msg::priority_mask (MASK_TYPE mask_type)
00621 {
00622   return mask_type == THREAD
00623     ? this->priority_mask_
00624     :  ACE_Log_Msg::process_priority_mask_;
00625 }
00626 
00627 int
00628 ACE_Log_Msg::log_priority_enabled (ACE_Log_Priority log_priority)
00629 {
00630   return ACE_BIT_ENABLED (this->priority_mask_ |
00631                           ACE_Log_Msg::process_priority_mask_,
00632                           log_priority);
00633 }
00634 
00635 int
00636 ACE_Log_Msg::release (void)
00637 {
00638   ACE_TRACE ("ACE_Log_Msg::release");
00639 
00640 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00641   return ACE_Log_Msg_Manager::get_lock ()->release ();
00642 #else  /* ! ACE_MT_SAFE */
00643   return 0;
00644 #endif /* ! ACE_MT_SAFE */
00645 }
00646 
00647 ACE_Log_Msg::ACE_Log_Msg (void)
00648   : status_ (0),
00649     errnum_ (0),
00650     linenum_ (0),
00651     msg_ (0),
00652     restart_ (1),  // Restart by default...
00653     ostream_ (0),
00654     msg_callback_ (0),
00655     trace_depth_ (0),
00656     trace_active_ (0),
00657     tracing_enabled_ (1), // On by default?
00658     delete_ostream_(0),
00659     thr_desc_ (0),
00660     priority_mask_ (default_priority_mask_),
00661     timestamp_ (0)
00662 {
00663   // ACE_TRACE ("ACE_Log_Msg::ACE_Log_Msg");
00664 
00665   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00666                      *ACE_Log_Msg_Manager::get_lock ()));
00667   ++instance_count_;
00668 
00669   if (this->instance_count_ == 1)
00670     ACE_Base_Thread_Adapter::set_log_msg_hooks (ACE_Log_Msg::init_hook,
00671                                                 ACE_Log_Msg::inherit_hook,
00672                                                 ACE_Log_Msg::close,
00673                                                 ACE_Log_Msg::sync_hook,
00674                                                 ACE_Log_Msg::thr_desc_hook);
00675 
00676   this->conditional_values_.is_set_ = 0;
00677 
00678   char *timestamp = ACE_OS::getenv ("ACE_LOG_TIMESTAMP");
00679   if (timestamp != 0)
00680     {
00681       // If variable is set or is set to date tag so we print date and time.
00682       if (ACE_OS::strcmp (timestamp, "TIME") == 0)
00683         {
00684           this->timestamp_ = 1;
00685         }
00686       else if (ACE_OS::strcmp (timestamp, "DATE") == 0)
00687         {
00688           this->timestamp_ = 2;
00689         }
00690     }
00691 
00692   ACE_NEW_NORETURN (this->msg_, ACE_TCHAR[ACE_MAXLOGMSGLEN+1]);
00693 }
00694 
00695 ACE_Log_Msg::~ACE_Log_Msg (void)
00696 {
00697 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00698 
00699   int instance_count;
00700 
00701   // Only hold the guard while updating the instance_count_.
00702   // If ACE_Log_Msg_Manager::close () is called, the lock will
00703   // be deleted.
00704   {
00705     ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00706                        *ACE_Log_Msg_Manager::get_lock ()));
00707     instance_count = --instance_count_;
00708   }
00709   // Release the guard.
00710 
00711 #else  /* ! ACE_MT_SAFE */
00712   int instance_count = --instance_count_;
00713 #endif /* ! ACE_MT_SAFE */
00714 
00715   // If this is the last instance then cleanup.  Only the last
00716   // thread to destroy its ACE_Log_Msg instance should execute
00717   // this block.
00718   if (instance_count == 0)
00719     {
00720       // Destroy the message queue instance.
00721       if (ACE_Log_Msg_Manager::log_backend_ != 0)
00722         ACE_Log_Msg_Manager::log_backend_->close ();
00723 
00724       // Close down custom backend
00725       if (ACE_Log_Msg_Manager::custom_backend_ != 0)
00726         ACE_Log_Msg_Manager::custom_backend_->close ();
00727 
00728 #     if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00729 #       if defined (ACE_HAS_TSS_EMULATION)
00730           ACE_Log_Msg_Manager::close ();
00731 #       endif /* ACE_HAS_TSS_EMULATION */
00732 #     endif /* ACE_MT_SAFE */
00733 
00734       if (ACE_Log_Msg::program_name_)
00735         {
00736           ACE_OS::free ((void *) ACE_Log_Msg::program_name_);
00737           ACE_Log_Msg::program_name_ = 0;
00738         }
00739 
00740       if (ACE_Log_Msg::local_host_)
00741         {
00742           ACE_OS::free ((void *) ACE_Log_Msg::local_host_);
00743           ACE_Log_Msg::local_host_ = 0;
00744         }
00745     }
00746 
00747   //
00748   // do we need to close and clean up?
00749   //
00750   if (this->delete_ostream_ == 1)
00751 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00752     {
00753       ACE_OS::fclose (this->ostream_);
00754     }
00755 #else
00756     {
00757       delete ostream_;
00758       ostream_ = 0;
00759     }
00760 #endif
00761 
00762   delete[] this->msg_;
00763 }
00764 
00765 // Open the sender-side of the message queue.
00766 
00767 int
00768 ACE_Log_Msg::open (const ACE_TCHAR *prog_name,
00769                    u_long flags,
00770                    const ACE_TCHAR *logger_key)
00771 {
00772   ACE_TRACE ("ACE_Log_Msg::open");
00773   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00774                             *ACE_Log_Msg_Manager::get_lock (), -1));
00775 
00776   if (prog_name)
00777     {
00778       ACE_OS::free ((void *) ACE_Log_Msg::program_name_);
00779 
00780       // Stop heap checking, block will be freed by the destructor.
00781       {
00782         ACE_NO_HEAP_CHECK;
00783 
00784         ACE_ALLOCATOR_RETURN (ACE_Log_Msg::program_name_,
00785                               ACE_OS::strdup (prog_name),
00786                               -1);
00787       }
00788     }
00789   else if (ACE_Log_Msg::program_name_ == 0)
00790     {
00791       // Stop heap checking, block will be freed by the destructor.
00792       ACE_NO_HEAP_CHECK;
00793       ACE_ALLOCATOR_RETURN (ACE_Log_Msg::program_name_,
00794                             ACE_OS::strdup (ACE_LIB_TEXT ("<unknown>")),
00795                             -1);
00796     }
00797 
00798   int status = 0;
00799 
00800   // Be sure that there is a message_queue_, with multiple threads.
00801   ACE_MT (ACE_Log_Msg_Manager::init_backend (&flags));
00802 
00803   // Always close the current handle before doing anything else.
00804   if (ACE_Log_Msg_Manager::log_backend_ != 0)
00805     ACE_Log_Msg_Manager::log_backend_->reset ();
00806 
00807   if (ACE_Log_Msg_Manager::custom_backend_ != 0)
00808     ACE_Log_Msg_Manager::custom_backend_->reset ();
00809 
00810   // Note that if we fail to open the message queue the default action
00811   // is to use stderr (set via static initialization in the
00812   // Log_Msg.cpp file).
00813 
00814   if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER)
00815       || ACE_BIT_ENABLED (flags, ACE_Log_Msg::SYSLOG))
00816     {
00817       // The SYSLOG backends (both NT and UNIX) can get along fine
00818       // without the logger_key - they will default to prog_name if
00819       // logger key is 0.
00820       if (logger_key == 0 && ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER))
00821         status = -1;
00822       else
00823         status = ACE_Log_Msg_Manager::log_backend_->open (logger_key);
00824 
00825       if (status == -1)
00826         ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR);
00827       else
00828         {
00829           if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER))
00830             ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER);
00831           if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::SYSLOG))
00832             ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG);
00833         }
00834     }
00835   else if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER)
00836            || ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG))
00837     {
00838       // If we are closing down logger, redirect logging to stderr.
00839       ACE_CLR_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER);
00840       ACE_CLR_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG);
00841       ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR);
00842     }
00843 
00844   if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::CUSTOM))
00845     {
00846       status =
00847         ACE_Log_Msg_Manager::custom_backend_->open (logger_key);
00848 
00849       if (status != -1)
00850         ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM);
00851     }
00852 
00853   // Remember, ACE_Log_Msg::STDERR bit is on by default...
00854   if (status != -1
00855       && ACE_BIT_ENABLED (flags,
00856                           ACE_Log_Msg::STDERR) == 0)
00857     ACE_CLR_BITS (ACE_Log_Msg::flags_,
00858                   ACE_Log_Msg::STDERR);
00859 
00860   // VERBOSE takes precedence over VERBOSE_LITE...
00861   if (ACE_BIT_ENABLED (flags,
00862                        ACE_Log_Msg::VERBOSE_LITE))
00863     ACE_SET_BITS (ACE_Log_Msg::flags_,
00864                   ACE_Log_Msg::VERBOSE_LITE);
00865   else if (ACE_BIT_ENABLED (flags,
00866                             ACE_Log_Msg::VERBOSE))
00867     ACE_SET_BITS (ACE_Log_Msg::flags_,
00868                   ACE_Log_Msg::VERBOSE);
00869 
00870   if (ACE_BIT_ENABLED (flags,
00871                        ACE_Log_Msg::OSTREAM))
00872     {
00873       ACE_SET_BITS (ACE_Log_Msg::flags_,
00874                     ACE_Log_Msg::OSTREAM);
00875       // Only set this to cerr if it hasn't already been set.
00876       if (this->msg_ostream () == 0)
00877         this->msg_ostream (ACE_DEFAULT_LOG_STREAM);
00878     }
00879 
00880   if (ACE_BIT_ENABLED (flags,
00881                        ACE_Log_Msg::MSG_CALLBACK))
00882     ACE_SET_BITS (ACE_Log_Msg::flags_,
00883                   ACE_Log_Msg::MSG_CALLBACK);
00884 
00885   if (ACE_BIT_ENABLED (flags,
00886                        ACE_Log_Msg::SILENT))
00887     ACE_SET_BITS (ACE_Log_Msg::flags_,
00888                   ACE_Log_Msg::SILENT);
00889 
00890   return status;
00891 }
00892 
00893 /**
00894  * Valid Options (prefixed by '%', as in printf format strings) include:
00895  *   'A': print an ACE_timer_t value
00896  *   'a': exit the program at this point (var-argument is the exit status!)
00897  *   'c': print a character
00898  *   'C': print a character string
00899  *   'i', 'd': print a decimal number
00900  *   'I', indent according to nesting depth
00901  *   'e', 'E', 'f', 'F', 'g', 'G': print a double
00902  *   'l', print line number where an error occurred.
00903  *   'M': print the name of the priority of the message.
00904  *   'm': Return the message corresponding to errno value, e.g., as done by <strerror>
00905  *   'N': print file name where the error occurred.
00906  *   'n': print the name of the program (or "<unknown>" if not set)
00907  *   'o': print as an octal number
00908  *   'P': format the current process id
00909  *   'p': format the appropriate errno message from sys_errlist, e.g., as done by <perror>
00910  *   'Q': print out the uint64 number
00911  *   'q': print out the int64 number
00912  *   '@': print a void* pointer (in hexadecimal)
00913  *   'r': call the function pointed to by the corresponding argument
00914  *   'R': print return status
00915  *   'S': format the appropriate _sys_siglist entry corresponding to var-argument.
00916  *   's': format a character string
00917  *   'T': print timestamp in hour:minute:sec:usec format.
00918  *   'D': print timestamp in month/day/year hour:minute:sec:usec format.
00919  *   't': print thread id (1 if single-threaded)
00920  *   'u': print as unsigned int
00921  *   'x': print as a hex number
00922  *   'X': print as a hex number
00923  *   'w': print a wide character
00924  *   'W': print out a wide character string.
00925  *   'z': print an ACE_OS::WChar character
00926  *   'Z': print an ACE_OS::WChar character string
00927  *   '%': format a single percent sign, '%'
00928  */
00929 ssize_t
00930 ACE_Log_Msg::log (ACE_Log_Priority log_priority,
00931                   const ACE_TCHAR *format_str, ...)
00932 {
00933   ACE_TRACE ("ACE_Log_Msg::log");
00934 
00935   // Start of variable args section.
00936   va_list argp;
00937 
00938   va_start (argp, format_str);
00939 
00940   ssize_t result = this->log (format_str,
00941                               log_priority,
00942                               argp);
00943   va_end (argp);
00944 
00945   return result;
00946 }
00947 
00948 #if defined (ACE_HAS_WCHAR)
00949 /**
00950  * Since this is the ANTI_TCHAR version, we need to convert
00951  * the format string over.
00952  */
00953 ssize_t
00954 ACE_Log_Msg::log (ACE_Log_Priority log_priority,
00955                   const ACE_ANTI_TCHAR *format_str, ...)
00956 {
00957   ACE_TRACE ("ACE_Log_Msg::log");
00958 
00959   // Start of variable args section.
00960   va_list argp;
00961 
00962   va_start (argp, format_str);
00963 
00964   ssize_t result = this->log (ACE_TEXT_ANTI_TO_TCHAR (format_str),
00965                               log_priority,
00966                               argp);
00967   va_end (argp);
00968 
00969   return result;
00970 }
00971 #endif /* ACE_HAS_WCHAR */
00972 
00973 ssize_t
00974 ACE_Log_Msg::log (const ACE_TCHAR *format_str,
00975                   ACE_Log_Priority log_priority,
00976                   va_list argp)
00977 {
00978   ACE_TRACE ("ACE_Log_Msg::log");
00979   // External decls.
00980 
00981   typedef void (*PTF)(...);
00982 
00983   // Check if there were any conditional values set.
00984   int conditional_values = this->conditional_values_.is_set_;
00985 
00986   // Reset conditional values.
00987   this->conditional_values_.is_set_ = 0;
00988 
00989   // Only print the message if <priority_mask_> hasn't been reset to
00990   // exclude this logging priority.
00991   if (this->log_priority_enabled (log_priority) == 0)
00992     return 0;
00993 
00994   // If conditional values were set and the log priority is correct,
00995   // then the values are actually set.
00996   if (conditional_values)
00997     this->set (this->conditional_values_.file_,
00998                this->conditional_values_.line_,
00999                this->conditional_values_.op_status_,
01000                this->conditional_values_.errnum_,
01001                this->restart (),
01002                this->msg_ostream (),
01003                this->msg_callback ());
01004 
01005   // Logging is supposed to be a benign activity (i.e., not interfer
01006   // with normal application operations), so don't inadvertently smash
01007   // errno!
01008   ACE_Errno_Guard guard (errno);
01009 
01010   ACE_Log_Record log_record (log_priority,
01011                              ACE_OS::gettimeofday (),
01012                              this->getpid ());
01013   // bp is pointer to where to put next part of logged message.
01014   // bspace is the number of characters remaining in msg_.
01015   ACE_TCHAR *bp = const_cast<ACE_TCHAR *> (this->msg ());
01016   size_t bspace = ACE_Log_Record::MAXLOGMSGLEN;  // Leave room for Nul term.
01017   if (this->msg_off_ <= ACE_Log_Record::MAXLOGMSGLEN)
01018     bspace -= static_cast<size_t> (this->msg_off_);
01019 
01020   // If this platform has snprintf() capability to prevent overrunning the
01021   // output buffer, use it. To avoid adding a maintenance-hassle compile-
01022   // time couple between here and OS.cpp, don't try to figure this out at
01023   // compile time. Instead, do a quick check now; if we get a -1 return,
01024   // the platform doesn't support the length-limiting capability.
01025   ACE_TCHAR test[2];
01026   int can_check = ACE_OS::snprintf (test, 1, ACE_LIB_TEXT ("x")) != -1;
01027 
01028   int abort_prog = 0;
01029   int exit_value = 0;
01030 
01031   if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::VERBOSE))
01032     {
01033       // Prepend the program name onto this message
01034 
01035       if (ACE_Log_Msg::program_name_ != 0)
01036         {
01037           for (const ACE_TCHAR *s = ACE_Log_Msg::program_name_;
01038                bspace > 1 && (*bp = *s) != '\0';
01039                ++s, --bspace)
01040             bp++;
01041 
01042           *bp++ = '|';
01043           --bspace;
01044         }
01045     }
01046 
01047   if (timestamp_ > 0)
01048   {
01049      ACE_TCHAR day_and_time[35];
01050      const ACE_TCHAR *s;
01051      if (timestamp_ == 1)
01052      {
01053         // Print just the time
01054         s = ACE::timestamp (day_and_time, sizeof day_and_time, 1);
01055      }
01056      else
01057      {
01058         // Print time and date
01059         ACE::timestamp (day_and_time, sizeof day_and_time);
01060         s = day_and_time;
01061      }
01062 
01063      for (; bspace > 1 && (*bp = *s) != '\0'; ++s, --bspace)
01064        ++bp;
01065 
01066      *bp++ = '|';
01067      --bspace;
01068   }
01069 
01070   while (*format_str != '\0' && bspace > 0)
01071     {
01072       // Copy input to output until we encounter a %, however a
01073       // % followed by another % is not a format specification.
01074 
01075       if (*format_str != '%')
01076         {
01077           *bp++ = *format_str++;
01078           --bspace;
01079         }
01080       else if (format_str[1] == '%') // An "escaped" '%' (just print one '%').
01081         {
01082           *bp++ = *format_str++;    // Store first %
01083           ++format_str;             // but skip second %
01084           --bspace;
01085         }
01086       else
01087         {
01088           // This is most likely a format specification that ends with
01089           // one of the valid options described previously. To enable full
01090           // use of all sprintf capabilities, save the format specifier
01091           // from the '%' up to the format letter in a new char array.
01092           // This allows the full sprintf capability for padding, field
01093           // widths, alignment, etc.  Any width/precision requiring a
01094           // caller-supplied argument is extracted and placed as text
01095           // into the format array. Lastly, we convert the caller-supplied
01096           // format specifier from the ACE_Log_Msg-supported list to the
01097           // equivalent sprintf specifier, and run the new format spec
01098           // through sprintf, adding it to the bp string.
01099 
01100           const ACE_TCHAR *abort_str = ACE_LIB_TEXT ("Aborting...");
01101           const ACE_TCHAR *start_format = format_str;
01102           ACE_TCHAR format[128]; // Converted format string
01103           ACE_TCHAR *fp;         // Current format pointer
01104           int       wp = 0;      // Width/precision extracted from args
01105           int       done = 0;
01106           int       skip_nul_locate = 0;
01107           int       this_len = 0;    // How many chars s[n]printf wrote
01108 
01109           fp = format;
01110           *fp++ = *format_str++;   // Copy in the %
01111 
01112           // Initialization to satisfy VC6
01113           int tmp_indent = 0;
01114           // Work through the format string to copy in the format
01115           // from the caller. While it's going across, extract ints
01116           // for '*' width/precision values from the argument list.
01117           // When the real format specifier is located, change it to
01118           // one recognized by sprintf, if needed, and do the sprintf
01119           // call.
01120 
01121           while (!done)
01122             {
01123               done = 1;               // Unless a conversion spec changes it
01124 
01125               switch (*format_str)
01126                 {
01127                 // The initial set of cases are the conversion
01128                 // specifiers. Copy them in to the format array.
01129                 // Note we don't use 'l', a normal conversion spec,
01130                 // as a conversion because it is a ACE_Log_Msg format
01131                 // specifier.
01132                 case '-':
01133                 case '+':
01134                 case '0':
01135                 case ' ':
01136                 case '#':
01137                 case '1':
01138                 case '2':
01139                 case '3':
01140                 case '4':
01141                 case '5':
01142                 case '6':
01143                 case '7':
01144                 case '8':
01145                 case '9':
01146                 case '.':
01147                 case 'L':
01148                 case 'h':
01149                   *fp++ = *format_str;
01150                   done = 0;
01151                   break;
01152 
01153                 case '*':
01154                   wp = va_arg (argp, int);
01155                   ACE_OS::sprintf (fp, ACE_LIB_TEXT ("%d"), wp);
01156                   fp += ACE_OS::strlen (fp);
01157                   done = 0;
01158                   break;
01159 
01160                 case 'A':             // ACE_timer_t
01161                   {
01162                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("f"));
01163                     double value = va_arg (argp, double);
01164                     if (can_check)
01165                       this_len = ACE_OS::snprintf (bp, bspace, format, value);
01166                     else
01167                       this_len = ACE_OS::sprintf (bp, format, value);
01168                     ACE_UPDATE_COUNT (bspace, this_len);
01169                   }
01170                   break;
01171 
01172                 case 'a': // Abort program after handling all of format string.
01173                   abort_prog = 1;
01174                   exit_value = va_arg (argp, int);
01175                   ACE_OS::strsncpy (bp, abort_str, bspace);
01176                   if (bspace > ACE_OS::strlen (abort_str))
01177                     bspace -= ACE_OS::strlen (abort_str);
01178                   else
01179                     bspace = 0;
01180                   break;
01181 
01182                 case 'l':             // Source file line number
01183                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("d"));
01184                   if (can_check)
01185                     this_len = ACE_OS::snprintf (bp,
01186                                                  bspace,
01187                                                  format,
01188                                                  this->linenum ());
01189                   else
01190                     this_len = ACE_OS::sprintf (bp, format, this->linenum ());
01191                   ACE_UPDATE_COUNT (bspace, this_len);
01192                   break;
01193 
01194                 case 'N':             // Source file name
01195 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01196                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("ls"));
01197 #else
01198                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01199 #endif
01200                   if (can_check)
01201                     this_len = ACE_OS::snprintf (bp, bspace, format,
01202                                                  this->file () ?
01203                                                  ACE_TEXT_CHAR_TO_TCHAR (this->file ())
01204                                                  : ACE_LIB_TEXT ("<unknown file>"));
01205                   else
01206                     this_len = ACE_OS::sprintf (bp, format,
01207                                                 this->file () ?
01208                                                 ACE_TEXT_CHAR_TO_TCHAR (this->file ())
01209                                                 : ACE_LIB_TEXT ("<unknown file>"));
01210                   ACE_UPDATE_COUNT (bspace, this_len);
01211                   break;
01212 
01213                 case 'n':             // Program name
01214 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01215                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("ls"));
01216 #else /* ACE_WIN32 && ACE_USES_WCHAR */
01217                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01218 #endif
01219                   if (can_check)
01220                     this_len = ACE_OS::snprintf (bp, bspace, format,
01221                                                  ACE_Log_Msg::program_name_ ?
01222                                                  ACE_Log_Msg::program_name_ :
01223                                                  ACE_LIB_TEXT ("<unknown>"));
01224                   else
01225                     this_len = ACE_OS::sprintf (bp, format,
01226                                                 ACE_Log_Msg::program_name_ ?
01227                                                 ACE_Log_Msg::program_name_ :
01228                                                 ACE_LIB_TEXT ("<unknown>"));
01229                   ACE_UPDATE_COUNT (bspace, this_len);
01230                   break;
01231 
01232                 case 'P':             // Process ID
01233                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("d"));
01234                   if (can_check)
01235                     this_len = ACE_OS::snprintf
01236                       (bp, bspace, format,
01237                        static_cast<int> (this->getpid ()));
01238                   else
01239                     this_len = ACE_OS::sprintf
01240                       (bp, format, static_cast<int> (this->getpid ()));
01241                   ACE_UPDATE_COUNT (bspace, this_len);
01242                   break;
01243 
01244                 case 'p':             // <errno> string, ala perror()
01245                   {
01246                     errno = 0;
01247                     char *msg;
01248                     msg = ACE_OS::strerror (ACE::map_errno (this->errnum ()));
01249                     // Windows can try to translate the errnum using
01250                     // system calls if strerror() doesn't get anything useful.
01251 #if defined (ACE_WIN32)
01252                     if (errno == 0)
01253                       {
01254 #endif
01255 
01256 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01257                         ACE_OS::strcpy (fp, ACE_LIB_TEXT ("ls: %ls"));
01258 #else
01259                         ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s: %s"));
01260 #endif
01261                         if (can_check)
01262                           this_len = ACE_OS::snprintf
01263                             (bp, bspace, format, va_arg (argp, ACE_TCHAR *),
01264                              ACE_TEXT_CHAR_TO_TCHAR (msg));
01265                         else
01266                           this_len = ACE_OS::sprintf
01267                             (bp, format, va_arg (argp, ACE_TCHAR *),
01268                              ACE_TEXT_CHAR_TO_TCHAR (msg));
01269 #if defined (ACE_WIN32)
01270                       }
01271                     else
01272                       {
01273                         errno = ACE::map_errno (this->errnum ());
01274                         ACE_TCHAR *lpMsgBuf = 0;
01275 
01276      // PharLap can't do FormatMessage, so try for socket
01277      // error.
01278 # if !defined (ACE_HAS_PHARLAP)
01279                         ACE_TEXT_FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
01280                                                   | FORMAT_MESSAGE_MAX_WIDTH_MASK
01281                                                   | FORMAT_MESSAGE_FROM_SYSTEM,
01282                                                   0,
01283                                                   errno,
01284                                                   MAKELANGID (LANG_NEUTRAL,
01285                                                               SUBLANG_DEFAULT),
01286                                                               // Default language
01287                                                   (ACE_TCHAR *) &lpMsgBuf,
01288                                                   0,
01289                                                   0);
01290 # endif /* ACE_HAS_PHARLAP */
01291 
01292                         // If we don't get a valid response from
01293                         // <FormatMessage>, we'll assume this is a
01294                         // WinSock error and so we'll try to convert
01295                         // it into a string.  If this doesn't work it
01296                         // returns "unknown error" which is fine for
01297                         // our purposes.
01298                         if (lpMsgBuf == 0)
01299                           {
01300                             const ACE_TCHAR *message =
01301                               ACE::sock_error (errno);
01302                             ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s: %s"));
01303                             if (can_check)
01304                               this_len = ACE_OS::snprintf
01305                                 (bp, bspace, format,
01306                                  va_arg (argp, const ACE_TCHAR *),
01307                                  message);
01308                             else
01309                               this_len = ACE_OS::sprintf
01310                                 (bp, format,
01311                                  va_arg (argp, const ACE_TCHAR *),
01312                                  message);
01313                           }
01314                         else
01315                           {
01316                             ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s: %s"));
01317                             if (can_check)
01318                               this_len = ACE_OS::snprintf
01319                                 (bp, bspace, format,
01320                                  va_arg (argp, ACE_TCHAR *),
01321                                  lpMsgBuf);
01322                             else
01323                               this_len = ACE_OS::sprintf
01324                                 (bp, format,
01325                                  va_arg (argp, ACE_TCHAR *),
01326                                  lpMsgBuf);
01327                             // Free the buffer.
01328                             ::LocalFree (lpMsgBuf);
01329                           }
01330                       }
01331 #endif /* ACE_WIN32 */
01332                     ACE_UPDATE_COUNT (bspace, this_len);
01333                     break;
01334                   }
01335 
01336                 case 'M': // Print the name of the priority of the message.
01337 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01338                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("ls"));
01339 #else
01340                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01341 #endif
01342                   if (can_check)
01343                     this_len = ACE_OS::snprintf
01344                       (bp, bspace, format,
01345                        ACE_Log_Record::priority_name (log_priority));
01346                   else
01347                     this_len = ACE_OS::sprintf
01348                       (bp, format,
01349                        ACE_Log_Record::priority_name (log_priority));
01350                   ACE_UPDATE_COUNT (bspace, this_len);
01351                   break;
01352 
01353                 case 'm': // Format the string assocated with the errno value.
01354                   {
01355                     errno = 0;
01356                     char *msg;
01357                     msg = ACE_OS::strerror (ACE::map_errno (this->errnum ()));
01358                     // Windows can try to translate the errnum using
01359                     // system calls if strerror() doesn't get anything useful.
01360 #if defined (ACE_WIN32)
01361                     if (errno == 0)
01362                       {
01363 #endif
01364 
01365 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01366                         ACE_OS::strcpy (fp, ACE_LIB_TEXT ("ls"));
01367 #else /* ACE_WIN32 && ACE_USES_WCHAR */
01368                         ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01369 #endif
01370                         if (can_check)
01371                           this_len = ACE_OS::snprintf
01372                             (bp, bspace, format, ACE_TEXT_CHAR_TO_TCHAR (msg));
01373                         else
01374                           this_len = ACE_OS::sprintf
01375                             (bp, format, ACE_TEXT_CHAR_TO_TCHAR (msg));
01376 #if defined (ACE_WIN32)
01377                       }
01378                     else
01379                       {
01380                         errno = ACE::map_errno (this->errnum ());
01381                         ACE_TCHAR *lpMsgBuf = 0;
01382 
01383      // PharLap can't do FormatMessage, so try for socket
01384      // error.
01385 # if !defined (ACE_HAS_PHARLAP)
01386                         ACE_TEXT_FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
01387                                                   | FORMAT_MESSAGE_MAX_WIDTH_MASK
01388                                                   | FORMAT_MESSAGE_FROM_SYSTEM,
01389                                                   0,
01390                                                   errno,
01391                                                   MAKELANGID (LANG_NEUTRAL,
01392                                                               SUBLANG_DEFAULT),
01393                                                               // Default language
01394                                                   (ACE_TCHAR *) &lpMsgBuf,
01395                                                   0,
01396                                                   0);
01397 # endif /* ACE_HAS_PHARLAP */
01398 
01399                         // If we don't get a valid response from
01400                         // <FormatMessage>, we'll assume this is a
01401                         // WinSock error and so we'll try to convert
01402                         // it into a string.  If this doesn't work it
01403                         // returns "unknown error" which is fine for
01404                         // our purposes.
01405                         if (lpMsgBuf == 0)
01406                           {
01407                             const ACE_TCHAR *message =
01408                               ACE::sock_error (errno);
01409                             ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01410                             if (can_check)
01411                               this_len = ACE_OS::snprintf
01412                                 (bp, bspace, format, message);
01413                             else
01414                               this_len = ACE_OS::sprintf (bp, format, message);
01415                           }
01416                         else
01417                           {
01418                             ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01419                             if (can_check)
01420                               this_len = ACE_OS::snprintf
01421                                 (bp, bspace, format, lpMsgBuf);
01422                             else
01423                               this_len = ACE_OS::sprintf
01424                                 (bp, format, lpMsgBuf);
01425                             // Free the buffer.
01426                             ::LocalFree (lpMsgBuf);
01427                           }
01428                       }
01429 #endif /* ACE_WIN32 */
01430                     ACE_UPDATE_COUNT (bspace, this_len);
01431                     break;
01432                   }
01433 
01434                 case 'R': // Format the return status of the operation.
01435                   this->op_status (va_arg (argp, int));
01436                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("d"));
01437                   if (can_check)
01438                     this_len = ACE_OS::snprintf
01439                       (bp, bspace, format, this->op_status ());
01440                   else
01441                     this_len = ACE_OS::sprintf
01442                       (bp, format, this->op_status ());
01443                   ACE_UPDATE_COUNT (bspace, this_len);
01444                   break;
01445 
01446                 case '{': // Increment the trace_depth, then indent
01447                   skip_nul_locate = 1;
01448                   (void) this->inc ();
01449                   break;
01450 
01451                 case '}': // indent, then decrement trace_depth
01452                   skip_nul_locate = 1;
01453                   (void) this->dec ();
01454                   break;
01455 
01456                 case '$': // insert a newline, then indent the next line
01457                           // according to %I
01458                   *bp++ = '\n';
01459                   --bspace;
01460                   /* fallthrough */
01461 
01462                 case 'I': // Indent with nesting_depth*width spaces
01463                   // Caller can do %*I to override nesting indent, and
01464                   // if %*I was done, wp has the extracted width.
01465 #if defined (ACE_HAS_TRACE)
01466                   if (0 == wp)
01467                     wp = ACE_Trace::get_nesting_indent ();
01468 #else
01469                   if (0 == wp)
01470                     wp = 4;
01471 #endif /* ACE_HAS_TRACE */
01472                   wp *= this->trace_depth_;
01473                   if (static_cast<size_t> (wp) > bspace)
01474                     wp = static_cast<int> (bspace);
01475                   for (tmp_indent = wp;
01476                        tmp_indent;
01477                        --tmp_indent)
01478                     *bp++ = ' ';
01479 
01480                   *bp = '\0';
01481                   bspace -= static_cast<size_t> (wp);
01482                   skip_nul_locate = 1;
01483                   break;
01484 
01485                 case 'r': // Run (invoke) this subroutine.
01486                   {
01487                     long osave = ACE_Log_Msg::msg_off_;
01488 
01489                     if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
01490                                          ACE_Log_Msg::SILENT) &&
01491                         bspace > 1)
01492                       {
01493                         *bp++ = '{';
01494                         --bspace;
01495                       }
01496                     ACE_Log_Msg::msg_off_ =  bp - this->msg_;
01497 
01498                     (*va_arg (argp, PTF))();
01499 
01500                     if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
01501                                          ACE_Log_Msg::SILENT) &&
01502                         bspace > (1 + ACE_OS::strlen (bp)))
01503                       {
01504                         bspace -= (ACE_OS::strlen (bp) + 1);
01505                         bp += ACE_OS::strlen (bp);
01506                         *bp++ =  '}';
01507                       }
01508                     *bp = '\0';
01509                     skip_nul_locate = 1;
01510                     ACE_Log_Msg::msg_off_ = osave;
01511                     break;
01512                   }
01513 
01514                 case 'S': // format the string for with this signal number.
01515                   {
01516                     int sig = va_arg (argp, int);
01517 #if defined (ACE_HAS_SYS_SIGLIST)
01518                     if (sig >= 0 && sig < ACE_NSIG)
01519                       {
01520                         ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01521                         if (can_check)
01522                           this_len = ACE_OS::snprintf
01523                             (bp, bspace, format, _sys_siglist[sig]);
01524                         else
01525                           this_len = ACE_OS::sprintf
01526                             (bp, format, _sys_siglist[sig]);
01527                       }
01528                     else
01529                       {
01530                         if (can_check)
01531                           this_len = ACE_OS::snprintf
01532                             (bp, bspace,
01533                              ACE_LIB_TEXT("<unknown signal> %d"), sig);
01534                         else
01535                           this_len = ACE_OS::sprintf
01536                             (bp, ACE_LIB_TEXT ("<unknown signal> %d"), sig);
01537                       }
01538 #else
01539                     if (can_check)
01540                       this_len = ACE_OS::snprintf
01541                         (bp, bspace, ACE_LIB_TEXT ("signal %d"), sig);
01542                     else
01543                       this_len = ACE_OS::sprintf
01544                         (bp, ACE_LIB_TEXT ("signal %d"), sig);
01545 #endif /* ACE_HAS_SYS_SIGLIST */
01546                     ACE_UPDATE_COUNT (bspace, this_len);
01547                     break;
01548                   }
01549 
01550                 case 'D': // Format the timestamp in month/day/year
01551                           // hour:minute:sec:usec format.
01552                   {
01553                     ACE_TCHAR day_and_time[35];
01554                     ACE::timestamp (day_and_time,
01555                                     sizeof day_and_time);
01556 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01557                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("ls"));
01558 #else
01559                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01560 #endif
01561                     if (can_check)
01562                       this_len = ACE_OS::snprintf
01563                         (bp, bspace, format, day_and_time);
01564                     else
01565                       this_len = ACE_OS::sprintf (bp, format, day_and_time);
01566                     ACE_UPDATE_COUNT (bspace, this_len);
01567                     break;
01568                   }
01569 
01570                 case 'T': // Format the timestamp in
01571                           // hour:minute:sec:usec format.
01572                   {
01573                     ACE_TCHAR day_and_time[35];
01574                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01575                     if (can_check)
01576                       this_len = ACE_OS::snprintf
01577                         (bp, bspace, format,
01578                          ACE::timestamp (day_and_time, sizeof day_and_time));
01579                     else
01580                       this_len = ACE_OS::sprintf
01581                         (bp, format, ACE::timestamp (day_and_time,
01582                                                      sizeof day_and_time));
01583                     ACE_UPDATE_COUNT (bspace, this_len);
01584                     break;
01585                   }
01586 
01587                 case 't': // Format thread id.
01588 #if defined (ACE_WIN32)
01589                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("u"));
01590                   if (can_check)
01591                     this_len = ACE_OS::snprintf
01592                       (bp, bspace, format,
01593                        static_cast<unsigned> (ACE_Thread::self ()));
01594                   else
01595                     this_len =
01596                       ACE_OS::sprintf (bp,
01597                                        format,
01598                                        static_cast <unsigned> (ACE_Thread::self ()));
01599 #elif defined (ACE_AIX_VERS) && (ACE_AIX_VERS <= 402)
01600                   // AIX's pthread_t (ACE_hthread_t) is a pointer, and it's
01601                   // a little ugly to send that through a %u format.  So,
01602                   // get the kernel thread ID (tid_t) via thread_self() and
01603                   // display that instead.
01604                   // This isn't conditionalized on ACE_HAS_THREAD_SELF because
01605                   // 1. AIX 4.2 doesn't have that def anymore (it messes up
01606                   //    other things)
01607                   // 2. OSF/1 V3.2 has that def, and I'm not sure what affect
01608                   //   this would have on that.
01609                   // -Steve Huston, 19-Aug-97
01610                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("u"));
01611                   if (can_check)
01612                     this_len = ACE_OS::snprintf
01613                       (bp, bspace, format, thread_self());
01614                   else
01615                     this_len = ACE_OS::sprintf (bp, format, thread_self());
01616 #elif defined (DIGITAL_UNIX)
01617                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("u"));
01618                   {
01619                     int id =
01620 #  if defined (ACE_HAS_THREADS)
01621                       pthread_getselfseq_np ();
01622 #  else
01623                       ACE_Thread::self ();
01624 #  endif /* ACE_HAS_THREADS */
01625 
01626                       if (can_check)
01627                         this_len = ACE_OS::snprintf (bp, bspace, format, id);
01628                       else
01629                         this_len = ACE_OS::sprintf (bp, format, id);
01630                   }
01631 #else
01632                   ACE_hthread_t t_id;
01633                   ACE_Thread::self (t_id);
01634 
01635 #  if defined (ACE_MVS) || defined (ACE_TANDEM_T1248_PTHREADS)
01636                   // MVS's pthread_t is a struct... yuck. So use the ACE 5.0
01637                   // code for it.
01638                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("u"));
01639                   if (can_check)
01640                     this_len = ACE_OS::snprintf (bp, bspace, format, t_id);
01641                   else
01642                     this_len = ACE_OS::sprintf (bp, format, t_id);
01643 #  else
01644                   // Yes, this is an ugly C-style cast, but the correct
01645                   // C++ cast is different depending on whether the t_id
01646                   // is an integral type or a pointer type. FreeBSD uses
01647                   // a pointer type, but doesn't have a _np function to
01648                   // get an integral type, like the OSes above.
01649                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("lu"));
01650                   if (can_check)
01651                     this_len = ACE_OS::snprintf
01652                       (bp, bspace, format, (unsigned long)t_id);
01653                   else
01654                     this_len = ACE_OS::sprintf
01655                       (bp, format, (unsigned long)t_id);
01656 #  endif /* ACE_MWS || ACE_TANDEM_T1248_PTHREADS */
01657 
01658 #endif /* ACE_WIN32 */
01659                   ACE_UPDATE_COUNT (bspace, this_len);
01660                   break;
01661 
01662                 case 's':                       // String
01663                   {
01664 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01665                     wchar_t *str = va_arg (argp, wchar_t *);
01666                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("ls"));
01667 #else /* ACE_WIN32 && ACE_USES_WCHAR */
01668                     ACE_TCHAR *str = va_arg (argp, ACE_TCHAR *);
01669                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01670 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
01671                     if (can_check)
01672                       this_len = ACE_OS::snprintf
01673                         (bp, bspace, format, str ? str : ACE_LIB_TEXT ("(null)"));
01674                     else
01675                       this_len = ACE_OS::sprintf
01676                         (bp, format, str ? str : ACE_LIB_TEXT ("(null)"));
01677                     ACE_UPDATE_COUNT (bspace, this_len);
01678                   }
01679                   break;
01680 
01681                 case 'C':         // Char string, Unicode for Win32/WCHAR
01682                   {
01683                     ACE_TCHAR *cstr = va_arg (argp, ACE_TCHAR *);
01684 #if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01685                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("S"));
01686 #else /* ACE_WIN32 && ACE_USES_WCHAR */
01687                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01688 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
01689                     if (can_check)
01690                       this_len = ACE_OS::snprintf
01691                         (bp, bspace, format, cstr ? cstr : ACE_LIB_TEXT ("(null)"));
01692                     else
01693                       this_len = ACE_OS::sprintf
01694                         (bp, format, cstr ? cstr : ACE_LIB_TEXT ("(null)"));
01695                     ACE_UPDATE_COUNT (bspace, this_len);
01696                   }
01697                   break;
01698 
01699                 case 'W':
01700                   {
01701 #if defined (ACE_WIN32)
01702                     ACE_TCHAR *wstr = va_arg (argp, ACE_TCHAR *);
01703 # if defined (ACE_USES_WCHAR)
01704                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01705 # else /* ACE_USES_WCHAR */
01706                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("S"));
01707 # endif /* ACE_USES_WCHAR */
01708                     if (can_check)
01709                       this_len = ACE_OS::snprintf
01710                         (bp, bspace, format, wstr ? wstr : ACE_LIB_TEXT ("(null)"));
01711                     else
01712                       this_len = ACE_OS::sprintf
01713                         (bp, format, wstr ? wstr : ACE_LIB_TEXT ("(null)"));
01714 #elif defined (ACE_HAS_WCHAR)
01715                     wchar_t *wchar_str = va_arg (argp, wchar_t *);
01716 # if defined (HPUX)
01717                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("S"));
01718 # else
01719                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("ls"));
01720 # endif /* HPUX */
01721                     if (can_check)
01722                       this_len = ACE_OS::snprintf
01723                         (bp, bspace, format, wchar_str);
01724                     else
01725                       this_len = ACE_OS::sprintf
01726                         (bp, format, wchar_str);
01727 #endif /* ACE_WIN32 / ACE_HAS_WCHAR */
01728                     ACE_UPDATE_COUNT (bspace, this_len);
01729                   }
01730                   break;
01731 
01732                 case 'w':              // Wide character
01733 #if defined (ACE_WIN32)
01734 # if defined (ACE_USES_WCHAR)
01735                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("c"));
01736 # else /* ACE_USES_WCHAR */
01737                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("C"));
01738 # endif /* ACE_USES_WCHAR */
01739                   if (can_check)
01740                     this_len = ACE_OS::snprintf
01741                       (bp, bspace, format, va_arg (argp, int));
01742                   else
01743                     this_len = ACE_OS::sprintf
01744                       (bp, format, va_arg (argp, int));
01745 #elif defined (ACE_USES_WCHAR)
01746 # if defined (HPUX)
01747                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("C"));
01748 # else
01749                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("lc"));
01750 # endif /* HPUX */
01751                   if (can_check)
01752                     this_len = ACE_OS::snprintf
01753                       (bp, bspace, format, va_arg (argp, wint_t));
01754                   else
01755                     this_len = ACE_OS::sprintf
01756                       (bp, format, va_arg (argp, wint_t));
01757 #else /* ACE_WIN32 */
01758                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("u"));
01759                   if (can_check)
01760                     this_len = ACE_OS::snprintf
01761                       (bp, bspace, format, va_arg (argp, int));
01762                   else
01763                     this_len = ACE_OS::sprintf
01764                       (bp, format, va_arg (argp, int));
01765 #endif /* ACE_WIN32 */
01766                   ACE_UPDATE_COUNT (bspace, this_len);
01767                   break;
01768 
01769                 case 'z':              // ACE_OS::WChar character
01770                   {
01771                     // On some platforms sizeof (wchar_t) can be 2
01772                     // on the others 4 ...
01773                     wchar_t wtchar =
01774                       static_cast<wchar_t> (va_arg (argp, int));
01775 #if defined (ACE_WIN32)
01776 # if defined (ACE_USES_WCHAR)
01777                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("c"));
01778 # else /* ACE_USES_WCHAR */
01779                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("C"));
01780 # endif /* ACE_USES_WCHAR */
01781 #elif defined (ACE_USES_WCHAR)
01782 # if defined (HPUX)
01783                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("C"));
01784 # else
01785                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("lc"));
01786 # endif /* HPUX */
01787 #else /* ACE_WIN32 */
01788                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("u"));
01789 #endif /* ACE_WIN32 */
01790                     if (can_check)
01791                       this_len = ACE_OS::snprintf (bp, bspace, format, wtchar);
01792                     else
01793                       this_len = ACE_OS::sprintf (bp, format, wtchar);
01794                     ACE_UPDATE_COUNT (bspace, this_len);
01795                     break;
01796                   }
01797 
01798                  case 'Z':              // ACE_OS::WChar character string
01799                   {
01800                     ACE_OS::WChar *wchar_str = va_arg (argp, ACE_OS::WChar*);
01801                     if (wchar_str == 0)
01802                       break;
01803 
01804                     wchar_t *wchar_t_str = 0;
01805                     if (sizeof (ACE_OS::WChar) != sizeof (wchar_t))
01806                       {
01807                         size_t len = ACE_OS::wslen (wchar_str) + 1;
01808                         ACE_NEW_NORETURN(wchar_t_str, wchar_t[len]);
01809                         if (wchar_t_str == 0)
01810                           break;
01811 
01812                         for (size_t i = 0; i < len; ++i)
01813                           {
01814                             wchar_t_str[i] = wchar_str[i];
01815                           }
01816                       }
01817 
01818                     if (wchar_t_str == 0)
01819                       {
01820                         wchar_t_str = reinterpret_cast<wchar_t*> (wchar_str);
01821                       }
01822 #if defined (ACE_WIN32)
01823 # if defined (ACE_USES_WCHAR)
01824                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("s"));
01825 # else /* ACE_USES_WCHAR */
01826                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("S"));
01827 # endif /* ACE_USES_WCHAR */
01828 #elif defined (ACE_HAS_WCHAR)
01829 # if defined (HPUX)
01830                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("S"));
01831 # else
01832                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("ls"));
01833 # endif /* HPUX */
01834 #endif /* ACE_WIN32 / ACE_HAS_WCHAR */
01835                   if (can_check)
01836                     this_len = ACE_OS::snprintf
01837                       (bp, bspace, format, wchar_t_str);
01838                   else
01839                     this_len = ACE_OS::sprintf (bp, format, wchar_t_str);
01840                   if(sizeof(ACE_OS::WChar) != sizeof(wchar_t))
01841                     {
01842                       delete wchar_t_str;
01843                     }
01844                   ACE_UPDATE_COUNT (bspace, this_len);
01845                   break;
01846                   }
01847 
01848                 case 'c':
01849 #if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01850                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("C"));
01851 #else
01852                   ACE_OS::strcpy (fp, ACE_LIB_TEXT ("c"));
01853 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
01854                   if (can_check)
01855                     this_len = ACE_OS::snprintf
01856                       (bp, bspace, format, va_arg (argp, int));
01857                   else
01858                     this_len = ACE_OS::sprintf
01859                       (bp, format, va_arg (argp, int));
01860                   ACE_UPDATE_COUNT (bspace, this_len);
01861                   break;
01862 
01863                 case 'd': case 'i': case 'o':
01864                 case 'u': case 'x': case 'X':
01865                   fp[0] = *format_str;
01866                   fp[1] = '\0';
01867                   if (can_check)
01868                     this_len = ACE_OS::snprintf
01869                       (bp, bspace, format, va_arg (argp, int));
01870                   else
01871                     this_len = ACE_OS::sprintf
01872                       (bp, format, va_arg (argp, int));
01873                   ACE_UPDATE_COUNT (bspace, this_len);
01874                   break;
01875 
01876                 case 'F': case 'f': case 'e': case 'E':
01877                 case 'g': case 'G':
01878                   fp[0] = *format_str;
01879                   fp[1] = '\0';
01880                   if (can_check)
01881                     this_len = ACE_OS::snprintf
01882                       (bp, bspace, format, va_arg (argp, double));
01883                   else
01884                     this_len = ACE_OS::sprintf
01885                       (bp, format, va_arg (argp, double));
01886                   ACE_UPDATE_COUNT (bspace, this_len);
01887                   break;
01888 
01889                 case 'Q':
01890 #if defined (ACE_LACKS_LONGLONG_T) || defined (ACE_LACKS_UNSIGNEDLONGLONG_T)
01891                   {
01892                     // This relies on the ACE_U_LongLong storage layout.
01893                     ACE_UINT32 hi = va_arg (argp, ACE_UINT32);
01894                     ACE_UINT32 lo = va_arg (argp, ACE_UINT32);
01895                     if (hi > 0)
01896                       this_len = ACE_OS::sprintf (bp,
01897                                                   "0x%lx%0*lx",
01898                                                   hi,
01899                                                   2 * sizeof lo,
01900                                                   lo);
01901                     else
01902                       this_len = ACE_OS::sprintf (bp, "0x%lx", lo);
01903                   }
01904 #else  /* ! ACE_LACKS_LONGLONG_T */
01905                   {
01906                     const ACE_TCHAR *fmt = ACE_UINT64_FORMAT_SPECIFIER;
01907                     ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
01908                     if (can_check)
01909                       this_len = ACE_OS::snprintf (bp, bspace,
01910                                                    format,
01911                                                    va_arg (argp, ACE_UINT64));
01912                     else
01913                       this_len = ACE_OS::sprintf (bp,
01914                                                   format,
01915                                                   va_arg (argp, ACE_UINT64));
01916                   }
01917 #endif /* ! ACE_LACKS_LONGLONG_T || ACE_LACKS_UNSIGNEDLONGLONG_T */
01918                   ACE_UPDATE_COUNT (bspace, this_len);
01919                   break;
01920 
01921                 case 'q':
01922  #if defined (ACE_LACKS_LONGLONG_T)
01923                    // No implementation available yet, no ACE_INT64 emulation
01924                    // available yet
01925  #else  /* ! ACE_LACKS_LONGLONG_T */
01926                    {
01927                      const ACE_TCHAR *fmt = ACE_INT64_FORMAT_SPECIFIER;
01928                      ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
01929                      if (can_check)
01930                        this_len = ACE_OS::snprintf (bp, bspace,
01931                                                     format,
01932                                                     va_arg (argp, ACE_INT64));
01933                      else
01934                        this_len = ACE_OS::sprintf (bp,
01935                                                    format,
01936                                                    va_arg (argp, ACE_INT64));
01937                    }
01938  #endif /* ! ACE_LACKS_LONGLONG_T */
01939                    ACE_UPDATE_COUNT (bspace, this_len);
01940                    break;
01941 
01942                 case '@':
01943                     ACE_OS::strcpy (fp, ACE_LIB_TEXT ("p"));
01944                     if (can_check)
01945                       this_len = ACE_OS::snprintf
01946                         (bp, bspace, format, va_arg (argp, void*));
01947                     else
01948                       this_len = ACE_OS::sprintf
01949                         (bp, format, va_arg (argp, void*));
01950                     ACE_UPDATE_COUNT (bspace, this_len);
01951                     break;
01952 
01953                 default:
01954                   // So, it's not a legit format specifier after all...
01955                   // Copy from the original % to where we are now, then
01956                   // continue with whatever comes next.
01957                   while (start_format != format_str && bspace > 0)
01958                     {
01959                       *bp++ = *start_format++;
01960                       --bspace;
01961                     }
01962                   if (bspace > 0)
01963                     {
01964                       *bp++ = *format_str;
01965                       --bspace;
01966                     }
01967                   break;
01968                 }
01969 
01970               // Bump to the next char in the caller's format_str
01971               ++format_str;
01972             }
01973 
01974           if (!skip_nul_locate)
01975             while (*bp != '\0') // Locate end of bp.
01976               ++bp;
01977         }
01978     }
01979 
01980   *bp = '\0'; // Terminate bp, but don't auto-increment this!
01981 
01982   ssize_t result = 0;
01983 
01984   // Check that memory was not corrupted, if it corrupted we can't log anything
01985   // anymore because all our members could be corrupted.
01986   if (bp >= (this->msg_ + ACE_MAXLOGMSGLEN+1))
01987     {
01988       abort_prog = 1;
01989       ACE_OS::fprintf (stderr,
01990                        "The following logged message is too long!\n");
01991     }
01992   else
01993     {
01994       // Copy the message from thread-specific storage into the transfer
01995       // buffer (this can be optimized away by changing other code...).
01996       log_record.msg_data (this->msg ());
01997 
01998       // Write the <log_record> to the appropriate location.
01999       result = this->log (log_record,
02000                           abort_prog);
02001     }
02002 
02003   if (abort_prog)
02004     {
02005       // Since we are now calling abort instead of exit, this value is
02006       // not used.
02007       ACE_UNUSED_ARG (exit_value);
02008 
02009       // *Always* print a message to stderr if we're aborting.  We
02010       // don't use verbose, however, to avoid recursive aborts if
02011       // something is hosed.
02012       log_record.print (ACE_Log_Msg::local_host_, 0, stderr);
02013       ACE_OS::abort ();
02014     }
02015 
02016    return result;
02017 }
02018 
02019 #if !defined (ACE_WIN32)
02020 /**
02021  * @class ACE_Log_Msg_Sig_Guard
02022  *
02023  * @brief For use only by ACE_Log_Msg.
02024  *
02025  * Doesn't require the use of global variables or global
02026  * functions in an application).
02027  */
02028 class ACE_Log_Msg_Sig_Guard
02029 {
02030 private:
02031   ACE_Log_Msg_Sig_Guard (void);
02032   ~ACE_Log_Msg_Sig_Guard (void);
02033 
02034   /// Original signal mask.
02035   sigset_t omask_;
02036 
02037   friend ssize_t ACE_Log_Msg::log (ACE_Log_Record &log_record,
02038                                    int suppress_stderr);
02039 };
02040 
02041 ACE_Log_Msg_Sig_Guard::ACE_Log_Msg_Sig_Guard (void)
02042 {
02043 #if !defined (ACE_LACKS_UNIX_SIGNALS)
02044   ACE_OS::sigemptyset (&this->omask_);
02045 
02046 #  if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
02047   ACE_OS::sigprocmask (SIG_BLOCK,
02048                        ACE_OS_Object_Manager::default_mask (),
02049                        &this->omask_);
02050 #  else
02051   ACE_OS::thr_sigsetmask (SIG_BLOCK,
02052                           ACE_OS_Object_Manager::default_mask (),
02053                           &this->omask_);
02054 #  endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
02055 #endif /* ACE_LACKS_UNIX_SIGNALS */
02056 }
02057 
02058 ACE_Log_Msg_Sig_Guard::~ACE_Log_Msg_Sig_Guard (void)
02059 {
02060 #if !defined (ACE_LACKS_UNIX_SIGNALS)
02061 # if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
02062   ACE_OS::sigprocmask (SIG_SETMASK,
02063                        &this->omask_,
02064                        0);
02065 # else
02066   ACE_OS::thr_sigsetmask (SIG_SETMASK,
02067                           &this->omask_,
02068                           0);
02069 # endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
02070 #endif /* ! ACE_LACKS_UNIX_SIGNALS */
02071 }
02072 #endif /* ! ACE_WIN32 */
02073 
02074 ssize_t
02075 ACE_Log_Msg::log (ACE_Log_Record &log_record,
02076                   int suppress_stderr)
02077 {
02078   ssize_t result = 0;
02079 
02080   // Format the message and print it to stderr and/or ship it off to
02081   // the log_client daemon, and/or print it to the ostream.  Of
02082   // course, only print the message if "SILENT" mode is disabled.
02083   if (ACE_BIT_DISABLED (ACE_Log_Msg::flags_,
02084                         ACE_Log_Msg::SILENT))
02085     {
02086       int tracing = this->tracing_enabled ();
02087       this->stop_tracing ();
02088 
02089 #if !defined (ACE_WIN32)
02090       // Make this block signal-safe.
02091       ACE_Log_Msg_Sig_Guard sb;
02092 #endif /* !ACE_WIN32 */
02093 
02094       // Do the callback, if needed, before acquiring the lock
02095       // to avoid holding the lock during the callback so we don't
02096       // have deadlock if the callback uses the logger.
02097       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
02098                            ACE_Log_Msg::MSG_CALLBACK)
02099           && this->msg_callback () != 0)
02100         this->msg_callback ()->log (log_record);
02101 
02102       // Make sure that the lock is held during all this.
02103       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
02104                                 *ACE_Log_Msg_Manager::get_lock (),
02105                                 -1));
02106 
02107       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
02108                            ACE_Log_Msg::STDERR)
02109           && !suppress_stderr) // This is taken care of by our caller.
02110         log_record.print (ACE_Log_Msg::local_host_,
02111                           ACE_Log_Msg::flags_,
02112                           stderr);
02113 
02114       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM) ||
02115           ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG) ||
02116           ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER))
02117         {
02118           // Be sure that there is a message_queue_, with multiple threads.
02119           ACE_MT (ACE_Log_Msg_Manager::init_backend ());
02120         }
02121 
02122 
02123       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER) ||
02124           ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG))
02125         {
02126           result =
02127             ACE_Log_Msg_Manager::log_backend_->log (log_record);
02128         }
02129 
02130       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM) &&
02131           ACE_Log_Msg_Manager::custom_backend_ != 0)
02132         {
02133           result =
02134             ACE_Log_Msg_Manager::custom_backend_->log (log_record);
02135         }
02136 
02137 
02138       // This must come last, after the other two print operations
02139       // (see the <ACE_Log_Record::print> method for details).
02140       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
02141                            ACE_Log_Msg::OSTREAM)
02142           && this->msg_ostream () != 0)
02143         log_record.print (ACE_Log_Msg::local_host_,
02144                           ACE_Log_Msg::flags_,
02145 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
02146                           static_cast<FILE *> (this->msg_ostream ())
02147 #else  /* ! ACE_LACKS_IOSTREAM_TOTALLY */
02148                           *this->msg_ostream ()
02149 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
02150                           );
02151 
02152       if (tracing)
02153         this->start_tracing ();
02154    }
02155 
02156   return result;
02157 }
02158 
02159 // Calls log to do the actual print, but formats first.
02160 
02161 int
02162 ACE_Log_Msg::log_hexdump (ACE_Log_Priority log_priority,
02163                           const char *buffer,
02164                           size_t size,
02165                           const ACE_TCHAR *text)
02166 {
02167   // Only print the message if <priority_mask_> hasn't been reset to
02168   // exclude this logging priority.
02169   if (this->log_priority_enabled (log_priority) == 0)
02170     return 0;
02171 
02172   ACE_TCHAR* buf = 0;
02173   const size_t buf_sz =
02174     ACE_Log_Record::MAXLOGMSGLEN - ACE_Log_Record::VERBOSE_LEN - 58;
02175   ACE_NEW_RETURN (buf, ACE_TCHAR[buf_sz], -1);
02176 
02177   ACE_TCHAR *msg_buf = 0;
02178   const size_t text_sz = text ? ACE_OS::strlen(text) : 0;
02179   ACE_NEW_RETURN (msg_buf,
02180                   ACE_TCHAR[text_sz + 58],
02181                  -1);
02182 
02183   buf[0] = 0; // in case size = 0
02184 
02185   const size_t len = ACE::format_hexdump
02186     (buffer, size, buf, buf_sz / sizeof (ACE_TCHAR) - text_sz);
02187 
02188   int sz = 0;
02189 
02190   if (text)
02191     sz = ACE_OS::sprintf (msg_buf,
02192                           ACE_LIB_TEXT ("%s - "),
02193                           text);
02194 
02195   sz += ACE_OS::sprintf (msg_buf + sz,
02196                          ACE_LIB_TEXT ("HEXDUMP ")
02197                          ACE_SIZE_T_FORMAT_SPECIFIER
02198                          ACE_LIB_TEXT (" bytes"),
02199                          size);
02200 
02201   if (len < size)
02202     ACE_OS::sprintf (msg_buf + sz,
02203                      ACE_LIB_TEXT (" (showing first ")
02204                      ACE_SIZE_T_FORMAT_SPECIFIER
02205                      ACE_LIB_TEXT (" bytes)"),
02206                      len);
02207 
02208   // Now print out the formatted buffer.
02209   this->log (log_priority,
02210              ACE_LIB_TEXT ("%s\n%s"),
02211              msg_buf,
02212              buf);
02213 
02214   delete [] msg_buf;
02215   delete [] buf;
02216   return 0;
02217 }
02218 
02219 void
02220 ACE_Log_Msg::set (const char *filename,
02221                   int line,
02222                   int status,
02223                   int err,
02224                   int rs,
02225                   ACE_OSTREAM_TYPE *os,
02226                   ACE_Log_Msg_Callback *c)
02227 {
02228   ACE_TRACE ("ACE_Log_Msg::set");
02229   this->file (filename);
02230   this->linenum (line);
02231   this->op_status (status);
02232   this->errnum (err);
02233   this->restart (rs);
02234   this->msg_ostream (os);
02235   this->msg_callback (c);
02236 }
02237 
02238 void
02239 ACE_Log_Msg::conditional_set (const char *filename,
02240                               int line,
02241                               int status,
02242                               int err)
02243 {
02244   this->conditional_values_.is_set_ = 1;
02245   this->conditional_values_.file_ = filename;
02246   this->conditional_values_.line_ = line;
02247   this->conditional_values_.op_status_ = status;
02248   this->conditional_values_.errnum_ = err;
02249 }
02250 
02251 void
02252 ACE_Log_Msg::dump (void) const
02253 {
02254 #if defined (ACE_HAS_DUMP)
02255   ACE_TRACE ("ACE_Log_Msg::dump");
02256 
02257   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
02258   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("status_ = %d\n"), this->status_));
02259   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nerrnum_ = %d\n"), this->errnum_));
02260   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nlinenum_ = %d\n"), this->linenum_));
02261   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nfile_ = %C\n"), this->file_));
02262   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nmsg_ = %s\n"), this->msg_));
02263   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nrestart_ = %d\n"), this->restart_));
02264   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nostream_ = %@\n"), this->ostream_));
02265   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nmsg_callback_ = %@\n"),
02266               this->msg_callback_));
02267   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nprogram_name_ = %s\n"),
02268               this->program_name_ ? this->program_name_
02269                                   : ACE_LIB_TEXT ("<unknown>")));
02270   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nlocal_host_ = %s\n"),
02271               this->local_host_ ? this->local_host_
02272                                 : ACE_LIB_TEXT ("<unknown>")));
02273   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\npid_ = %d\n"), this->getpid ()));
02274   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nflags_ = 0x%x\n"), this->flags_));
02275   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntrace_depth_ = %d\n"),
02276               this->trace_depth_));
02277   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntrace_active_ = %d\n"),
02278               this->trace_active_));
02279   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntracing_enabled_ = %d\n"),
02280               this->tracing_enabled_));
02281   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\npriority_mask_ = 0x%x\n"),
02282               this->priority_mask_));
02283   if (this->thr_desc_ != 0 && this->thr_desc_->state () != 0)
02284     ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nthr_state_ = %d\n"),
02285                 this->thr_desc_->state ()));
02286   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nmsg_off_ = %d\n"), this->msg_off_));
02287 
02288   // Be sure that there is a message_queue_, with multiple threads.
02289   ACE_MT (ACE_Log_Msg_Manager::init_backend ());
02290 
02291   ACE_MT (ACE_Log_Msg_Manager::get_lock ()->dump ());
02292   // Synchronize output operations.
02293 
02294   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
02295 #endif /* ACE_HAS_DUMP */
02296 }
02297 
02298 void
02299 ACE_Log_Msg::op_status (int status)
02300 {
02301   this->status_ = status;
02302 }
02303 
02304 int
02305 ACE_Log_Msg::op_status (void)
02306 {
02307   return this->status_;
02308 }
02309 
02310 void
02311 ACE_Log_Msg::restart (int r)
02312 {
02313   this->restart_ = r;
02314 }
02315 
02316 int
02317 ACE_Log_Msg::restart (void)
02318 {
02319   return this->restart_;
02320 }
02321 
02322 int
02323 ACE_Log_Msg::errnum (void)
02324 {
02325   return this->errnum_;
02326 }
02327 
02328 void
02329 ACE_Log_Msg::errnum (int e)
02330 {
02331   this->errnum_ = e;
02332 }
02333 
02334 int
02335 ACE_Log_Msg::linenum (void)
02336 {
02337   return this->linenum_;
02338 }
02339 
02340 void
02341 ACE_Log_Msg::linenum (int l)
02342 {
02343   this->linenum_ = l;
02344 }
02345 
02346 int
02347 ACE_Log_Msg::inc (void)
02348 {
02349   return this->trace_depth_++;
02350 }
02351 
02352 int
02353 ACE_Log_Msg::dec (void)
02354 {
02355   return this->trace_depth_ == 0 ? 0 : --this->trace_depth_;
02356 }
02357 
02358 int
02359 ACE_Log_Msg::trace_depth (void)
02360 {
02361   return this->trace_depth_;
02362 }
02363 
02364 void
02365 ACE_Log_Msg::trace_depth (int depth)
02366 {
02367   this->trace_depth_ = depth;
02368 }
02369 
02370 int
02371 ACE_Log_Msg::trace_active (void)
02372 {
02373   return this->trace_active_;
02374 }
02375 
02376 void
02377 ACE_Log_Msg::trace_active (int value)
02378 {
02379   this->trace_active_ = value;
02380 }
02381 
02382 ACE_Thread_Descriptor *
02383 ACE_Log_Msg::thr_desc (void) const
02384 {
02385   return this->thr_desc_;
02386 }
02387 
02388 void
02389 ACE_Log_Msg::thr_desc (ACE_Thread_Descriptor *td)
02390 {
02391   this->thr_desc_ = td;
02392 
02393   if (td != 0)
02394     td->acquire_release ();
02395 }
02396 
02397 #if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) && defined(ACE_LEGACY_MODE)
02398 ACE_SEH_EXCEPT_HANDLER
02399 ACE_Log_Msg::seh_except_selector (void)
02400 {
02401   return ACE_OS_Object_Manager::seh_except_selector ();
02402 }
02403 
02404 ACE_SEH_EXCEPT_HANDLER
02405 ACE_Log_Msg::seh_except_selector (ACE_SEH_EXCEPT_HANDLER n)
02406 {
02407   return ACE_OS_Object_Manager::seh_except_selector (n);
02408 }
02409 
02410 ACE_SEH_EXCEPT_HANDLER
02411 ACE_Log_Msg::seh_except_handler (void)
02412 {
02413   return ACE_OS_Object_Manager::seh_except_handler ();
02414 }
02415 
02416 ACE_SEH_EXCEPT_HANDLER
02417 ACE_Log_Msg::seh_except_handler (ACE_SEH_EXCEPT_HANDLER n)
02418 {
02419   return ACE_OS_Object_Manager::seh_except_handler (n);
02420 }
02421 #endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS && ACE_LEGACY_MODE */
02422 
02423 // Enable the tracing facility on a per-thread basis.
02424 
02425 void
02426 ACE_Log_Msg::start_tracing (void)
02427 {
02428   this->tracing_enabled_ = 1;
02429 }
02430 
02431 // Disable the tracing facility on a per-thread basis.
02432 
02433 void
02434 ACE_Log_Msg::stop_tracing (void)
02435 {
02436   this->tracing_enabled_ = 0;
02437 }
02438 
02439 int
02440 ACE_Log_Msg::tracing_enabled (void)
02441 {
02442   return this->tracing_enabled_;
02443 }
02444 
02445 const char *
02446 ACE_Log_Msg::file (void)
02447 {
02448   return this->file_;
02449 }
02450 
02451 void
02452 ACE_Log_Msg::file (const char *s)
02453 {
02454   ACE_OS::strsncpy (this->file_, s, sizeof this->file_);
02455 }
02456 
02457 const ACE_TCHAR *
02458 ACE_Log_Msg::msg (void)
02459 {
02460   return this->msg_ + ACE_Log_Msg::msg_off_;
02461 }
02462 
02463 void
02464 ACE_Log_Msg::msg (const ACE_TCHAR *m)
02465 {
02466   ACE_OS::strsncpy (this->msg_, m,
02467                     ((ACE_MAXLOGMSGLEN+1) / sizeof (ACE_TCHAR)));
02468 }
02469 
02470 ACE_Log_Msg_Callback *
02471 ACE_Log_Msg::msg_callback (void) const
02472 {
02473   return this->msg_callback_;
02474 }
02475 
02476 ACE_Log_Msg_Callback *
02477 ACE_Log_Msg::msg_callback (ACE_Log_Msg_Callback *c)
02478 {
02479   ACE_Log_Msg_Callback *old = this->msg_callback_;
02480   this->msg_callback_ = c;
02481   return old;
02482 }
02483 
02484 ACE_Log_Msg_Backend *
02485 ACE_Log_Msg::msg_backend (ACE_Log_Msg_Backend *b)
02486 {
02487   ACE_TRACE ("ACE_Log_Msg::msg_backend");
02488   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
02489                             *ACE_Log_Msg_Manager::get_lock (), 0));
02490 
02491   ACE_Log_Msg_Backend *tmp  = ACE_Log_Msg_Manager::custom_backend_;
02492   ACE_Log_Msg_Manager::custom_backend_ = b;
02493   return tmp;
02494 }
02495 
02496 ACE_Log_Msg_Backend *
02497 ACE_Log_Msg::msg_backend (void)
02498 {
02499   ACE_TRACE ("ACE_Log_Msg::msg_backend");
02500   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
02501                             *ACE_Log_Msg_Manager::get_lock (), 0));
02502 
02503   return ACE_Log_Msg_Manager::custom_backend_;
02504 }
02505 
02506 ACE_OSTREAM_TYPE *
02507 ACE_Log_Msg::msg_ostream (void) const
02508 {
02509   return this->ostream_;
02510 }
02511 
02512 void
02513 ACE_Log_Msg::msg_ostream (ACE_OSTREAM_TYPE *m, int delete_ostream)
02514 {
02515   if (this->ostream_ == m)
02516     return;
02517 
02518   if (this->delete_ostream_)
02519     {
02520 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
02521       ACE_OS::fclose (this->ostream_);
02522 #else
02523       delete this->ostream_;
02524 #endif
02525     }
02526 
02527   this->delete_ostream_ = delete_ostream;
02528   this->ostream_ = m;
02529 }
02530 
02531 void
02532 ACE_Log_Msg::msg_ostream (ACE_OSTREAM_TYPE *m)
02533 {
02534   this->ostream_ = m;
02535 }
02536 
02537 void
02538 ACE_Log_Msg::local_host (const ACE_TCHAR *s)
02539 {
02540   if (s)
02541     {
02542       ACE_OS::free ((void *) ACE_Log_Msg::local_host_);
02543       {
02544         ACE_NO_HEAP_CHECK;
02545 
02546         ACE_ALLOCATOR (ACE_Log_Msg::local_host_, ACE_OS::strdup (s));
02547       }
02548     }
02549 }
02550 
02551 const ACE_TCHAR *
02552 ACE_Log_Msg::local_host (void) const
02553 {
02554   return ACE_Log_Msg::local_host_;
02555 }
02556 
02557 pid_t
02558 ACE_Log_Msg::getpid (void) const
02559 {
02560   if (ACE_Log_Msg::pid_ == -1)
02561     ACE_Log_Msg::pid_ = ACE_OS::getpid ();
02562 
02563   return ACE_Log_Msg::pid_;
02564 }
02565 
02566 int
02567 ACE_Log_Msg::log_priority_enabled (ACE_Log_Priority log_priority,
02568                                    const char *,
02569                                    ...)
02570 {
02571   return this->log_priority_enabled (log_priority);
02572 }
02573 
02574 #if defined (ACE_USES_WCHAR)
02575 int
02576 ACE_Log_Msg::log_priority_enabled (ACE_Log_Priority log_priority,
02577                                    const wchar_t *,
02578                                    ...)
02579 {
02580   return this->log_priority_enabled (log_priority);
02581 }
02582 #endif /* ACE_USES_WCHAR */
02583 
02584 // ****************************************************************
02585 
02586 void
02587 ACE_Log_Msg::init_hook (ACE_OS_Log_Msg_Attributes &attributes
02588 # if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
02589                         , ACE_SEH_EXCEPT_HANDLER selector
02590                         , ACE_SEH_EXCEPT_HANDLER handler
02591 # endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
02592                                    )
02593 {
02594 # if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
02595   attributes.seh_except_selector_ = selector;
02596   attributes.seh_except_handler_ = handler;
02597 # endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
02598   if (ACE_Log_Msg::exists ())
02599     {
02600       ACE_Log_Msg *inherit_log = ACE_LOG_MSG;
02601       attributes.ostream_ = inherit_log->msg_ostream ();
02602       attributes.priority_mask_ = inherit_log->priority_mask ();
02603       attributes.tracing_enabled_ = inherit_log->tracing_enabled ();
02604       attributes.restart_ = inherit_log->restart ();
02605       attributes.trace_depth_ = inherit_log->trace_depth ();
02606     }
02607 }
02608 
02609 void
02610 ACE_Log_Msg::inherit_hook (ACE_OS_Thread_Descriptor *thr_desc,
02611                            ACE_OS_Log_Msg_Attributes &attributes)
02612 {
02613 #if !defined (ACE_THREADS_DONT_INHERIT_LOG_MSG)  && \
02614     !defined (ACE_HAS_MINIMAL_ACE_OS)
02615   // Inherit the logging features if the parent thread has an
02616   // <ACE_Log_Msg>.  Note that all of the following operations occur
02617   // within thread-specific storage.
02618   ACE_Log_Msg *new_log = ACE_LOG_MSG;
02619 
02620   // Note that we do not inherit the callback because this might have
02621   // been allocated off of the stack of the original thread, in which
02622   // case all hell would break loose...
02623 
02624   if (attributes.ostream_)
02625     {
02626       new_log->msg_ostream (attributes.ostream_);
02627       new_log->priority_mask (attributes.priority_mask_);
02628 
02629       if (attributes.tracing_enabled_)
02630         new_log->start_tracing ();
02631 
02632       new_log->restart (attributes.restart_);
02633       new_log->trace_depth (attributes.trace_depth_);
02634     }
02635 
02636   // @@ Now the TSS Log_Msg has been created, cache my thread
02637   // descriptor in.
02638 
02639   if (thr_desc != 0)
02640     // This downcast is safe.  We do it to avoid having to #include
02641     // ace/Thread_Manager.h.
02642     new_log->thr_desc (static_cast<ACE_Thread_Descriptor *> (thr_desc));
02643   // Block the thread from proceeding until
02644   // thread manager has thread descriptor ready.
02645 #endif /* ! ACE_THREADS_DONT_INHERIT_LOG_MSG  &&  ! ACE_HAS_MINIMAL_ACE_OS */
02646 }
02647 
02648 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:53 2006 for ACE by doxygen 1.3.6