Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes

ACE_Log_Msg Class Reference

Provides a variable length argument message logging abstraction. More...

#include <Log_Msg.h>

Collaboration diagram for ACE_Log_Msg:
Collaboration graph
[legend]

List of all members.

Public Types

enum  {
  STDERR = 1, LOGGER = 2, OSTREAM = 4, MSG_CALLBACK = 8,
  VERBOSE = 16, VERBOSE_LITE = 32, SILENT = 64, SYSLOG = 128,
  CUSTOM = 256
}
enum  MASK_TYPE { PROCESS = 0, THREAD = 1 }

Public Member Functions

 ACE_Log_Msg (void)
 Initialize logger.
 ~ACE_Log_Msg (void)
 cleanup logger.
int open (const ACE_TCHAR *prog_name, u_long options_flags=ACE_Log_Msg::STDERR, const ACE_TCHAR *logger_key=0)
 Initialize the ACE logging facility.
void set_flags (u_long f)
void clr_flags (u_long f)
u_long flags (void)
void sync (const ACE_TCHAR *program_name)
void op_status (int status)
int op_status (void) const
void errnum (int)
int errnum (void) const
void linenum (int)
 Set the line number where an error occurred.
int linenum (void) const
 Get the line number where an error occurred.
void file (const char *)
 Set the file name where an error occurred.
const char * file (void)
 Get the file name where an error occurred.
void msg (const ACE_TCHAR *)
 Set the message that describes what type of error occurred.
const ACE_TCHARmsg (void)
 Get the message that describes what type of error occurred.
void restart (bool r)
bool restart (void) const
void msg_ostream (ACE_OSTREAM_TYPE *)
 Update the ostream without overwriting the delete_ostream_ flag.
void msg_ostream (ACE_OSTREAM_TYPE *, bool delete_ostream)
ACE_OSTREAM_TYPE * msg_ostream (void) const
 Get the ostream that is used to print error messages.
ACE_Log_Msg_Callbackmsg_callback (ACE_Log_Msg_Callback *c)
ACE_Log_Msg_Callbackmsg_callback (void) const
int inc (void)
 Nesting depth increment.
int dec (void)
 Nesting depth decrement.
int trace_depth (void) const
 Get trace depth.
void trace_depth (int)
 Set trace depth.
bool trace_active (void) const
 Get trace active status.
void trace_active (bool value)
 Set trace active status.
ACE_Thread_Descriptorthr_desc (void) const
 Get the TSS thread descriptor.
void thr_desc (ACE_Thread_Descriptor *td)
void stop_tracing (void)
 Stop tracing status on a per-thread basis...
void start_tracing (void)
 Start tracing status on a per-thread basis...
bool tracing_enabled (void) const
 Query tracing status on a per-thread basis...
u_long priority_mask (MASK_TYPE=THREAD)
 Get the current ACE_Log_Priority mask.
u_long priority_mask (u_long, MASK_TYPE=THREAD)
 Set the ACE_Log_Priority mask, returns original mask.
int log_priority_enabled (ACE_Log_Priority log_priority)
 Return true if the requested priority is enabled.
int log_priority_enabled (ACE_Log_Priority log_priority, const char *,...)
 Return true if the requested priority is enabled.
pid_t getpid (void) const
const ACE_TCHARlocal_host (void) const
 Get the name of the local host.
void local_host (const ACE_TCHAR *)
 Set the name of the local host.
void set (const char *file, int line, int op_status=-1, int errnum=0, bool restart=true, ACE_OSTREAM_TYPE *os=0, ACE_Log_Msg_Callback *c=0)
void conditional_set (const char *file, int line, int op_status, int errnum)
ssize_t log (ACE_Log_Priority priority, const ACE_TCHAR *format,...)
ssize_t log (const ACE_TCHAR *format, ACE_Log_Priority priority, va_list argp)
ssize_t log (ACE_Log_Record &log_record, int suppress_stderr=0)
int log_hexdump (ACE_Log_Priority log_priority, const char *buffer, size_t size, const ACE_TCHAR *text=0)
void dump (void) const
 Dump the state of an object.
Allow apps to acquire and release internal synchronization

lock

This lock is used internally by the ACE_Log_Msg implementation. By exporting the lock, applications can hold the lock atomically over a number of calls to ACE_Log_Msg.

int acquire (void)
 Acquire the internal lock.
int release (void)
 Release the internal lock.

Static Public Member Functions

static ACE_Log_Msginstance (void)
 Returns a pointer to the Singleton.
static int last_error_adapter (void)
 Returns last error.
static int exists (void)
 Returns non-null if an ACE_Log_Msg exists for the calling thread.
static const ACE_TCHARprogram_name (void)
 Returns the current program name used for logging.
static void disable_debug_messages (ACE_Log_Priority priority=LM_DEBUG)
static void enable_debug_messages (ACE_Log_Priority priority=LM_DEBUG)
static ACE_Log_Msg_Backendmsg_backend (ACE_Log_Msg_Backend *b)
static ACE_Log_Msg_Backendmsg_backend (void)
static void init_hook (ACE_OS_Log_Msg_Attributes &attributes)
static void inherit_hook (ACE_OS_Thread_Descriptor *thr_desc, ACE_OS_Log_Msg_Attributes &attributes)

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.
bool is_set_
const char * file_
int line_
int op_status_

Private Types

typedef ACE_Atomic_Op
< ACE_SYNCH_MUTEX, unsigned
long > 
Atomic_ULong

Private Member Functions

void cleanup_ostream ()
ACE_Log_Msgoperator= (const ACE_Log_Msg &)
 ACE_Log_Msg (const ACE_Log_Msg &)

Static Private Member Functions

static void close (void)
 For cleanup, at program termination.
static void sync_hook (const ACE_TCHAR *prg_name)
 Decouple the OS layer from the ACE_Log_Msg layer.
static ACE_OS_Thread_Descriptorthr_desc_hook (void)
 Return the TSS singleton thread descriptor.

Private Attributes

int status_
 Status of operation (-1 means failure, >= 0 means success).
int errnum_
 Type of error that occurred (see <sys/errno.h>).
int linenum_
 Line number where the error occurred.
char file_ [MAXPATHLEN+1]
 File where the error occurred.
ACE_TCHARmsg_
bool restart_
ACE_OSTREAM_TYPE * ostream_
 The ostream where logging messages can be written.
Atomic_ULongostream_refcount_
ACE_Log_Msg_Callbackmsg_callback_
 The callback object.
int trace_depth_
 Depth of the nesting for printing traces.
bool trace_active_
 Are we already within an ACE_Trace constructor call?
bool tracing_enabled_
 Are we allowing tracing in this thread?
ACE_Thread_Descriptorthr_desc_
u_long priority_mask_
int timestamp_
 Always timestamp?
