/dep/acelite/ace/Log_Msg.cpp
C++ | 1441 lines | 986 code | 196 blank | 259 comment | 213 complexity | f690917c395ff68c77d3499ede44b9ca MD5 | raw file
- // $Id: Log_Msg.cpp 92052 2010-09-27 14:20:22Z vzykov $
- // We need this to get the status of ACE_NTRACE...
- #include "ace/config-all.h"
- // Turn off tracing for the duration of this file.
- #if defined (ACE_NTRACE)
- # undef ACE_NTRACE
- #endif /* ACE_NTRACE */
- #define ACE_NTRACE 1
- #include "ace/ACE.h"
- #include "ace/Thread_Manager.h"
- #include "ace/Guard_T.h"
- #include "ace/OS_NS_stdio.h"
- #include "ace/OS_NS_errno.h"
- #include "ace/OS_NS_sys_time.h"
- #include "ace/OS_NS_wchar.h"
- #include "ace/OS_NS_signal.h"
- #include "ace/os_include/os_typeinfo.h"
- #if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE != 0)
- # include "ace/Object_Manager_Base.h"
- #endif /* ! ACE_MT_SAFE */
- #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
- // FUZZ: disable check_for_streams_include
- # include "ace/streams.h"
- #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
- #if defined (ACE_HAS_TRACE)
- # include "ace/Trace.h"
- #endif /* ACE_HAS_TRACE */
- #include "ace/Log_Msg.h"
- #include "ace/Log_Msg_Callback.h"
- #include "ace/Log_Msg_IPC.h"
- #include "ace/Log_Msg_NT_Event_Log.h"
- #include "ace/Log_Msg_UNIX_Syslog.h"
- #include "ace/Log_Record.h"
- #include "ace/Recursive_Thread_Mutex.h"
- #include "ace/Stack_Trace.h"
- #include "ace/Atomic_Op.h"
- #if !defined (__ACE_INLINE__)
- #include "ace/Log_Msg.inl"
- #endif /* __ACE_INLINE__ */
- ACE_BEGIN_VERSIONED_NAMESPACE_DECL
- ACE_ALLOC_HOOK_DEFINE(ACE_Log_Msg)
- #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- bool ACE_Log_Msg::key_created_ = 0;
- # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
- defined (ACE_HAS_TSS_EMULATION)
- #if defined (ACE_MVS)
- static ACE_thread_key_t the_log_msg_tss_key =
- #if !defined(_LP64)
- { '\0','\0','\0','\0' };
- #else
- { '\0','\0','\0','\0','\0','\0','\0','\0' };
- #endif
- #else
- static ACE_thread_key_t the_log_msg_tss_key = 0;
- #endif /* defined (ACE_MVS) */
- ACE_thread_key_t *log_msg_tss_key (void)
- {
- return &the_log_msg_tss_key;
- }
- # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
- #else
- static ACE_Cleanup_Adapter<ACE_Log_Msg>* log_msg_cleanup = 0;
- class ACE_Msg_Log_Cleanup: public ACE_Cleanup_Adapter<ACE_Log_Msg>
- {
- public:
- virtual ~ACE_Msg_Log_Cleanup (void) {
- if (this == log_msg_cleanup)
- log_msg_cleanup = 0;
- }
- };
- #endif /* ACE_MT_SAFE */
- #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP)
- # define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_NT_Event_Log
- #elif !defined (ACE_LACKS_UNIX_SYSLOG) && !defined (ACE_HAS_WINCE)
- # define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_UNIX_Syslog
- #else
- # define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_IPC
- #endif /* ! ACE_WIN32 */
- // When doing ACE_OS::s[n]printf() calls in log(), we need to update
- // the space remaining in the output buffer based on what's returned from
- // the output function. If we could rely on more modern compilers, this
- // would be in an unnamed namespace, but it's a macro instead.
- // count is a size_t, len is an int and assumed to be non-negative.
- #define ACE_UPDATE_COUNT(COUNT, LEN) \
- do { if (static_cast<size_t> (LEN) > COUNT) COUNT = 0; \
- else COUNT -= static_cast<size_t> (LEN); \
- } while (0)
- /// Instance count for Log_Msg - used to know when dynamically
- /// allocated storage (program name and host name) can be safely
- /// deleted.
- int ACE_Log_Msg::instance_count_ = 0;
- /**
- * @class ACE_Log_Msg_Manager
- *
- * @brief Synchronize output operations.
- *
- * Provides global point of contact for all ACE_Log_Msg instances
- * in a process.
- *
- * For internal use by ACE, only!
- */
- class ACE_Log_Msg_Manager
- {
- public:
- static ACE_Log_Msg_Backend *log_backend_;
- static ACE_Log_Msg_Backend *custom_backend_;
- static u_long log_backend_flags_;
- static int init_backend (const u_long *flags = 0);
- #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- //FUZZ: disable check_for_lack_ACE_OS
- static void close (void) ACE_GCC_DESTRUCTOR_ATTRIBUTE;
- //FUZZ: enable check_for_lack_ACE_OS
- static ACE_Recursive_Thread_Mutex *get_lock (void);
- private:
- static ACE_Recursive_Thread_Mutex *lock_;
- #endif /* ! ACE_MT_SAFE */
- };
- ACE_Log_Msg_Backend *ACE_Log_Msg_Manager::log_backend_ = 0;
- ACE_Log_Msg_Backend *ACE_Log_Msg_Manager::custom_backend_ = 0;
- u_long ACE_Log_Msg_Manager::log_backend_flags_ = 0;
- int ACE_Log_Msg_Manager::init_backend (const u_long *flags)
- {
- // If flags have been supplied, and they are different from the flags
- // we had last time, then we may have to re-create the backend as a
- // different type.
- if (flags)
- {
- // Sanity check for custom backend.
- if (ACE_BIT_ENABLED (*flags, ACE_Log_Msg::CUSTOM) &&
- ACE_Log_Msg_Manager::custom_backend_ == 0)
- {
- return -1;
- }
- if ((ACE_BIT_ENABLED (*flags, ACE_Log_Msg::SYSLOG)
- && ACE_BIT_DISABLED (ACE_Log_Msg_Manager::log_backend_flags_, ACE_Log_Msg::SYSLOG))
- || (ACE_BIT_DISABLED (*flags, ACE_Log_Msg::SYSLOG)
- && ACE_BIT_ENABLED (ACE_Log_Msg_Manager::log_backend_flags_, ACE_Log_Msg::SYSLOG)))
- {
- delete ACE_Log_Msg_Manager::log_backend_;
- ACE_Log_Msg_Manager::log_backend_ = 0;
- }
- ACE_Log_Msg_Manager::log_backend_flags_ = *flags;
- }
- if (ACE_Log_Msg_Manager::log_backend_ == 0)
- {
- ACE_NO_HEAP_CHECK;
- #if (defined (WIN32) || !defined (ACE_LACKS_UNIX_SYSLOG)) && !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP)
- // Allocate the ACE_Log_Msg_Backend instance.
- if (ACE_BIT_ENABLED (ACE_Log_Msg_Manager::log_backend_flags_, ACE_Log_Msg::SYSLOG))
- ACE_NEW_RETURN (ACE_Log_Msg_Manager::log_backend_,
- ACE_LOG_MSG_SYSLOG_BACKEND,
- -1);
- else
- #endif /* defined (WIN32) && !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP) */
- ACE_NEW_RETURN (ACE_Log_Msg_Manager::log_backend_,
- ACE_Log_Msg_IPC,
- -1);
- }
- return 0;
- }
- #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- ACE_Recursive_Thread_Mutex *ACE_Log_Msg_Manager::lock_ = 0;
- ACE_Recursive_Thread_Mutex *
- ACE_Log_Msg_Manager::get_lock (void)
- {
- // This function is called by the first thread to create an ACE_Log_Msg
- // instance. It makes the call while holding a mutex, so we don't have
- // to grab another one here.
- if (ACE_Log_Msg_Manager::lock_ == 0)
- {
- ACE_NO_HEAP_CHECK;
- ACE_NEW_RETURN (ACE_Log_Msg_Manager::lock_,
- ACE_Recursive_Thread_Mutex,
- 0);
- }
- if (init_backend () == -1)
- return 0;
- return ACE_Log_Msg_Manager::lock_;
- }
- void
- ACE_Log_Msg_Manager::close (void)
- {
- #if defined (ACE_HAS_STHREADS) && ! defined (ACE_HAS_TSS_EMULATION) && ! defined (ACE_HAS_EXCEPTIONS)
- // Delete the (main thread's) Log_Msg instance. I think that this
- // is only "necessary" if exception handling is not enabled.
- // Without exception handling, main thread TSS destructors don't
- // seem to be called. It's not really necessary anyways, because
- // this one leak is harmless on Solaris.
- delete ACE_Log_Msg::instance ();
- #endif /* ACE_HAS_STHREADS && ! TSS_EMULATION && ! ACE_HAS_EXCEPTIONS */
- // Ugly, ugly, but don't know a better way.
- delete ACE_Log_Msg_Manager::lock_;
- ACE_Log_Msg_Manager::lock_ = 0;
- delete ACE_Log_Msg_Manager::log_backend_;
- ACE_Log_Msg_Manager::log_backend_ = 0;
- // we are never responsible for custom backend
- ACE_Log_Msg_Manager::custom_backend_ = 0;
- }
- # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
- defined (ACE_HAS_TSS_EMULATION)
- /* static */
- # if defined (ACE_HAS_THR_C_DEST)
- # define LOCAL_EXTERN_PREFIX extern "C"
- # else
- # define LOCAL_EXTERN_PREFIX
- # endif /* ACE_HAS_THR_C_DEST */
- LOCAL_EXTERN_PREFIX
- void
- ACE_TSS_CLEANUP_NAME (void *ptr)
- {
- // Delegate to thr_desc if this not has terminated
- ACE_Log_Msg* log_msg = (ACE_Log_Msg*) ptr;
- if (log_msg->thr_desc()!=0)
- log_msg->thr_desc()->log_msg_cleanup(log_msg);
- else
- delete log_msg;
- }
- # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
- #endif /* ! ACE_MT_SAFE */
- /* static */
- int
- ACE_Log_Msg::exists (void)
- {
- #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
- defined (ACE_HAS_TSS_EMULATION)
- void *tss_log_msg = 0; // The actual type is ACE_Log_Msg*, but we need this
- // void to keep G++ from complaining.
- // Get the tss_log_msg from thread-specific storage.
- return ACE_Log_Msg::key_created_
- && ACE_Thread::getspecific (*(log_msg_tss_key ()), &tss_log_msg) != -1
- && tss_log_msg != 0;
- # else
- # error "Platform must support thread-specific storage if threads are used."
- # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
- #else /* ! ACE_MT_SAFE */
- return 1;
- #endif /* ! ACE_MT_SAFE */
- }
- ACE_Log_Msg *
- ACE_Log_Msg::instance (void)
- {
- #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
- defined (ACE_HAS_TSS_EMULATION)
- // TSS Singleton implementation.
- if (!ACE_Log_Msg::key_created_)
- {
- ACE_thread_mutex_t *lock =
- reinterpret_cast<ACE_thread_mutex_t *> (
- ACE_OS_Object_Manager::preallocated_object
- [ACE_OS_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK]);
- if (1 == ACE_OS_Object_Manager::starting_up())
- //This function is called before ACE_OS_Object_Manager is
- //initialized. So the lock might not be valid. Assume it's
- //single threaded and so don't need the lock.
- ;
- else
- ACE_OS::thread_mutex_lock (lock);
- if (!ACE_Log_Msg::key_created_)
- {
- // Allocate the Singleton lock.
- ACE_Log_Msg_Manager::get_lock ();
- {
- ACE_NO_HEAP_CHECK;
- if (ACE_Thread::keycreate (log_msg_tss_key (),
- &ACE_TSS_CLEANUP_NAME) != 0)
- {
- if (1 == ACE_OS_Object_Manager::starting_up())
- //This function is called before ACE_OS_Object_Manager is
- //initialized. So the lock might not be valid. Assume it's
- //single threaded and so don't need the lock.
- ;
- else
- ACE_OS::thread_mutex_unlock (lock);
- return 0; // Major problems, this should *never* happen!
- }
- }
- ACE_Log_Msg::key_created_ = true;
- }
- if (1 == ACE_OS_Object_Manager::starting_up())
- //This function is called before ACE_OS_Object_Manager is
- //initialized. So the lock might not be valid. Assume it's
- //single threaded and so don't need the lock.
- ;
- else
- ACE_OS::thread_mutex_unlock (lock);
- }
- ACE_Log_Msg *tss_log_msg = 0;
- void *temp = 0;
- // Get the tss_log_msg from thread-specific storage.
- if (ACE_Thread::getspecific (*(log_msg_tss_key ()), &temp) == -1)
- return 0; // This should not happen!
- tss_log_msg = static_cast <ACE_Log_Msg *> (temp);
- // Check to see if this is the first time in for this thread.
- if (tss_log_msg == 0)
- {
- // Allocate memory off the heap and store it in a pointer in
- // thread-specific storage (on the stack...). Stop heap
- // checking, the memory will always be freed by the thread
- // rundown because of the TSS callback set up when the key was
- // created. This prevents from getting these blocks reported as
- // memory leaks.
- {
- ACE_NO_HEAP_CHECK;
- ACE_NEW_RETURN (tss_log_msg,
- ACE_Log_Msg,
- 0);
- // Store the dynamically allocated pointer in thread-specific
- // storage. It gets deleted via the ACE_TSS_cleanup function
- // when the thread terminates.
- if (ACE_Thread::setspecific (*(log_msg_tss_key()),
- reinterpret_cast<void *> (tss_log_msg))
- != 0)
- return 0; // Major problems, this should *never* happen!
- }
- }
- return tss_log_msg;
- # else
- # error "Platform must support thread-specific storage if threads are used."
- # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
- #else /* ! ACE_MT_SAFE */
- // We don't have threads, we cannot call
- // ACE_Log_Msg_Manager::get_lock () to initialize the logger
- // callback, so instead we do it here.
- if (ACE_Log_Msg_Manager::init_backend () == -1)
- return 0;
- // Singleton implementation.
- if (log_msg_cleanup == 0)
- {
- ACE_NEW_RETURN (log_msg_cleanup, ACE_Msg_Log_Cleanup, 0);
- // Register the instance for destruction at program termination.
- ACE_Object_Manager::at_exit (log_msg_cleanup,
- 0,
- typeid (*log_msg_cleanup).name ());
- }
- return &log_msg_cleanup->object ();
- #endif /* ! ACE_MT_SAFE */
- }
- // Not inlined to help prevent having to include OS.h just to
- // get ACE_DEBUG, et al, macros.
- int
- ACE_Log_Msg::last_error_adapter (void)
- {
- return ACE_OS::last_error ();
- }
- // Sets the flag in the default priority mask used to initialize
- // ACE_Log_Msg instances, as well as the current per-thread instance.
- void
- ACE_Log_Msg::enable_debug_messages (ACE_Log_Priority priority)
- {
- ACE_SET_BITS (ACE_Log_Msg::default_priority_mask_, priority);
- ACE_Log_Msg *i = ACE_Log_Msg::instance ();
- i->priority_mask (i->priority_mask () | priority);
- }
- // Clears the flag in the default priority mask used to initialize
- // ACE_Log_Msg instances, as well as the current per-thread instance.
- void
- ACE_Log_Msg::disable_debug_messages (ACE_Log_Priority priority)
- {
- ACE_CLR_BITS (ACE_Log_Msg::default_priority_mask_, priority);
- ACE_Log_Msg *i = ACE_Log_Msg::instance ();
- i->priority_mask (i->priority_mask () & ~priority);
- }
- const ACE_TCHAR *
- ACE_Log_Msg::program_name (void)
- {
- return ACE_Log_Msg::program_name_;
- }
- /// Name of the local host.
- const ACE_TCHAR *ACE_Log_Msg::local_host_ = 0;
- /// Records the program name.
- const ACE_TCHAR *ACE_Log_Msg::program_name_ = 0;
- /// Default is to use stderr.
- u_long ACE_Log_Msg::flags_ = ACE_Log_Msg::STDERR;
- /// Process id of the current process.
- pid_t ACE_Log_Msg::pid_ = -2;
- /// Current offset of msg_[].
- ptrdiff_t ACE_Log_Msg::msg_off_ = 0;
- /// Default per-thread priority mask
- /// By default, no priorities are enabled.
- u_long ACE_Log_Msg::default_priority_mask_ = 0;
- /// Default per-process priority mask
- /// By default, all priorities are enabled.
- u_long ACE_Log_Msg::process_priority_mask_ = LM_SHUTDOWN
- | LM_TRACE
- | LM_DEBUG
- | LM_INFO
- | LM_NOTICE
- | LM_WARNING
- | LM_STARTUP
- | LM_ERROR
- | LM_CRITICAL
- | LM_ALERT
- | LM_EMERGENCY;
- void
- ACE_Log_Msg::close (void)
- {
- // This call needs to go here to avoid memory leaks.
- ACE_MT (ACE_Log_Msg_Manager::close ());
- // Please note that this will be called by a statement that is
- // harded coded into the ACE_Object_Manager's shutdown sequence, in
- // its destructor.
- #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && \
- (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
- defined (ACE_HAS_TSS_EMULATION))
- if (ACE_Log_Msg::key_created_)
- {
- ACE_thread_mutex_t *lock =
- reinterpret_cast<ACE_thread_mutex_t *>
- (ACE_OS_Object_Manager::preallocated_object
- [ACE_OS_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK]);
- ACE_OS::thread_mutex_lock (lock);
- if (ACE_Log_Msg::key_created_)
- {
- // Clean up this ACE_Log_Msg instance and reset the TSS to
- // prevent any future cleanup attempts via TSS mechanisms at
- // thread exit. Otherwise in the event of a dynamic library
- // unload of libACE, by a program not linked with libACE,
- // ACE_TSS_cleanup will be invoked after libACE has been unloaded.
- // See Bugzilla 2980 for lots of details.
- ACE_Log_Msg *tss_log_msg = 0;
- void *temp = 0;
- // Get the tss_log_msg from thread-specific storage.
- if (ACE_Thread::getspecific (*(log_msg_tss_key ()), &temp) != -1
- && temp)
- {
- tss_log_msg = static_cast <ACE_Log_Msg *> (temp);
- // we haven't been cleaned up
- ACE_TSS_CLEANUP_NAME(tss_log_msg);
- if (ACE_Thread::setspecific(*(log_msg_tss_key()),
- reinterpret_cast <void *>(0)) != 0)
- ACE_OS::printf ("ACE_Log_Msg::close failed to ACE_Thread::setspecific to 0\n");
- }
- // The key is not needed any longer; ACE_Log_Msg is closing
- // and will need to be reopened if this process wishes to use
- // logging again. So delete the key.
- ACE_Thread::keyfree (*(log_msg_tss_key()));
- ACE_Log_Msg::key_created_ = false;
- }
- ACE_OS::thread_mutex_unlock (lock);
- }
- #endif /* (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION) && ACE_MT_SAFE */
- }
- void
- ACE_Log_Msg::sync_hook (const ACE_TCHAR *prg_name)
- {
- ACE_LOG_MSG->sync (prg_name);
- }
- ACE_OS_Thread_Descriptor *
- ACE_Log_Msg::thr_desc_hook (void)
- {
- return ACE_LOG_MSG->thr_desc ();
- }
- // Call after a fork to resynchronize the PID and PROGRAM_NAME
- // variables.
- void
- ACE_Log_Msg::sync (const ACE_TCHAR *prog_name)
- {
- ACE_TRACE ("ACE_Log_Msg::sync");
- if (prog_name)
- {
- // Must free if already allocated!!!
- ACE_OS::free ((void *) ACE_Log_Msg::program_name_);
- // Stop heap checking, block will be freed by the destructor when
- // the last ACE_Log_Msg instance is deleted.
- // Heap checking state will be restored when the block is left.
- {
- ACE_NO_HEAP_CHECK;
- ACE_Log_Msg::program_name_ = ACE_OS::strdup (prog_name);
- }
- }
- ACE_Log_Msg::pid_ = ACE_OS::getpid ();
- ACE_Log_Msg::msg_off_ = 0;
- }
- u_long
- ACE_Log_Msg::flags (void)
- {
- ACE_TRACE ("ACE_Log_Msg::flags");
- u_long result;
- ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Log_Msg_Manager::get_lock (), 0));
- result = ACE_Log_Msg::flags_;
- return result;
- }
- void
- ACE_Log_Msg::set_flags (u_long flgs)
- {
- ACE_TRACE ("ACE_Log_Msg::set_flags");
- ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Log_Msg_Manager::get_lock ()));
- ACE_SET_BITS (ACE_Log_Msg::flags_, flgs);
- }
- void
- ACE_Log_Msg::clr_flags (u_long flgs)
- {
- ACE_TRACE ("ACE_Log_Msg::clr_flags");
- ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Log_Msg_Manager::get_lock ()));
- ACE_CLR_BITS (ACE_Log_Msg::flags_, flgs);
- }
- int
- ACE_Log_Msg::acquire (void)
- {
- ACE_TRACE ("ACE_Log_Msg::acquire");
- #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- return ACE_Log_Msg_Manager::get_lock ()->acquire ();
- #else /* ! ACE_MT_SAFE */
- return 0;
- #endif /* ! ACE_MT_SAFE */
- }
- u_long
- ACE_Log_Msg::priority_mask (u_long n_mask, MASK_TYPE mask_type)
- {
- u_long o_mask;
- if (mask_type == THREAD)
- {
- o_mask = this->priority_mask_;
- this->priority_mask_ = n_mask;
- }
- else
- {
- o_mask = ACE_Log_Msg::process_priority_mask_;
- ACE_Log_Msg::process_priority_mask_ = n_mask;
- }
- return o_mask;
- }
- int
- ACE_Log_Msg::release (void)
- {
- ACE_TRACE ("ACE_Log_Msg::release");
- #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- return ACE_Log_Msg_Manager::get_lock ()->release ();
- #else /* ! ACE_MT_SAFE */
- return 0;
- #endif /* ! ACE_MT_SAFE */
- }
- ACE_Log_Msg::ACE_Log_Msg (void)
- : status_ (0),
- errnum_ (0),
- linenum_ (0),
- msg_ (0),
- restart_ (1), // Restart by default...
- ostream_ (0),
- ostream_refcount_ (0),
- msg_callback_ (0),
- trace_depth_ (0),
- trace_active_ (false),
- tracing_enabled_ (true), // On by default?
- thr_desc_ (0),
- priority_mask_ (default_priority_mask_),
- timestamp_ (0)
- {
- // ACE_TRACE ("ACE_Log_Msg::ACE_Log_Msg");
- ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Log_Msg_Manager::get_lock ()));
- ++instance_count_;
- if (this->instance_count_ == 1)
- ACE_Base_Thread_Adapter::set_log_msg_hooks (ACE_Log_Msg::init_hook,
- ACE_Log_Msg::inherit_hook,
- ACE_Log_Msg::close,
- ACE_Log_Msg::sync_hook,
- ACE_Log_Msg::thr_desc_hook);
- this->conditional_values_.is_set_ = false;
- char *timestamp = ACE_OS::getenv ("ACE_LOG_TIMESTAMP");
- if (timestamp != 0)
- {
- // If variable is set or is set to date tag so we print date and time.
- if (ACE_OS::strcmp (timestamp, "TIME") == 0)
- {
- this->timestamp_ = 1;
- }
- else if (ACE_OS::strcmp (timestamp, "DATE") == 0)
- {
- this->timestamp_ = 2;
- }
- }
- ACE_NEW_NORETURN (this->msg_, ACE_TCHAR[ACE_MAXLOGMSGLEN+1]);
- }
- ACE_Log_Msg::~ACE_Log_Msg (void)
- {
- #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- int instance_count = 0;
- // Only hold the guard while updating the instance_count_.
- // If ACE_Log_Msg_Manager::close () is called, the lock will
- // be deleted.
- {
- ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Log_Msg_Manager::get_lock ()));
- instance_count = --instance_count_;
- }
- // Release the guard.
- #else /* ! ACE_MT_SAFE */
- int instance_count = --instance_count_;
- #endif /* ! ACE_MT_SAFE */
- // If this is the last instance then cleanup. Only the last
- // thread to destroy its ACE_Log_Msg instance should execute
- // this block.
- if (instance_count == 0)
- {
- // Destroy the message queue instance.
- if (ACE_Log_Msg_Manager::log_backend_ != 0)
- ACE_Log_Msg_Manager::log_backend_->close ();
- // Close down custom backend
- if (ACE_Log_Msg_Manager::custom_backend_ != 0)
- ACE_Log_Msg_Manager::custom_backend_->close ();
- # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
- # if defined (ACE_HAS_TSS_EMULATION)
- ACE_Log_Msg_Manager::close ();
- # endif /* ACE_HAS_TSS_EMULATION */
- # endif /* ACE_MT_SAFE */
- if (ACE_Log_Msg::program_name_)
- {
- ACE_OS::free ((void *) ACE_Log_Msg::program_name_);
- ACE_Log_Msg::program_name_ = 0;
- }
- if (ACE_Log_Msg::local_host_)
- {
- ACE_OS::free ((void *) ACE_Log_Msg::local_host_);
- ACE_Log_Msg::local_host_ = 0;
- }
- }
- this->cleanup_ostream ();
- delete[] this->msg_;
- }
- void
- ACE_Log_Msg::cleanup_ostream ()
- {
- if (this->ostream_refcount_)
- {
- if (--*this->ostream_refcount_ == 0)
- {
- delete this->ostream_refcount_;
- #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
- ACE_OS::fclose (this->ostream_);
- #else
- delete this->ostream_;
- this->ostream_ = 0;
- #endif
- }
- this->ostream_refcount_ = 0;
- }
- }
- // Open the sender-side of the message queue.
- int
- ACE_Log_Msg::open (const ACE_TCHAR *prog_name,
- u_long flags,
- const ACE_TCHAR *logger_key)
- {
- ACE_TRACE ("ACE_Log_Msg::open");
- ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Log_Msg_Manager::get_lock (), -1));
- if (prog_name)
- {
- ACE_OS::free ((void *) ACE_Log_Msg::program_name_);
- // Stop heap checking, block will be freed by the destructor.
- {
- ACE_NO_HEAP_CHECK;
- ACE_ALLOCATOR_RETURN (ACE_Log_Msg::program_name_,
- ACE_OS::strdup (prog_name),
- -1);
- }
- }
- else if (ACE_Log_Msg::program_name_ == 0)
- {
- // Stop heap checking, block will be freed by the destructor.
- ACE_NO_HEAP_CHECK;
- ACE_ALLOCATOR_RETURN (ACE_Log_Msg::program_name_,
- ACE_OS::strdup (ACE_TEXT ("<unknown>")),
- -1);
- }
- int status = 0;
- // Be sure that there is a message_queue_, with multiple threads.
- ACE_MT (ACE_Log_Msg_Manager::init_backend (&flags));
- // Always close the current handle before doing anything else.
- if (ACE_Log_Msg_Manager::log_backend_ != 0)
- ACE_Log_Msg_Manager::log_backend_->reset ();
- if (ACE_Log_Msg_Manager::custom_backend_ != 0)
- ACE_Log_Msg_Manager::custom_backend_->reset ();
- // Note that if we fail to open the message queue the default action
- // is to use stderr (set via static initialization in the
- // Log_Msg.cpp file).
- if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER)
- || ACE_BIT_ENABLED (flags, ACE_Log_Msg::SYSLOG))
- {
- // The SYSLOG backends (both NT and UNIX) can get along fine
- // without the logger_key - they will default to prog_name if
- // logger key is 0.
- if (logger_key == 0 && ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER))
- status = -1;
- else
- status = ACE_Log_Msg_Manager::log_backend_->open (logger_key);
- if (status == -1)
- ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR);
- else
- {
- if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER))
- ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER);
- if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::SYSLOG))
- ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG);
- }
- }
- else if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER)
- || ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG))
- {
- // If we are closing down logger, redirect logging to stderr.
- ACE_CLR_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER);
- ACE_CLR_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG);
- ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR);
- }
- if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::CUSTOM))
- {
- status =
- ACE_Log_Msg_Manager::custom_backend_->open (logger_key);
- if (status != -1)
- ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM);
- }
- // Remember, ACE_Log_Msg::STDERR bit is on by default...
- if (status != -1
- && ACE_BIT_ENABLED (flags,
- ACE_Log_Msg::STDERR) == 0)
- ACE_CLR_BITS (ACE_Log_Msg::flags_,
- ACE_Log_Msg::STDERR);
- // VERBOSE takes precedence over VERBOSE_LITE...
- if (ACE_BIT_ENABLED (flags,
- ACE_Log_Msg::VERBOSE_LITE))
- ACE_SET_BITS (ACE_Log_Msg::flags_,
- ACE_Log_Msg::VERBOSE_LITE);
- else if (ACE_BIT_ENABLED (flags,
- ACE_Log_Msg::VERBOSE))
- ACE_SET_BITS (ACE_Log_Msg::flags_,
- ACE_Log_Msg::VERBOSE);
- if (ACE_BIT_ENABLED (flags,
- ACE_Log_Msg::OSTREAM))
- {
- ACE_SET_BITS (ACE_Log_Msg::flags_,
- ACE_Log_Msg::OSTREAM);
- // Only set this to cerr if it hasn't already been set.
- if (this->msg_ostream () == 0)
- this->msg_ostream (ACE_DEFAULT_LOG_STREAM);
- }
- if (ACE_BIT_ENABLED (flags,
- ACE_Log_Msg::MSG_CALLBACK))
- ACE_SET_BITS (ACE_Log_Msg::flags_,
- ACE_Log_Msg::MSG_CALLBACK);
- if (ACE_BIT_ENABLED (flags,
- ACE_Log_Msg::SILENT))
- ACE_SET_BITS (ACE_Log_Msg::flags_,
- ACE_Log_Msg::SILENT);
- return status;
- }
- /**
- * Valid Options (prefixed by '%', as in printf format strings) include:
- * 'A': print an ACE_timer_t value
- * 'a': exit the program at this point (var-argument is the exit status!)
- * 'b': print a ssize_t value
- * 'B': print a size_t value
- * 'c': print a character
- * 'C': print a character string
- * 'i', 'd': print a decimal number
- * 'I', indent according to nesting depth
- * 'e', 'E', 'f', 'F', 'g', 'G': print a double
- * 'l', print line number where an error occurred.
- * 'M': print the name of the priority of the message.
- * 'm': Return the message corresponding to errno value, e.g., as done by <strerror>
- * 'N': print file name where the error occurred.
- * 'n': print the name of the program (or "<unknown>" if not set)
- * 'o': print as an octal number
- * 'P': format the current process id
- * 'p': format the appropriate errno message from sys_errlist, e.g., as done by <perror>
- * 'Q': print out the uint64 number
- * 'q': print out the int64 number
- * '@': print a void* pointer (in hexadecimal)
- * 'r': call the function pointed to by the corresponding argument
- * 'R': print return status
- * 'S': print out the appropriate signal message corresponding
- * to var-argument, e.g., as done by strsignal()
- * 's': format a character string
- * 'T': print timestamp in hour:minute:sec:usec format.
- * 'D': print timestamp in month/day/year hour:minute:sec:usec format.
- * 't': print thread id (1 if single-threaded)
- * 'u': print as unsigned int
- * 'x': print as a hex number
- * 'X': print as a hex number
- * 'w': print a wide character
- * 'W': print out a wide character string.
- * 'z': print an ACE_OS::WChar character
- * 'Z': print an ACE_OS::WChar character string
- * ':': print a time_t value as an integral number
- * '%': format a single percent sign, '%'
- */
- ssize_t
- ACE_Log_Msg::log (ACE_Log_Priority log_priority,
- const ACE_TCHAR *format_str, ...)
- {
- ACE_TRACE ("ACE_Log_Msg::log");
- // Start of variable args section.
- va_list argp;
- va_start (argp, format_str);
- ssize_t const result = this->log (format_str,
- log_priority,
- argp);
- va_end (argp);
- return result;
- }
- #if defined (ACE_HAS_WCHAR)
- /**
- * Since this is the ANTI_TCHAR version, we need to convert
- * the format string over.
- */
- ssize_t
- ACE_Log_Msg::log (ACE_Log_Priority log_priority,
- const ACE_ANTI_TCHAR *format_str, ...)
- {
- ACE_TRACE ("ACE_Log_Msg::log");
- // Start of variable args section.
- va_list argp;
- va_start (argp, format_str);
- ssize_t const result = this->log (ACE_TEXT_ANTI_TO_TCHAR (format_str),
- log_priority,
- argp);
- va_end (argp);
- return result;
- }
- #endif /* ACE_HAS_WCHAR */
- ssize_t
- ACE_Log_Msg::log (const ACE_TCHAR *format_str,
- ACE_Log_Priority log_priority,
- va_list argp)
- {
- ACE_TRACE ("ACE_Log_Msg::log");
- // External decls.
- typedef void (*PTF)(...);
- // Check if there were any conditional values set.
- bool const conditional_values = this->conditional_values_.is_set_;
- // Reset conditional values.
- this->conditional_values_.is_set_ = false;
- // Only print the message if <priority_mask_> hasn't been reset to
- // exclude this logging priority.
- if (this->log_priority_enabled (log_priority) == 0)
- return 0;
- // If conditional values were set and the log priority is correct,
- // then the values are actually set.
- if (conditional_values)
- this->set (this->conditional_values_.file_,
- this->conditional_values_.line_,
- this->conditional_values_.op_status_,
- this->conditional_values_.errnum_,
- this->restart (),
- this->msg_ostream (),
- this->msg_callback ());
- // Logging is supposed to be a benign activity (i.e., not interfer
- // with normal application operations), so don't inadvertently smash
- // errno!
- ACE_Errno_Guard guard (errno);
- ACE_Log_Record log_record (log_priority,
- ACE_OS::gettimeofday (),
- this->getpid ());
- // bp is pointer to where to put next part of logged message.
- // bspace is the number of characters remaining in msg_.
- ACE_TCHAR *bp = const_cast<ACE_TCHAR *> (this->msg ());
- size_t bspace = ACE_MAXLOGMSGLEN; // Leave room for Nul term.
- if (this->msg_off_ <= ACE_Log_Record::MAXLOGMSGLEN)
- bspace -= static_cast<size_t> (this->msg_off_);
- // If this platform has snprintf() capability to prevent overrunning the
- // output buffer, use it. To avoid adding a maintenance-hassle compile-
- // time couple between here and OS.cpp, don't try to figure this out at
- // compile time. Instead, do a quick check now; if we get a -1 return,
- // the platform doesn't support the length-limiting capability.
- ACE_TCHAR test[2];
- bool can_check = ACE_OS::snprintf (test, 1, ACE_TEXT ("x")) != -1;
- bool abort_prog = false;
- int exit_value = 0;
- if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::VERBOSE))
- {
- // Prepend the program name onto this message
- if (ACE_Log_Msg::program_name_ != 0)
- {
- for (const ACE_TCHAR *s = ACE_Log_Msg::program_name_;
- bspace > 1 && (*bp = *s) != '\0';
- ++s, --bspace)
- bp++;
- *bp++ = '|';
- --bspace;
- }
- }
- if (timestamp_ > 0)
- {
- ACE_TCHAR day_and_time[35];
- const ACE_TCHAR *s = 0;
- if (timestamp_ == 1)
- {
- // Print just the time
- s = ACE::timestamp (day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR), 1);
- }
- else
- {
- // Print time and date
- ACE::timestamp (day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR));
- s = day_and_time;
- }
- for (; bspace > 1 && (*bp = *s) != '\0'; ++s, --bspace)
- ++bp;
- *bp++ = '|';
- --bspace;
- }
- while (*format_str != '\0' && bspace > 0)
- {
- // Copy input to output until we encounter a %, however a
- // % followed by another % is not a format specification.
- if (*format_str != '%')
- {
- *bp++ = *format_str++;
- --bspace;
- }
- else if (format_str[1] == '%') // An "escaped" '%' (just print one '%').
- {
- *bp++ = *format_str++; // Store first %
- ++format_str; // but skip second %
- --bspace;
- }
- else
- {
- // This is most likely a format specification that ends with
- // one of the valid options described previously. To enable full
- // use of all sprintf capabilities, save the format specifier
- // from the '%' up to the format letter in a new char array.
- // This allows the full sprintf capability for padding, field
- // widths, alignment, etc. Any width/precision requiring a
- // caller-supplied argument is extracted and placed as text
- // into the format array. Lastly, we convert the caller-supplied
- // format specifier from the ACE_Log_Msg-supported list to the
- // equivalent sprintf specifier, and run the new format spec
- // through sprintf, adding it to the bp string.
- const ACE_TCHAR *abort_str = ACE_TEXT ("Aborting...");
- const ACE_TCHAR *start_format = format_str;
- ACE_TCHAR format[128]; // Converted format string
- ACE_TCHAR *fp; // Current format pointer
- int wp = 0; // Width/precision extracted from args
- bool done = false;
- bool skip_nul_locate = false;
- int this_len = 0; // How many chars s[n]printf wrote
- fp = format;
- *fp++ = *format_str++; // Copy in the %
- // Initialization to satisfy VC6
- int tmp_indent = 0;
- // Work through the format string to copy in the format
- // from the caller. While it's going across, extract ints
- // for '*' width/precision values from the argument list.
- // When the real format specifier is located, change it to
- // one recognized by sprintf, if needed, and do the sprintf
- // call.
- while (!done)
- {
- done = true; // Unless a conversion spec changes it
- switch (*format_str)
- {
- // The initial set of cases are the conversion
- // specifiers. Copy them in to the format array.
- // Note we don't use 'l', a normal conversion spec,
- // as a conversion because it is a ACE_Log_Msg format
- // specifier.
- case '-':
- case '+':
- case '0':
- case ' ':
- case '#':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '.':
- case 'L':
- case 'h':
- *fp++ = *format_str;
- done = false;
- break;
- case '*':
- wp = va_arg (argp, int);
- ACE_OS::sprintf (fp, ACE_TEXT ("%d"), wp);
- fp += ACE_OS::strlen (fp);
- done = false;
- break;
- case 'A': // ACE_timer_t
- {
- ACE_OS::strcpy (fp, ACE_TEXT ("f"));
- double const value = va_arg (argp, double);
- if (can_check)
- this_len = ACE_OS::snprintf (bp, bspace, format, value);
- else
- this_len = ACE_OS::sprintf (bp, format, value);
- ACE_UPDATE_COUNT (bspace, this_len);
- }
- break;
- case 'a': // Abort program after handling all of format string.
- abort_prog = true;
- exit_value = va_arg (argp, int);
- ACE_OS::strsncpy (bp, abort_str, bspace);
- if (bspace > ACE_OS::strlen (abort_str))
- bspace -= ACE_OS::strlen (abort_str);
- else
- bspace = 0;
- break;
- case 'l': // Source file line number
- ACE_OS::strcpy (fp, ACE_TEXT ("d"));
- if (can_check)
- this_len = ACE_OS::snprintf (bp,
- bspace,
- format,
- this->linenum ());
- else
- this_len = ACE_OS::sprintf (bp, format, this->linenum ());
- ACE_UPDATE_COUNT (bspace, this_len);
- break;
- case 'N': // Source file name
- #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
- ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
- #else
- ACE_OS::strcpy (fp, ACE_TEXT ("s"));
- #endif
- if (can_check)
- this_len = ACE_OS::snprintf (bp, bspace, format,
- this->file () ?
- ACE_TEXT_CHAR_TO_TCHAR (this->file ())
- : ACE_TEXT ("<unknown file>"));
- else
- this_len = ACE_OS::sprintf (bp, format,
- this->file () ?
- ACE_TEXT_CHAR_TO_TCHAR (this->file ())
- : ACE_TEXT ("<unknown file>"));
- ACE_UPDATE_COUNT (bspace, this_len);
- break;
- case 'n': // Program name
- #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
- ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
- #else /* ACE_WIN32 && ACE_USES_WCHAR */
- ACE_OS::strcpy (fp, ACE_TEXT ("s"));
- #endif
- if (can_check)
- this_len = ACE_OS::snprintf (bp, bspace, format,
- ACE_Log_Msg::program_name_ ?
- ACE_Log_Msg::program_name_ :
- ACE_TEXT ("<unknown>"));
- else
- this_len = ACE_OS::sprintf (bp, format,
- ACE_Log_Msg::program_name_ ?
- ACE_Log_Msg::program_name_ :
- ACE_TEXT ("<unknown>"));
- ACE_UPDATE_COUNT (bspace, this_len);
- break;
- case 'P': // Process ID
- #if defined (ACE_OPENVMS)
- // Print the process id in hex on OpenVMS.
- ACE_OS::strcpy (fp, ACE_TEXT ("x"));
- #else
- ACE_OS::strcpy (fp, ACE_TEXT ("d"));
- #endif
- if (can_check)
- this_len = ACE_OS::snprintf
- (bp, bspace, format,
- static_cast<int> (this->getpid ()));
- else
- this_len = ACE_OS::sprintf
- (bp, format, static_cast<int> (this->getpid ()));
- ACE_UPDATE_COUNT (bspace, this_len);
- break;
- case 'p': // <errno> string, ala perror()
- {
- errno = 0;
- char *msg = ACE_OS::strerror (ACE::map_errno (this->errnum ()));
- // Windows can try to translate the errnum using
- // system calls if strerror() doesn't get anything useful.
- #if defined (ACE_WIN32)
- if (errno == 0)
- {
- #endif
- #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
- ACE_OS::strcpy (fp, ACE_TEXT ("ls: %ls"));
- wchar_t *str = va_arg (argp, wchar_t *);
- #else
- ACE_OS::strcpy (fp, ACE_TEXT ("s: %s"));
- ACE_TCHAR *str = va_arg (argp, ACE_TCHAR *);
- #endif
- if (can_check)
- this_len = ACE_OS::snprintf
- (bp, bspace, format,
- str ? str : ACE_TEXT ("(null)"),
- ACE_TEXT_CHAR_TO_TCHAR (msg));
- else
- this_len = ACE_OS::sprintf
- (bp, format,
- str ? str : ACE_TEXT ("(null)"),
- ACE_TEXT_CHAR_TO_TCHAR (msg));
- #if defined (ACE_WIN32)
- }
- else
- {
- errno = ACE::map_errno (this->errnum ());
- ACE_TCHAR *lpMsgBuf = 0;
- // PharLap can't do FormatMessage, so try for socket
- // error.
- # if !defined (ACE_HAS_PHARLAP)
- ACE_TEXT_FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
- | FORMAT_MESSAGE_MAX_WIDTH_MASK
- | FORMAT_MESSAGE_FROM_SYSTEM,
- 0,
- errno,
- MAKELANGID (LANG_NEUTRAL,
- SUBLANG_DEFAULT),
- // Default language
- (ACE_TCHAR *) &lpMsgBuf,
- 0,
- 0);
- # endif /* ACE_HAS_PHARLAP */
- // If we don't get a valid response from
- // <FormatMessage>, we'll assume this is a
- // WinSock error and so we'll try to convert
- // it into a string. If this doesn't work it
- // returns "unknown error" which is fine for
- // our purposes.
- ACE_TCHAR *str = va_arg (argp, ACE_TCHAR *);
- if (lpMsgBuf == 0)
- {
- const ACE_TCHAR *message =
- ACE::sock_error (errno);
- ACE_OS::strcpy (fp, ACE_TEXT ("s: %s"));
- if (can_check)
- this_len = ACE_OS::snprintf
- (bp, bspace, format,
- str ? str : ACE_TEXT ("(null)"),
- message);
- else
- this_len = ACE_OS::sprintf
- (bp, format,
- str ? str : ACE_TEXT ("(null)"),
- message);
- }
- else
- {
- ACE_OS::strcpy (fp, ACE_TEXT ("s: %s"));
- if (can_check)
- this_len = ACE_OS::snprintf
- (bp, bspace, format,
- str ? str : ACE_TEXT ("(null)"),
- lpMsgBuf);
- else
- this_len = ACE_OS::sprintf
- (bp, format,
- str ? str : ACE_TEXT ("(null)"),
- lpMsgBuf);
- // Free the buffer.
- ::LocalFree (lpMsgBuf);
- }
- }
- #endif /* ACE_WIN32 */
- ACE_UPDATE_COUNT (bspace, this_len);
- break;
- }
- case 'M': // Print the name of the priority of the message.
- // Look at the format precision specifier. .1 is interpreted
- // as a single character printout, otherwise we print the name of
- // the priority.
- // So, did we find a .1 specifier? Do we need to override it?
- if (format[1] == ACE_TEXT('.') &&
- format[2] == ACE_TEXT('1'))
- {
- // Yup.
- // Print a single character signifying the severity of the message
- fp = format;
- fp++;
- # if defined (ACE_USES_WCHAR)
- # if defined (ACE_WIN32) // Windows uses 'c' for a wide character
- ACE_OS::strcpy (fp, ACE_TEXT ("c"));
- # else // Other platforms behave differently
- # if defined (HPUX) // HP-Unix compatible
- ACE_OS::strcpy (fp, ACE_TEXT ("C"));
- # else // Other
- ACE_OS::strcpy (fp, ACE_TEXT ("lc"));
- # endif /* HPUX */
- # endif
- # else /* ACE_USES_WCHAR */
- // Non-unicode builds simply use a standard character format specifier
- ACE_OS::strcpy (fp, ACE_TEXT ("c"));
- # endif /* ACE_USES_WCHAR */
- // Below is an optimized (binary search based)
- // version of the following simple piece of code:
- //
- // log_priority == LM_SHUTDOWN ? 'S' : // Shutdown
- // log_priority == LM_TRACE ? 'T' : // Trace
- // log_priority == LM_DEBUG ? 'D' : // Debug
- // log_priority == LM_INFO ? 'I' : // Info
- // log_priority == LM_NOTICE ? 'N' : // Notice
- // log_priority == LM_WARNING ? 'W' : // Warning
- // log_priority == LM_STARTUP ? 'U' : // Startup
- // log_priority == LM_ERROR ? 'E' : // Error
- // log_priority == LM_CRITICAL ? 'C' : // Critical
- // log_priority == LM_ALERT ? 'A' : // Alert
- // log_priority == LM_EMERGENCY ? '!' : // Emergency
- // '?' // Unknown
- if (can_check)
- {
- this_len = ACE_OS::snprintf
- (bp, bspace, format,
- #if !defined (ACE_USES_WCHAR) || defined (ACE_WIN32)
- (int)
- #else
- (wint_t)
- #endif
- (log_priority <= LM_WARNING) ?
- (log_priority <= LM_DEBUG) ?
- (log_priority <= LM_TRACE) ?
- (log_priority == LM_SHUTDOWN) ?
- ACE_TEXT('S') : ACE_TEXT('T') : ACE_TEXT('D') :
- (log_priority <= LM_NOTICE) ?
- (log_priority == LM_INFO) ?
- ACE_TEXT('I') : ACE_TEXT('N') : ACE_TEXT('W') :
- (log_priority <= LM_CRITICAL) ?
- (log_priority <= LM_ERROR) ?
- (log_priority == LM_STARTUP) ?
- ACE_TEXT('U') : ACE_TEXT('E') : ACE_TEXT('C') :
- (log_priority <= LM_EMERGENCY) ?
- (log_priority == LM_ALERT) ?
- ACE_TEXT('A') : ACE_TEXT('!') : ACE_TEXT('?'));
- }
- else
- {
- this_len = ACE_OS::sprintf
- (bp, format,
- #if !defined (ACE_USES_WCHAR) || defined (ACE_WIN32)
- (int)
- #else
- (wint_t)
- #endif
- (log_priority <= LM_WARNING) ?
- (log_priority <= LM_DEBUG) ?
- (log_priority <= LM_TRACE) ?
- (log_priority == LM_SHUTDOWN) ?
- ACE_TEXT('S') : ACE_TEXT('T') : ACE_TEXT('D') :
- (log_priority <= LM_NOTICE) ?
- (log_pri