struct {
   bool   is_set_
   const char *   file_
   int   line_
   int   op_status_
   int   errnum_
conditional_values_

Static Private Attributes

static u_long process_priority_mask_
static const ACE_TCHARprogram_name_ = 0
 Records the program name.
static const ACE_TCHARlocal_host_ = 0
 Name of the local host (used when printing messages).
static pid_t pid_ = -2
 Process id of the current process.
static u_long flags_ = ACE_Log_Msg::STDERR
 Default is to use stderr.
static ptrdiff_t msg_off_ = 0
 Offset of msg_[].
static int instance_count_ = 0
static u_long default_priority_mask_ = 0

Detailed Description

Provides a variable length argument message logging abstraction.

This class is very flexible since it allows formatted error messages to be printed in a thread-safe manner to various locations, such as stderr, cerr, a distributed logger, etc. The current message is also kept in a thread-specific storage location (threads spawned using ACE_Thread_Manager automatically get an ACE_Log_Msg object that inherits the spawning thread's settings), which can be used to communicate errors between framework methods and callers. A message is logged by the log() method, only if the message priority is currently enabled. Moreover, only the current log message is stored here -- it will be overwritten by the subsequent call to log().

The ACE_Log_Msg class uses two priority masks to control its logging behavior. The priority_mask_ object attribute is thread- specific and specifies the priority levels logged by the thread. The process_priority_mask_ class attribute is not thread-specific and specifies the priority levels that will be logged by all threads in the process. By default, all levels are disabled for priority_mask_ and all levels are enabled for process_priority_mask_ (i.e. the process-wide mask controls the settings, and each instance can expand on it if desired). Both priority masks can be modified using the priority_mask() method of this class.

Definition at line 179 of file Log_Msg.h.


Member Typedef Documentation

typedef ACE_Atomic_Op<ACE_SYNCH_MUTEX, unsigned long> ACE_Log_Msg::Atomic_ULong [private]

This pointer is 0 if we are not reference counting (the user has not passed "true" for the delete_ostream argument to msg_ostream). If we are reference counting, this points to a shared count that will be deleted when it reaches zero. Since we want optional but shared ownership neither std::auto_ptr nor ACE_Strong_Bound_Ptr have the right semantics. *Bound_Ptr also doesn't take advantage of Atomic_Op.

Definition at line 640 of file Log_Msg.h.


Member Enumeration Documentation

anonymous enum
Enumerator:
STDERR 

Write messages to stderr.

LOGGER 

Write messages to the local client logger deamon.

OSTREAM 

Write messages to the ostream * stored in thread-specific storage.

MSG_CALLBACK 

Write messages to the callback object.

VERBOSE 

Display messages in a verbose manner.

VERBOSE_LITE 

Display messages in a less verbose manner (i.e., only print information that can change between calls).

SILENT 

Do not print messages at all (just leave in thread-specific storage for later inspection).

SYSLOG 

Write messages to the system's event log.

CUSTOM 

Write messages to the user provided backend.

Definition at line 183 of file Log_Msg.h.

  {
    /// Write messages to stderr.
    STDERR = 1,
    /// Write messages to the local client logger deamon.
    LOGGER = 2,
    /// Write messages to the ostream * stored in thread-specific
    /// storage.
    OSTREAM = 4,
    /// Write messages to the callback object.
    MSG_CALLBACK = 8,
    /// Display messages in a verbose manner.
    VERBOSE = 16,
    /// Display messages in a less verbose manner (i.e., only print
    /// information that can change between calls).
    VERBOSE_LITE = 32,
    /// Do not print messages at all (just leave in thread-specific
    /// storage for later inspection).
    SILENT = 64,
    /// Write messages to the system's event log.
    SYSLOG = 128,
    /// Write messages to the user provided backend
    CUSTOM = 256
 };

Enumerator:
PROCESS 
THREAD 

Definition at line 438 of file Log_Msg.h.

  {
    PROCESS = 0,
    THREAD = 1
  } MASK_TYPE;


Constructor & Destructor Documentation

ACE_Log_Msg::ACE_Log_Msg ( void   ) 

Initialize logger.

Definition at line 641 of file Log_Msg.cpp.

  : 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   ) 

cleanup logger.

Definition at line 689 of file Log_Msg.cpp.

{
#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_;
}

ACE_Log_Msg::ACE_Log_Msg ( const ACE_Log_Msg  )  [private]

Member Function Documentation

int ACE_Log_Msg::acquire ( void   ) 

Acquire the internal lock.

Definition at line 600 of file Log_Msg.cpp.

{
  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 */
}

void ACE_Log_Msg::cleanup_ostream (  )  [private]

Definition at line 747 of file Log_Msg.cpp.

{
  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;
    }
}

void ACE_Log_Msg::close ( void   )  [static, private]

For cleanup, at program termination.

Definition at line 473 of file Log_Msg.cpp.

{
  // 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::clr_flags ( u_long  f  ) 

Disable the bits in the logger's options flags.

Definition at line 590 of file Log_Msg.cpp.

{
  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);
}

void ACE_Log_Msg::conditional_set ( const char *  file,
int  line,
int  op_status,
int  errnum 
)

These values are only actually set if the requested priority is enabled.

Definition at line 2419 of file Log_Msg.cpp.

{
  this->conditional_values_.is_set_ = true;
  this->conditional_values_.file_ = filename;
  this->conditional_values_.line_ = line;
  this->conditional_values_.op_status_ = status;
  this->conditional_values_.errnum_ = err;
}

int ACE_Log_Msg::dec ( void   )  [inline]

Nesting depth decrement.

Definition at line 93 of file Log_Msg.inl.

{
  return this->trace_depth_ == 0 ? 0 : --this->trace_depth_;
}

void ACE_Log_Msg::disable_debug_messages ( ACE_Log_Priority  priority = LM_DEBUG  )  [static]

Clears the flag from the default priority mask used to initialize ACE_Log_Msg instances.

Definition at line 426 of file Log_Msg.cpp.

void ACE_Log_Msg::dump ( void   )  const

Dump the state of an object.

Definition at line 2432 of file Log_Msg.cpp.

{
#if defined (ACE_HAS_DUMP)
  ACE_TRACE ("ACE_Log_Msg::dump");

  ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("status_ = %d\n"), this->status_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nerrnum_ = %d\n"), this->errnum_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nlinenum_ = %d\n"), this->linenum_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nfile_ = %C\n"), this->file_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmsg_ = %s\n"), this->msg_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nrestart_ = %d\n"), this->restart_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nostream_ = %@\n"), this->ostream_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmsg_callback_ = %@\n"),
              this->msg_callback_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nprogram_name_ = %s\n"),
              this->program_name_ ? this->program_name_
                                  : ACE_TEXT ("<unknown>")));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nlocal_host_ = %s\n"),
              this->local_host_ ? this->local_host_
                                : ACE_TEXT ("<unknown>")));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\npid_ = %d\n"), this->getpid ()));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nflags_ = 0x%x\n"), this->flags_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntrace_depth_ = %d\n"),
              this->trace_depth_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntrace_active_ = %d\n"),
              this->trace_active_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntracing_enabled_ = %d\n"),
              this->tracing_enabled_));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\npriority_mask_ = 0x%x\n"),
              this->priority_mask_));
  if (this->thr_desc_ != 0 && this->thr_desc_->state () != 0)
    ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_state_ = %d\n"),
                this->thr_desc_->state ()));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmsg_off_ = %d\n"), this->msg_off_));

  // Be sure that there is a message_queue_, with multiple threads.
  ACE_MT (ACE_Log_Msg_Manager::init_backend ());

  ACE_MT (ACE_Log_Msg_Manager::get_lock ()->dump ());
  // Synchronize output operations.

  ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_HAS_DUMP */
}

void ACE_Log_Msg::enable_debug_messages ( ACE_Log_Priority  priority = LM_DEBUG  )  [static]

Sets the flag in the default priority mask used to initialize ACE_Log_Msg instances.

Definition at line 415 of file Log_Msg.cpp.

void ACE_Log_Msg::errnum ( int  e  )  [inline]

Set the value of the errnum (by convention this corresponds to errno).

Definition at line 65 of file Log_Msg.inl.

{
  this->errnum_ = e;
}

int ACE_Log_Msg::errnum ( void   )  const [inline]

Get the value of the errnum (by convention this corresponds to errno).

Definition at line 58 of file Log_Msg.inl.

{
  return this->errnum_;
}

int ACE_Log_Msg::exists ( void   )  [static]

Returns non-null if an ACE_Log_Msg exists for the calling thread.

Definition at line 266 of file Log_Msg.cpp.

{
#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 */
}

void ACE_Log_Msg::file ( const char *  s  )  [inline]

Set the file name where an error occurred.

Definition at line 165 of file Log_Msg.inl.

{
  ACE_OS::strsncpy (this->file_, s, sizeof this->file_);
}

const char * ACE_Log_Msg::file ( void   )  [inline]

Get the file name where an error occurred.

Definition at line 158 of file Log_Msg.inl.

{
  return this->file_;
}

u_long ACE_Log_Msg::flags ( void   ) 

Return the bits in the logger's options flags.

Definition at line 568 of file Log_Msg.cpp.

{
  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;
}

pid_t ACE_Log_Msg::getpid ( void   )  const [inline]

Optimize reading of the pid (avoids a system call if the value is cached...).

Definition at line 224 of file Log_Msg.inl.

int ACE_Log_Msg::inc ( void   )  [inline]

Nesting depth increment.

Definition at line 86 of file Log_Msg.inl.

{
  return this->trace_depth_++;
}

void ACE_Log_Msg::inherit_hook ( ACE_OS_Thread_Descriptor thr_desc,
ACE_OS_Log_Msg_Attributes attributes 
) [static]

Inherit hook, the attributes field is a ACE_OS_Log_Msg_Attributes object, invoke the inherit_log_msg() method on it, then destroy it and set the attribute argument to 0.

Definition at line 2635 of file Log_Msg.cpp.

{
#if !defined (ACE_THREADS_DONT_INHERIT_LOG_MSG)  && \
    !defined (ACE_HAS_MINIMAL_ACE_OS)
  // Inherit the logging features if the parent thread has an
  // <ACE_Log_Msg>.  Note that all of the following operations occur
  // within thread-specific storage.
  ACE_Log_Msg *new_log = ACE_LOG_MSG;

  // Note that we do not inherit the callback because this might have
  // been allocated off of the stack of the original thread, in which
  // case all hell would break loose...

  if (attributes.ostream_)
    {
      new_log->ostream_ = attributes.ostream_;
      new_log->ostream_refcount_ =
        static_cast<Atomic_ULong *> (attributes.ostream_refcount_);

      new_log->priority_mask (attributes.priority_mask_);

      if (attributes.tracing_enabled_)
        new_log->start_tracing ();

      new_log->restart (attributes.restart_);
      new_log->trace_depth (attributes.trace_depth_);
    }

  // @@ Now the TSS Log_Msg has been created, cache my thread
  // descriptor in.

  if (thr_desc != 0)
    // This downcast is safe.  We do it to avoid having to #include
    // ace/Thread_Manager.h.
    new_log->thr_desc (static_cast<ACE_Thread_Descriptor *> (thr_desc));
  // Block the thread from proceeding until
  // thread manager has thread descriptor ready.
#endif /* ! ACE_THREADS_DONT_INHERIT_LOG_MSG  &&  ! ACE_HAS_MINIMAL_ACE_OS */
}

void ACE_Log_Msg::init_hook ( ACE_OS_Log_Msg_Attributes attributes  )  [static]
Parameters:
attributes Init hook, create a Log_Msg_Attribute object, initialize its attributes from the TSS Log_Msg and save the object in the attributes argument

Definition at line 2603 of file Log_Msg.cpp.

{
# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
  attributes.seh_except_selector_ = selector;
  attributes.seh_except_handler_ = handler;
# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
  if (ACE_Log_Msg::exists ())
    {
      ACE_Log_Msg *inherit_log = ACE_LOG_MSG;
      attributes.ostream_ = inherit_log->msg_ostream ();
      if (attributes.ostream_ && inherit_log->ostream_refcount_)
        {
          ++*inherit_log->ostream_refcount_;
          attributes.ostream_refcount_ = inherit_log->ostream_refcount_;
        }
      else
        {
          attributes.ostream_refcount_ = 0;
        }
      attributes.priority_mask_ = inherit_log->priority_mask ();
      attributes.tracing_enabled_ = inherit_log->tracing_enabled ();
      attributes.restart_ = inherit_log->restart ();
      attributes.trace_depth_ = inherit_log->trace_depth ();
    }
}

ACE_Log_Msg * ACE_Log_Msg::instance ( void   )  [static]

Returns a pointer to the Singleton.

Definition at line 287 of file Log_Msg.cpp.

{
#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 */
}

int ACE_Log_Msg::last_error_adapter ( void   )  [static]

Returns last error.

Definition at line 406 of file Log_Msg.cpp.

{
  return ACE_OS::last_error ();
}

void ACE_Log_Msg::linenum ( int  l  )  [inline]

Set the line number where an error occurred.

Definition at line 79 of file Log_Msg.inl.

{
  this->linenum_ = l;
}

int ACE_Log_Msg::linenum ( void   )  const [inline]

Get the line number where an error occurred.

Definition at line 72 of file Log_Msg.inl.

{
  return this->linenum_;
}

const ACE_TCHAR * ACE_Log_Msg::local_host ( void   )  const [inline]

Get the name of the local host.

Definition at line 217 of file Log_Msg.inl.

void ACE_Log_Msg::local_host ( const ACE_TCHAR s  ) 

Set the name of the local host.

Definition at line 2569 of file Log_Msg.cpp.

{
  if (s)
    {
      ACE_OS::free ((void *) ACE_Log_Msg::local_host_);
      {
        ACE_NO_HEAP_CHECK;

        ACE_ALLOCATOR (ACE_Log_Msg::local_host_, ACE_OS::strdup (s));
      }
    }
}

ssize_t ACE_Log_Msg::log ( ACE_Log_Record log_record,
int  suppress_stderr = 0 
)

Log a custom built log record to the currently enabled logging sinks.

Definition at line 2252 of file Log_Msg.cpp.

{
  ssize_t result = 0;

  // Format the message and print it to stderr and/or ship it off to
  // the log_client daemon, and/or print it to the ostream.  Of
  // course, only print the message if "SILENT" mode is disabled.
  if (ACE_BIT_DISABLED (ACE_Log_Msg::flags_,
                        ACE_Log_Msg::SILENT))
    {
      bool tracing = this->tracing_enabled ();
      this->stop_tracing ();

#if !defined (ACE_WIN32)
      // Make this block signal-safe.
      ACE_Log_Msg_Sig_Guard sb;
#endif /* !ACE_WIN32 */

      // Do the callback, if needed, before acquiring the lock
      // to avoid holding the lock during the callback so we don't
      // have deadlock if the callback uses the logger.
      if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
                           ACE_Log_Msg::MSG_CALLBACK)
          && this->msg_callback () != 0)
        this->msg_callback ()->log (log_record);

      // Make sure that the lock is held during all this.
      ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
                                *ACE_Log_Msg_Manager::get_lock (),
                                -1));

      if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
                           ACE_Log_Msg::STDERR)
          && !suppress_stderr) // This is taken care of by our caller.
        log_record.print (ACE_Log_Msg::local_host_,
                          ACE_Log_Msg::flags_,
                          stderr);

      if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM) ||
          ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG) ||
          ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER))
        {
          // Be sure that there is a message_queue_, with multiple threads.
          ACE_MT (ACE_Log_Msg_Manager::init_backend ());
        }


      if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER) ||
          ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG))
        {
          result =
            ACE_Log_Msg_Manager::log_backend_->log (log_record);
        }

      if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM) &&
          ACE_Log_Msg_Manager::custom_backend_ != 0)
        {
          result =
            ACE_Log_Msg_Manager::custom_backend_->log (log_record);
        }

      // This must come last, after the other two print operations
      // (see the <ACE_Log_Record::print> method for details).
      if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
                           ACE_Log_Msg::OSTREAM)
          && this->msg_ostream () != 0)
        log_record.print (ACE_Log_Msg::local_host_,
                          ACE_Log_Msg::flags_,
#if defined (ACE_LACKS_IOSTREAM_TOTALLY)
                          static_cast<FILE *> (this->msg_ostream ())
#else  /* ! ACE_LACKS_IOSTREAM_TOTALLY */
                          *this->msg_ostream ()
#endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
                          );

      if (tracing)
        this->start_tracing ();
   }

  return result;
}

ssize_t ACE_Log_Msg::log ( ACE_Log_Priority  log_priority,
const ACE_TCHAR format_str,
  ... 
)

Format a message to the thread-safe ACE logging mechanism. Valid options (prefixed by '', as in printf format strings) include:

  • 'A': print an ACE_timer_t value (which could be either double or ACE_UINT32.)
  • 'a': abort the program at this point abruptly.
  • 'b': print a ssize_t value
  • 'B': print a size_t value
  • 'c': print a character
  • 'C': print a char* character string (also see s and W)
  • 'i', 'd': print a decimal number
  • 'I': indent according to nesting depth (obtained from ACE_Trace::get_nesting_indent()).
  • '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': print out the current process id
  • 'p': print out 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': prints a ACE_TCHAR* character string (also see C and W)
  • 'T': print timestamp in hour:minute:sec:usec format (plain option, i.e. without any flags, prints system supplied timestamp; with '#' flag added expects ACE_Time_Value* in argument list)
  • 'D': print timestamp as Weekday Month day year hour:minute:sec.usec (plain option, i.e. without any flags, prints system supplied timestamp; with '#' flag added expects ACE_Time_Value* in argument list)
  • 't': print thread id (1 if single-threaded)
  • 'u': print as unsigned int
  • 'w': prints a wide character
  • 'W': prints a wchar_t* character string (also see C and s)
  • 'x': print as a hex number
  • 'X': print as a hex number
  • 'z': print an ACE_OS::WChar character
  • 'Z': print an ACE_OS::WChar character string
  • ':': print a time_t value as an integral number
  • '': print out a single percent sign, ''
  • '?': print out stack trace (see Stack_Trace.h header comments)

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, ''

Definition at line 934 of file Log_Msg.cpp.

{
  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;
}

ssize_t ACE_Log_Msg::log ( const ACE_TCHAR format,
ACE_Log_Priority  priority,
va_list  argp 
)

An alternative logging mechanism that makes it possible to integrate variable argument lists from other logging mechanisms into the ACE mechanism.

Definition at line 978 of file Log_Msg.cpp.

{
  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_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('?'));
                      }

                      ACE_UPDATE_COUNT (bspace, this_len);
                  }
                  else
                  {
                      // Nope, print out standard priority_name() string

#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,
                           ACE_Log_Record::priority_name (log_priority));
                      else
                        this_len = ACE_OS::sprintf
                          (bp, format,
                           ACE_Log_Record::priority_name (log_priority));
                      ACE_UPDATE_COUNT (bspace, this_len);
                  }
                  break;

                case 'm': // Format the string assocated with the errno value.
                  {
                    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"));
#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_TEXT_CHAR_TO_TCHAR (msg));
                        else
                          this_len = ACE_OS::sprintf
                            (bp, format, 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.
                        if (lpMsgBuf == 0)
                          {
                            const ACE_TCHAR *message =
                              ACE::sock_error (errno);
                            ACE_OS::strcpy (fp, ACE_TEXT ("s"));
                            if (can_check)
                              this_len = ACE_OS::snprintf
                                (bp, bspace, format, message);
                            else
                              this_len = ACE_OS::sprintf (bp, format, message);
                          }
                        else
                          {
                            ACE_OS::strcpy (fp, ACE_TEXT ("s"));
                            if (can_check)
                              this_len = ACE_OS::snprintf
                                (bp, bspace, format, lpMsgBuf);
                            else
                              this_len = ACE_OS::sprintf
                                (bp, format, lpMsgBuf);
                            // Free the buffer.
                            ::LocalFree (lpMsgBuf);
                          }
                      }
#endif /* ACE_WIN32 */
                    ACE_UPDATE_COUNT (bspace, this_len);
                    break;
                  }

                case 'R': // Format the return status of the operation.
                  this->op_status (va_arg (argp, int));
                  ACE_OS::strcpy (fp, ACE_TEXT ("d"));
                  if (can_check)
                    this_len = ACE_OS::snprintf
                      (bp, bspace, format, this->op_status ());
                  else
                    this_len = ACE_OS::sprintf
                      (bp, format, this->op_status ());
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;

                case '{': // Increment the trace_depth, then indent
                  skip_nul_locate = true;
                  (void) this->inc ();
                  break;

                case '}': // indent, then decrement trace_depth
                  skip_nul_locate = true;
                  (void) this->dec ();
                  break;

                case '$': // insert a newline, then indent the next line
                          // according to %I
                  *bp++ = '\n';
                  --bspace;
                  /* fallthrough */

                case 'I': // Indent with nesting_depth*width spaces
                  // Caller can do %*I to override nesting indent, and
                  // if %*I was done, wp has the extracted width.
#if defined (ACE_HAS_TRACE)
                  if (0 == wp)
                    wp = ACE_Trace::get_nesting_indent ();
#else
                  if (0 == wp)
                    wp = 4;
#endif /* ACE_HAS_TRACE */
                  wp *= this->trace_depth_;
                  if (static_cast<size_t> (wp) > bspace)
                    wp = static_cast<int> (bspace);
                  for (tmp_indent = wp;
                       tmp_indent;
                       --tmp_indent)
                    *bp++ = ' ';

                  *bp = '\0';
                  bspace -= static_cast<size_t> (wp);
                  skip_nul_locate = true;
                  break;

                case 'r': // Run (invoke) this subroutine.
                  {
                    ptrdiff_t const osave = ACE_Log_Msg::msg_off_;

                    if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
                                         ACE_Log_Msg::SILENT) &&
                        bspace > 1)
                      {
                        *bp++ = '{';
                        --bspace;
                      }
                    ACE_Log_Msg::msg_off_ =  bp - this->msg_;

                    (*va_arg (argp, PTF))();

                    if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
                                         ACE_Log_Msg::SILENT) &&
                        bspace > (1 + ACE_OS::strlen (bp)))
                      {
                        bspace -= (ACE_OS::strlen (bp) + 1);
                        bp += ACE_OS::strlen (bp);
                        *bp++ =  '}';
                      }
                    *bp = '\0';
                    skip_nul_locate = true;
                    ACE_Log_Msg::msg_off_ = osave;
                    break;
                  }

                case 'S': // format the string for with this signal number.
                  {
                    const int sig = va_arg (argp, int);
                    ACE_OS::strcpy (fp, ACE_TEXT ("s"));
                    if (can_check)
                      this_len = ACE_OS::snprintf
                        (bp, bspace, format, ACE_OS::strsignal(sig));
                    else
                      this_len = ACE_OS::sprintf
                        (bp, format, ACE_OS::strsignal(sig));
                    ACE_UPDATE_COUNT (bspace, this_len);
                    break;
                  }

                case 'D': // Format the timestamp in format:
                          // Weekday Month day year hour:minute:sec.usec
                  {
                    ACE_TCHAR day_and_time[35];
                    // Did we find the flag indicating a time value argument 
                    if (format[1] == ACE_TEXT('#'))
                    {
                      ACE_Time_Value* time_value = va_arg (argp, ACE_Time_Value*);
                      ACE::timestamp (*time_value,
                                      day_and_time,
                                      sizeof day_and_time / sizeof (ACE_TCHAR));
                    }
                    else
                    {
                      ACE::timestamp (day_and_time,
                                      sizeof day_and_time / sizeof (ACE_TCHAR));
                    }
#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, day_and_time);
                    else
                      this_len = ACE_OS::sprintf (bp, format, day_and_time);
                    ACE_UPDATE_COUNT (bspace, this_len);
                    break;
                  }

                case 'T': // Format the timestamp in
                          // hour:minute:sec:usec format.
                  {
                    ACE_TCHAR day_and_time[35];
#if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
                    ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
#else
                    ACE_OS::strcpy (fp, ACE_TEXT ("s"));
#endif
                    // Did we find the flag indicating a time value argument 
                    if (format[1] == ACE_TEXT('#'))
                    {
                      ACE_Time_Value* time_value = va_arg (argp, ACE_Time_Value*);
                      if (can_check)
                        this_len = ACE_OS::snprintf
                          (bp, bspace, format,
                          ACE::timestamp (*time_value, 
                                         day_and_time, 
                                         sizeof day_and_time / sizeof (ACE_TCHAR)));
                      else
                        this_len = ACE_OS::sprintf
                          (bp, format, ACE::timestamp (*time_value,
                                                      day_and_time,
                                                      sizeof day_and_time / sizeof (ACE_TCHAR)));
                    }
                    else
                    {
                      if (can_check)
                        this_len = ACE_OS::snprintf
                          (bp, bspace, format,
                          ACE::timestamp (day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR)));
                      else
                        this_len = ACE_OS::sprintf
                          (bp, format, ACE::timestamp (day_and_time,
                                                      sizeof day_and_time / sizeof (ACE_TCHAR)));
                    }
                    ACE_UPDATE_COUNT (bspace, this_len);
                    break;
                  }

                case 't': // Format thread id.
#if defined (ACE_WIN32)
                  ACE_OS::strcpy (fp, ACE_TEXT ("u"));
                  if (can_check)
                    this_len = ACE_OS::snprintf
                      (bp, bspace, format,
                       static_cast<unsigned> (ACE_Thread::self ()));
                  else
                    this_len =
                      ACE_OS::sprintf (bp,
                                       format,
                                       static_cast <unsigned> (ACE_Thread::self ()));
#elif defined (DIGITAL_UNIX)
                  ACE_OS::strcpy (fp, ACE_TEXT ("u"));
                  {
                    int id =
#  if defined (ACE_HAS_THREADS)
                      pthread_getselfseq_np ();
#  else
                      ACE_Thread::self ();
#  endif /* ACE_HAS_THREADS */

                      if (can_check)
                        this_len = ACE_OS::snprintf (bp, bspace, format, id);
                      else
                        this_len = ACE_OS::sprintf (bp, format, id);
                  }
#else
                  ACE_hthread_t t_id;
                  ACE_Thread::self (t_id);

#  if defined (ACE_MVS) || defined (ACE_TANDEM_T1248_PTHREADS)
                  // MVS's pthread_t is a struct... yuck. So use the ACE 5.0
                  // code for it.
                  ACE_OS::strcpy (fp, ACE_TEXT ("u"));
                  if (can_check)
                    this_len = ACE_OS::snprintf (bp, bspace, format, t_id);
                  else
                    this_len = ACE_OS::sprintf (bp, format, t_id);
#  else
                  // Yes, this is an ugly C-style cast, but the correct
                  // C++ cast is different depending on whether the t_id
                  // is an integral type or a pointer type. FreeBSD uses
                  // a pointer type, but doesn't have a _np function to
                  // get an integral type, like the OSes above.
                  ACE_OS::strcpy (fp, ACE_TEXT ("lu"));
                  if (can_check)
                    this_len = ACE_OS::snprintf
                      (bp, bspace, format, (unsigned long)t_id);
                  else
                    this_len = ACE_OS::sprintf
                      (bp, format, (unsigned long)t_id);
#  endif /* ACE_MWS || ACE_TANDEM_T1248_PTHREADS */

#endif /* ACE_WIN32 */
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;

                case 's':                       // String
                  {
#if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
                    wchar_t *str = va_arg (argp, wchar_t *);
                    ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
#else /* ACE_WIN32 && ACE_USES_WCHAR */
                    ACE_TCHAR *str = va_arg (argp, ACE_TCHAR *);
                    ACE_OS::strcpy (fp, ACE_TEXT ("s"));
#endif /* ACE_WIN32 && ACE_USES_WCHAR */
                    if (can_check)
                      this_len = ACE_OS::snprintf
                        (bp, bspace, format, str ? str : ACE_TEXT ("(null)"));
                    else
                      this_len = ACE_OS::sprintf
                        (bp, format, str ? str : ACE_TEXT ("(null)"));
                    ACE_UPDATE_COUNT (bspace, this_len);
                  }
                  break;

                case 'C':         // Narrow-char string
                  {
                    char *cstr = va_arg (argp, char *);
#if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
                    ACE_OS::strcpy (fp, ACE_TEXT ("S"));
#else /* ACE_WIN32 && ACE_USES_WCHAR */
                    ACE_OS::strcpy (fp, ACE_TEXT ("s"));
#endif /* ACE_WIN32 && ACE_USES_WCHAR */
                    if (can_check)
                      this_len = ACE_OS::snprintf
                        (bp, bspace, format, cstr ? cstr : "(null)");
                    else
                      this_len = ACE_OS::sprintf
                        (bp, format, cstr ? cstr : "(null)");
                    ACE_UPDATE_COUNT (bspace, this_len);
                  }
                  break;

                case 'W':
                  {
#if defined (ACE_HAS_WCHAR)
                    wchar_t *wchar_str = va_arg (argp, wchar_t *);
# if defined (HPUX)
                    ACE_OS::strcpy (fp, ACE_TEXT ("S"));
# elif defined (ACE_WIN32)
#   if defined (ACE_USES_WCHAR)
                    ACE_OS::strcpy (fp, ACE_TEXT ("s"));
#   else /* ACE_USES_WCHAR */
                    ACE_OS::strcpy (fp, ACE_TEXT ("S"));
#   endif /* ACE_USES_WCHAR */
# else
                    ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
# endif /* HPUX */
                    if (can_check)
                      this_len = ACE_OS::snprintf
                        (bp, bspace, format, wchar_str ? wchar_str : ACE_TEXT_WIDE("(null)"));
                    else
                      this_len = ACE_OS::sprintf
                        (bp, format, wchar_str ? wchar_str : ACE_TEXT_WIDE("(null)"));
#endif /* ACE_HAS_WCHAR */
                    ACE_UPDATE_COUNT (bspace, this_len);
                  }
                  break;

                case 'w':              // Wide character
#if defined (ACE_WIN32)
# if defined (ACE_USES_WCHAR)
                  ACE_OS::strcpy (fp, ACE_TEXT ("c"));
# else /* ACE_USES_WCHAR */
                  ACE_OS::strcpy (fp, ACE_TEXT ("C"));
# endif /* ACE_USES_WCHAR */
                  if (can_check)
                    this_len = ACE_OS::snprintf
                      (bp, bspace, format, va_arg (argp, int));
                  else
                    this_len = ACE_OS::sprintf
                      (bp, format, va_arg (argp, int));
#elif defined (ACE_USES_WCHAR)
# if defined (HPUX)
                  ACE_OS::strcpy (fp, ACE_TEXT ("C"));
# else
                  ACE_OS::strcpy (fp, ACE_TEXT ("lc"));
# endif /* HPUX */
                  if (can_check)
                    this_len = ACE_OS::snprintf
                      (bp, bspace, format, va_arg (argp, wint_t));
                  else
                    this_len = ACE_OS::sprintf
                      (bp, format, va_arg (argp, wint_t));
#else /* ACE_WIN32 */
                  ACE_OS::strcpy (fp, ACE_TEXT ("u"));
                  if (can_check)
                    this_len = ACE_OS::snprintf
                      (bp, bspace, format, va_arg (argp, int));
                  else
                    this_len = ACE_OS::sprintf
                      (bp, format, va_arg (argp, int));
#endif /* ACE_WIN32 */
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;

                case 'z':              // ACE_OS::WChar character
                  {
                    // On some platforms sizeof (wchar_t) can be 2
                    // on the others 4 ...
                    wchar_t wtchar =
                      static_cast<wchar_t> (va_arg (argp, int));
#if defined (ACE_WIN32)
# if defined (ACE_USES_WCHAR)
                    ACE_OS::strcpy (fp, ACE_TEXT ("c"));
# else /* ACE_USES_WCHAR */
                    ACE_OS::strcpy (fp, ACE_TEXT ("C"));
# endif /* ACE_USES_WCHAR */
#elif defined (ACE_USES_WCHAR)
# if defined (HPUX)
                    ACE_OS::strcpy (fp, ACE_TEXT ("C"));
# else
                    ACE_OS::strcpy (fp, ACE_TEXT ("lc"));
# endif /* HPUX */
#else /* ACE_WIN32 */
                    ACE_OS::strcpy (fp, ACE_TEXT ("u"));
#endif /* ACE_WIN32 */
                    if (can_check)
                      this_len = ACE_OS::snprintf (bp, bspace, format, wtchar);
                    else
                      this_len = ACE_OS::sprintf (bp, format, wtchar);
                    ACE_UPDATE_COUNT (bspace, this_len);
                    break;
                  }

                 case 'Z':              // ACE_OS::WChar character string
                  {
                    ACE_OS::WChar *wchar_str = va_arg (argp, ACE_OS::WChar*);
                    if (wchar_str == 0)
                      break;

                    wchar_t *wchar_t_str = 0;
                    if (sizeof (ACE_OS::WChar) != sizeof (wchar_t))
                      {
                        size_t len = ACE_OS::wslen (wchar_str) + 1;
                        ACE_NEW_NORETURN(wchar_t_str, wchar_t[len]);
                        if (wchar_t_str == 0)
                          break;

                        for (size_t i = 0; i < len; ++i)
                          {
                            wchar_t_str[i] = wchar_str[i];
                          }
                      }

                    if (wchar_t_str == 0)
                      {
                        wchar_t_str = reinterpret_cast<wchar_t*> (wchar_str);
                      }
#if defined (ACE_WIN32)
# if defined (ACE_USES_WCHAR)
                  ACE_OS::strcpy (fp, ACE_TEXT ("s"));
# else /* ACE_USES_WCHAR */
                  ACE_OS::strcpy (fp, ACE_TEXT ("S"));
# endif /* ACE_USES_WCHAR */
#elif defined (ACE_HAS_WCHAR)
# if defined (HPUX)
                  ACE_OS::strcpy (fp, ACE_TEXT ("S"));
# else
                  ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
# endif /* HPUX */
#endif /* ACE_WIN32 / ACE_HAS_WCHAR */
                  if (can_check)
                    this_len = ACE_OS::snprintf
                      (bp, bspace, format, wchar_t_str);
                  else
                    this_len = ACE_OS::sprintf (bp, format, wchar_t_str);
                  if(sizeof(ACE_OS::WChar) != sizeof(wchar_t))
                    {
                      delete [] wchar_t_str;
                    }
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;
                  }

                case 'c':
#if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
                  ACE_OS::strcpy (fp, ACE_TEXT ("C"));
#else
                  ACE_OS::strcpy (fp, ACE_TEXT ("c"));
#endif /* ACE_WIN32 && ACE_USES_WCHAR */
                  if (can_check)
                    this_len = ACE_OS::snprintf
                      (bp, bspace, format, va_arg (argp, int));
                  else
                    this_len = ACE_OS::sprintf
                      (bp, format, va_arg (argp, int));
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;

                case 'd': case 'i': case 'o':
                case 'u': case 'x': case 'X':
                  fp[0] = *format_str;
                  fp[1] = '\0';
                  if (can_check)
                    this_len = ACE_OS::snprintf
                      (bp, bspace, format, va_arg (argp, int));
                  else
                    this_len = ACE_OS::sprintf
                      (bp, format, va_arg (argp, int));
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;

                case 'F': case 'f': case 'e': case 'E':
                case 'g': case 'G':
                  fp[0] = *format_str;
                  fp[1] = '\0';
                  if (can_check)
                    this_len = ACE_OS::snprintf
                      (bp, bspace, format, va_arg (argp, double));
                  else
                    this_len = ACE_OS::sprintf
                      (bp, format, va_arg (argp, double));
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;

                case 'Q':
#if defined (ACE_LACKS_LONGLONG_T) || defined (ACE_LACKS_UNSIGNEDLONGLONG_T)
                  {
                    // This relies on the ACE_U_LongLong storage layout.
                    ACE_UINT32 hi = va_arg (argp, ACE_UINT32);
                    ACE_UINT32 lo = va_arg (argp, ACE_UINT32);
                    if (hi > 0)
                      this_len = ACE_OS::sprintf (bp,
                                                  "0x%lx%0*lx",
                                                  hi,
                                                  2 * sizeof lo,
                                                  lo);
                    else
                      this_len = ACE_OS::sprintf (bp, "0x%lx", lo);
                  }
#else  /* ! ACE_LACKS_LONGLONG_T */
                  {
                    const ACE_TCHAR *fmt = ACE_UINT64_FORMAT_SPECIFIER;
                    ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
                    if (can_check)
                      this_len = ACE_OS::snprintf (bp, bspace,
                                                   format,
                                                   va_arg (argp, ACE_UINT64));
                    else
                      this_len = ACE_OS::sprintf (bp,
                                                  format,
                                                  va_arg (argp, ACE_UINT64));
                  }
#endif /* ! ACE_LACKS_LONGLONG_T || ACE_LACKS_UNSIGNEDLONGLONG_T */
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;

                case 'q':
 #if defined (ACE_LACKS_LONGLONG_T)
                   // No implementation available yet, no ACE_INT64 emulation
                   // available yet
 #else  /* ! ACE_LACKS_LONGLONG_T */
                   {
                     const ACE_TCHAR *fmt = ACE_INT64_FORMAT_SPECIFIER;
                     ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
                     if (can_check)
                       this_len = ACE_OS::snprintf (bp, bspace,
                                                    format,
                                                    va_arg (argp, ACE_INT64));
                     else
                       this_len = ACE_OS::sprintf (bp,
                                                   format,
                                                   va_arg (argp, ACE_INT64));
                   }
 #endif /* ! ACE_LACKS_LONGLONG_T */
                   ACE_UPDATE_COUNT (bspace, this_len);
                   break;

                case 'b':
                  {
                    const ACE_TCHAR *fmt = ACE_SSIZE_T_FORMAT_SPECIFIER;
                    ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
                  }
                  if (can_check)
                    this_len = ACE_OS::snprintf (bp, bspace,
                                                 format,
                                                 va_arg (argp, ssize_t));
                  else
                    this_len = ACE_OS::sprintf (bp,
                                                format,
                                                va_arg (argp, ssize_t));
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;

                case 'B':
                  {
                    const ACE_TCHAR *fmt = ACE_SIZE_T_FORMAT_SPECIFIER;
                    ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
                  }
                  if (can_check)
                    this_len = ACE_OS::snprintf (bp, bspace,
                                                 format,
                                                 va_arg (argp, size_t));
                  else
                    this_len = ACE_OS::sprintf (bp,
                                                format,
                                                va_arg (argp, size_t));
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;

                case ':':
                  {
                    // Assume a 32 bit time_t and change if needed.
                    const ACE_TCHAR *fmt = ACE_TEXT ("%d");
                    if (sizeof (time_t) == 8)
                      fmt = ACE_INT64_FORMAT_SPECIFIER;

                    ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
                  }
                  if (can_check)
                    this_len = ACE_OS::snprintf (bp, bspace,
                                                 format,
                                                 va_arg (argp, time_t));
                  else
                    this_len = ACE_OS::sprintf (bp,
                                                format,
                                                va_arg (argp, time_t));
                  ACE_UPDATE_COUNT (bspace, this_len);
                  break;

                case '@':
                    ACE_OS::strcpy (fp, ACE_TEXT ("p"));
                    if (can_check)
                      this_len = ACE_OS::snprintf
                        (bp, bspace, format, va_arg (argp, void*));
                    else
                      this_len = ACE_OS::sprintf
                        (bp, format, va_arg (argp, void*));
                    ACE_UPDATE_COUNT (bspace, this_len);
                    break;

                case '?':
                  // Stack trace up to this point
                  {
                    // skip the frame that we're currently in
                    ACE_Stack_Trace t(2);
                    ACE_OS::strcpy (fp, ACE_TEXT ("s"));
                    if (can_check)
                      this_len = ACE_OS::snprintf
                        (bp, bspace, format, t.c_str ());
                    else
                      this_len = ACE_OS::sprintf
                        (bp, format, t.c_str ());
                    ACE_UPDATE_COUNT (bspace, this_len);
                    break;
                  }


                default:
                  // So, it's not a legit format specifier after all...
                  // Copy from the original % to where we are now, then
                  // continue with whatever comes next.
                  while (start_format != format_str && bspace > 0)
                    {
                      *bp++ = *start_format++;
                      --bspace;
                    }
                  if (bspace > 0)
                    {
                      *bp++ = *format_str;
                      --bspace;
                    }
                  break;
                }

              // Bump to the next char in the caller's format_str
              ++format_str;
            }

          if (!skip_nul_locate)
            while (*bp != '\0') // Locate end of bp.
              ++bp;
        }
    }

  *bp = '\0'; // Terminate bp, but don't auto-increment this!

  ssize_t result = 0;

  // Check that memory was not corrupted, if it corrupted we can't log anything
  // anymore because all our members could be corrupted.
  if (bp >= (this->msg_ + ACE_MAXLOGMSGLEN+1))
    {
      abort_prog = true;
      ACE_OS::fprintf (stderr,
                       "The following logged message is too long!\n");
    }
  else
    {
      // Copy the message from thread-specific storage into the transfer
      // buffer (this can be optimized away by changing other code...).
      log_record.msg_data (this->msg ());

      // Write the <log_record> to the appropriate location.
      result = this->log (log_record,
                          abort_prog);
    }

  if (abort_prog)
    {
      // Since we are now calling abort instead of exit, this value is
      // not used.
      ACE_UNUSED_ARG (exit_value);

      // *Always* print a message to stderr if we're aborting.  We
      // don't use verbose, however, to avoid recursive aborts if
      // something is hosed.
      log_record.print (ACE_Log_Msg::local_host_, 0, stderr);
      ACE_OS::abort ();
    }

   return result;
}

int ACE_Log_Msg::log_hexdump ( ACE_Log_Priority  log_priority,
const char *  buffer,
size_t  size,
const ACE_TCHAR text = 0 
)

Method to log hex dump. This is useful for debugging. Calls log() to do the actual print, but formats first to make the chars printable.

Definition at line 2338 of file Log_Msg.cpp.

{
  // 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;

  ACE_TCHAR* buf = 0;
  size_t const buf_sz =
    ACE_Log_Record::MAXLOGMSGLEN - ACE_Log_Record::VERBOSE_LEN - 58;
  ACE_NEW_RETURN (buf, ACE_TCHAR[buf_sz], -1);

  ACE_TCHAR *msg_buf = 0;
  const size_t text_sz = text ? ACE_OS::strlen(text) : 0;
  ACE_NEW_RETURN (msg_buf,
                  ACE_TCHAR[text_sz + 58],
                 -1);

  buf[0] = 0; // in case size = 0

  size_t const len = ACE::format_hexdump
    (buffer, size, buf, buf_sz / sizeof (ACE_TCHAR) - text_sz);

  int sz = 0;

  if (text)
    sz = ACE_OS::sprintf (msg_buf,
#if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
                          ACE_TEXT ("%ls - "),
#else
                          ACE_TEXT ("%s - "),
#endif
                          text);

  sz += ACE_OS::sprintf (msg_buf + sz,
                         ACE_TEXT ("HEXDUMP ")
                         ACE_SIZE_T_FORMAT_SPECIFIER
                         ACE_TEXT (" bytes"),
                         size);

  if (len < size)
    ACE_OS::sprintf (msg_buf + sz,
                     ACE_TEXT (" (showing first ")
                     ACE_SIZE_T_FORMAT_SPECIFIER
                     ACE_TEXT (" bytes)"),
                     len);

  // Now print out the formatted buffer.
  this->log (log_priority,
             ACE_TEXT ("%s\n%s"),
             msg_buf,
             buf);

  delete [] msg_buf;
  delete [] buf;
  return 0;
}

int ACE_Log_Msg::log_priority_enabled ( ACE_Log_Priority  log_priority  )  [inline]

Return true if the requested priority is enabled.

Definition at line 21 of file Log_Msg.inl.

int ACE_Log_Msg::log_priority_enabled ( ACE_Log_Priority  log_priority,
const char *  ,
  ... 
)

Return true if the requested priority is enabled.

Definition at line 2583 of file Log_Msg.cpp.

{
  return this->log_priority_enabled (log_priority);
}

void ACE_Log_Msg::msg ( const ACE_TCHAR m  )  [inline]

Set the message that describes what type of error occurred.

Definition at line 179 of file Log_Msg.inl.

{
  ACE_OS::strsncpy (this->msg_, m,
                    ((ACE_MAXLOGMSGLEN+1) / sizeof (ACE_TCHAR)));
}

const ACE_TCHAR * ACE_Log_Msg::msg ( void   )  [inline]

Get the message that describes what type of error occurred.

Definition at line 172 of file Log_Msg.inl.

{
  return this->msg_ + ACE_Log_Msg::msg_off_;
}

ACE_Log_Msg_Backend * ACE_Log_Msg::msg_backend ( void   )  [static]

Definition at line 2526 of file Log_Msg.cpp.

{
  ACE_TRACE ("ACE_Log_Msg::msg_backend");
  ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
                            *ACE_Log_Msg_Manager::get_lock (), 0));

  return ACE_Log_Msg_Manager::custom_backend_;
}

ACE_Log_Msg_Backend * ACE_Log_Msg::msg_backend ( ACE_Log_Msg_Backend b  )  [static]

Set a new backend object and return the existing backend to allow "chaining". Note that as opposed to ACE_Log_Msg_Callback, ACE_Log_Msg_Backend is a per-process entity.

Note:
Be aware that because of the current architecture there is no guarantee that open (), reset () and close () will be called on a backend object.

Definition at line 2514 of file Log_Msg.cpp.

{
  ACE_TRACE ("ACE_Log_Msg::msg_backend");
  ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
                            *ACE_Log_Msg_Manager::get_lock (), 0));

  ACE_Log_Msg_Backend *tmp  = ACE_Log_Msg_Manager::custom_backend_;
  ACE_Log_Msg_Manager::custom_backend_ = b;
  return tmp;
}

ACE_Log_Msg_Callback * ACE_Log_Msg::msg_callback ( ACE_Log_Msg_Callback c  )  [inline]

Set a new callback object and return the existing callback to allow "chaining". Note that ACE_Log_Msg_Callback objects are not inherited when spawning a new thread, so you'll need to reset them in each thread.

Definition at line 194 of file Log_Msg.inl.

{
  ACE_Log_Msg_Callback *old = this->msg_callback_;
  this->msg_callback_ = c;
  return old;
}

ACE_Log_Msg_Callback * ACE_Log_Msg::msg_callback ( void   )  const [inline]

Definition at line 187 of file Log_Msg.inl.

{
  return this->msg_callback_;
}

void ACE_Log_Msg::msg_ostream ( ACE_OSTREAM_TYPE *  m,
bool  delete_ostream 
)

delete_stream == true, forces Log_Msg.h to delete the stream in its own ~dtor (assumes control of the stream) use only with proper ostream (eg: fstream), not (cout, cerr)

Definition at line 2536 of file Log_Msg.cpp.

{
  if (this->ostream_ == m)
    {
      // Same stream, allow user to change the delete_ostream "flag"
      if (delete_ostream && !this->ostream_refcount_)
        {
          ACE_NEW (this->ostream_refcount_, Atomic_ULong (1));
        }
      else if (!delete_ostream && this->ostream_refcount_)
        {
          if (--*this->ostream_refcount_ == 0)
            {
              delete this->ostream_refcount_;
            }
          this->ostream_refcount_ = 0;
        }
      // The other two cases are no-ops, the user has requested the same
      // state that's already present.
      return;
    }

  this->cleanup_ostream ();

  if (delete_ostream)
    {
      ACE_NEW (this->ostream_refcount_, Atomic_ULong (1));
    }

  this->ostream_ = m;
}

ACE_OSTREAM_TYPE * ACE_Log_Msg::msg_ostream ( void   )  const [inline]

Get the ostream that is used to print error messages.

Definition at line 203 of file Log_Msg.inl.

{
  return this->ostream_;
}

void ACE_Log_Msg::msg_ostream ( ACE_OSTREAM_TYPE *  m  )  [inline]

Update the ostream without overwriting the delete_ostream_ flag.

Definition at line 210 of file Log_Msg.inl.

{
  this->ostream_ = m;
}

void ACE_Log_Msg::op_status ( int  status  )  [inline]

Set the result of the operation status (by convention, -1 means error).

Definition at line 30 of file Log_Msg.inl.

{
  this->status_ = status;
}

int ACE_Log_Msg::op_status ( void   )  const [inline]

Get the result of the operation status (by convention, -1 means error).

Definition at line 37 of file Log_Msg.inl.

{
  return this->status_;
}

int ACE_Log_Msg::open ( const ACE_TCHAR prog_name,
u_long  options_flags = ACE_Log_Msg::STDERR,
const ACE_TCHAR logger_key = 0 
)

Initialize the ACE logging facility.

Initialize the ACE logging facility. Supplies the program name that is available to each logging message call. Default arguments set up logging to STDERR only.

Parameters:
prog_name The name of the calling program.
options_flags A bitwise-or of options flags used to set the initial behavior and logging sink(s). (see the enum above for the valid values).
logger_key The name of ACE_FIFO rendezvous point where the local client logger daemon is listening for logging messages if the LOGGER bit is set in the flags argument. If the SYSLOG bit is set in flags, logger_key is the source/program name specified in the syslog facility (UNIX/Linux) or the Windows event log (Windows). In the SYSLOG case, if logger_key is 0, prog_name is used.

Definition at line 768 of file Log_Msg.cpp.

{
  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;
}

ACE_Log_Msg& ACE_Log_Msg::operator= ( const ACE_Log_Msg  )  [private]
u_long ACE_Log_Msg::priority_mask ( MASK_TYPE  mask_type = THREAD  )  [inline]

Get the current ACE_Log_Priority mask.

Definition at line 12 of file Log_Msg.inl.

{
  return mask_type == THREAD
    ? this->priority_mask_
    :  ACE_Log_Msg::process_priority_mask_;
}

u_long ACE_Log_Msg::priority_mask ( u_long  n_mask,
MASK_TYPE  mask_type = THREAD 
)

Set the ACE_Log_Priority mask, returns original mask.

Definition at line 611 of file Log_Msg.cpp.

{
  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;
}

const ACE_TCHAR * ACE_Log_Msg::program_name ( void   )  [static]

Returns the current program name used for logging.

Definition at line 434 of file Log_Msg.cpp.

int ACE_Log_Msg::release ( void   ) 

Release the internal lock.

Definition at line 630 of file Log_Msg.cpp.

{
  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 */
}

bool ACE_Log_Msg::restart ( void   )  const [inline]

Get the field that indicates whether interrupted calls should be restarted.

Definition at line 51 of file Log_Msg.inl.

{
  return this->restart_;
}

void ACE_Log_Msg::restart ( bool  r  )  [inline]

Set the field that indicates whether interrupted calls should be restarted.

Definition at line 44 of file Log_Msg.inl.

{
  this->restart_ = r;
}

void ACE_Log_Msg::set ( const char *  file,
int  line,
int  op_status = -1,
int  errnum = 0,
bool  restart = true,
ACE_OSTREAM_TYPE *  os = 0,
ACE_Log_Msg_Callback c = 0 
)

Set the line number, file name, operational status, error number, restart flag, ostream, and the callback object. This combines all the other set methods into a single method.

Definition at line 2400 of file Log_Msg.cpp.

{
  ACE_TRACE ("ACE_Log_Msg::set");
  this->file (file);
  this->linenum (line);
  this->op_status (op_status);
  this->errnum (errnum);
  this->restart (restart);
  this->msg_ostream (os);
  this->msg_callback (c);
}

void ACE_Log_Msg::set_flags ( u_long  f  ) 

Enable the bits in the logger's options flags.

Definition at line 580 of file Log_Msg.cpp.

{
  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::start_tracing ( void   )  [inline]

Start tracing status on a per-thread basis...

Enable the tracing facility on a per-thread basis.

Definition at line 136 of file Log_Msg.inl.

{
  this->tracing_enabled_ = true;
}

void ACE_Log_Msg::stop_tracing ( void   )  [inline]

Stop tracing status on a per-thread basis...

Disable the tracing facility on a per-thread basis.

Definition at line 144 of file Log_Msg.inl.

{
  this->tracing_enabled_ = false;
}

void ACE_Log_Msg::sync ( const ACE_TCHAR program_name  ) 

Call after doing a fork() to resynchronize the process id and program_name_ variables.

Definition at line 544 of file Log_Msg.cpp.

{
  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;
}

void ACE_Log_Msg::sync_hook ( const ACE_TCHAR prg_name  )  [static, private]

Decouple the OS layer from the ACE_Log_Msg layer.

Definition at line 530 of file Log_Msg.cpp.

{
  ACE_LOG_MSG->sync (prg_name);
}

void ACE_Log_Msg::thr_desc ( ACE_Thread_Descriptor td  ) 

Set the TSS thread descriptor. This method will call td->acquire_release to block execution until this call return.

Definition at line 2479 of file Log_Msg.cpp.

{
  this->thr_desc_ = td;

  if (td != 0)
    td->acquire_release ();
}

ACE_Thread_Descriptor * ACE_Log_Msg::thr_desc ( void   )  const [inline]

Get the TSS thread descriptor.

Definition at line 128 of file Log_Msg.inl.

{
  return this->thr_desc_;
}

ACE_OS_Thread_Descriptor * ACE_Log_Msg::thr_desc_hook ( void   )  [static, private]

Return the TSS singleton thread descriptor.

Definition at line 536 of file Log_Msg.cpp.

{
  return ACE_LOG_MSG->thr_desc ();
}

bool ACE_Log_Msg::trace_active ( void   )  const [inline]

Get trace active status.

Definition at line 114 of file Log_Msg.inl.

{
  return this->trace_active_;
}

void ACE_Log_Msg::trace_active ( bool  value  )  [inline]

Set trace active status.

Definition at line 121 of file Log_Msg.inl.

{
  this->trace_active_ = value;
}

void ACE_Log_Msg::trace_depth ( int  depth  )  [inline]

Set trace depth.

Definition at line 107 of file Log_Msg.inl.

{
  this->trace_depth_ = depth;
}

int ACE_Log_Msg::trace_depth ( void   )  const [inline]

Get trace depth.

Definition at line 100 of file Log_Msg.inl.

{
  return this->trace_depth_;
}

bool ACE_Log_Msg::tracing_enabled ( void   )  const [inline]

Query tracing status on a per-thread basis...

Definition at line 151 of file Log_Msg.inl.

{
  return this->tracing_enabled_;
}


Member Data Documentation

Declare the dynamic allocation hooks.

Definition at line 605 of file Log_Msg.h.

struct { ... } ACE_Log_Msg::conditional_values_ [private]

Anonymous struct since there will only be one instance. This struct keeps information stored away in case we actually end up calling log() if the log priority is correct.

u_long ACE_Log_Msg::default_priority_mask_ = 0 [static, private]

Priority mask to use for each new instance

Default per-thread priority mask By default, no priorities are enabled.

Definition at line 709 of file Log_Msg.h.

int ACE_Log_Msg::errnum_ [private]

Type of error that occurred (see <sys/errno.h>).

Definition at line 614 of file Log_Msg.h.

char ACE_Log_Msg::file_[MAXPATHLEN+1] [private]

File where the error occurred.

Definition at line 620 of file Log_Msg.h.

const char* ACE_Log_Msg::file_

Definition at line 717 of file Log_Msg.h.

u_long ACE_Log_Msg::flags_ = ACE_Log_Msg::STDERR [static, private]

Default is to use stderr.

Options flags used to hold the logger flag options, e.g., STDERR, LOGGER, OSTREAM, MSG_CALLBACK, etc.

Definition at line 695 of file Log_Msg.h.

int ACE_Log_Msg::instance_count_ = 0 [static, private]

Number of existing ACE_Log_Msg instances; when 0, delete program/host names

Instance count for Log_Msg - used to know when dynamically allocated storage (program name and host name) can be safely deleted.

Definition at line 704 of file Log_Msg.h.

Definition at line 716 of file Log_Msg.h.

Definition at line 718 of file Log_Msg.h.

int ACE_Log_Msg::linenum_ [private]

Line number where the error occurred.

Definition at line 617 of file Log_Msg.h.

const ACE_TCHAR * ACE_Log_Msg::local_host_ = 0 [static, private]

Name of the local host (used when printing messages).

Name of the local host.

Definition at line 688 of file Log_Msg.h.

The log message, which resides in thread-specific storage. Note that only the current log message is stored here -- it will be overwritten by the subsequent call to log().

Definition at line 625 of file Log_Msg.h.

The callback object.

Definition at line 644 of file Log_Msg.h.

ptrdiff_t ACE_Log_Msg::msg_off_ = 0 [static, private]

Offset of msg_[].

Current offset of msg_[].

Definition at line 698 of file Log_Msg.h.

Definition at line 719 of file Log_Msg.h.

ACE_OSTREAM_TYPE* ACE_Log_Msg::ostream_ [private]

The ostream where logging messages can be written.

Definition at line 632 of file Log_Msg.h.

Definition at line 641 of file Log_Msg.h.

pid_t ACE_Log_Msg::pid_ = -2 [static, private]

Process id of the current process.

Definition at line 691 of file Log_Msg.h.

u_long ACE_Log_Msg::priority_mask_ [private]

Keeps track of all the per-thread ACE_Log_Priority values that are currently enabled. Default is for all logging priorities to be disabled.

Definition at line 668 of file Log_Msg.h.

u_long ACE_Log_Msg::process_priority_mask_ [static, private]
Initial value:

Keeps track of all the per-process ACE_Log_Priority values that are currently enabled. Default is for all logging priorities to be enabled.

Default per-process priority mask By default, all priorities are enabled.

Definition at line 682 of file Log_Msg.h.

const ACE_TCHAR * ACE_Log_Msg::program_name_ = 0 [static, private]

Records the program name.

Definition at line 685 of file Log_Msg.h.

bool ACE_Log_Msg::restart_ [private]

Indicates whether we should restart system calls that are interrupted.

Definition at line 629 of file Log_Msg.h.

int ACE_Log_Msg::status_ [private]

Status of operation (-1 means failure, >= 0 means success).

Definition at line 611 of file Log_Msg.h.

If we're running in the context of an ACE_Thread_Manager this will point to the thread descriptor adapter which holds the thread descriptor of the thread. This can be used to repidly access all thread data kept in ACE_Thread_Descriptor.

Definition at line 661 of file Log_Msg.h.

int ACE_Log_Msg::timestamp_ [private]

Always timestamp?

Definition at line 671 of file Log_Msg.h.

Are we already within an ACE_Trace constructor call?

Definition at line 650 of file Log_Msg.h.

Depth of the nesting for printing traces.

Definition at line 647 of file Log_Msg.h.

Are we allowing tracing in this thread?

Definition at line 653 of file Log_Msg.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines