1 // We need this to get the status of ACE_NTRACE...
2 #include "ace/config-all.h"
4 // Turn off tracing for the duration of this file.
5 #if defined (ACE_NTRACE)
7 #endif /* ACE_NTRACE */
11 #include "ace/Thread_Manager.h"
12 #include "ace/Guard_T.h"
13 #include "ace/OS_NS_stdio.h"
14 #include "ace/OS_NS_errno.h"
15 #include "ace/OS_NS_sys_time.h"
16 #include "ace/OS_NS_string.h"
17 #include "ace/OS_NS_wchar.h"
18 #include "ace/OS_NS_signal.h"
19 #include "ace/os_include/os_typeinfo.h"
21 #if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE != 0)
22 # include "ace/Object_Manager.h"
23 #endif /* ! ACE_MT_SAFE */
25 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
26 // FUZZ: disable check_for_streams_include
27 # include "ace/streams.h"
28 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
30 #if defined (ACE_HAS_TRACE)
31 # include "ace/Trace.h"
32 #endif /* ACE_HAS_TRACE */
34 #include "ace/Log_Msg.h"
35 #include "ace/Log_Msg_Callback.h"
36 #include "ace/Log_Msg_IPC.h"
37 #include "ace/Log_Msg_NT_Event_Log.h"
38 #include "ace/Log_Msg_UNIX_Syslog.h"
39 #include "ace/Log_Record.h"
40 #include "ace/Recursive_Thread_Mutex.h"
41 #include "ace/Stack_Trace.h"
42 #include "ace/Atomic_Op.h"
46 #if !defined (__ACE_INLINE__)
47 #include "ace/Log_Msg.inl"
48 #endif /* __ACE_INLINE__ */
51 # include "ace/Log_Msg_Android_Logcat.h"
54 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
56 ACE_ALLOC_HOOK_DEFINE(ACE_Log_Msg
)
58 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
59 bool ACE_Log_Msg::key_created_
= 0;
60 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
61 defined (ACE_HAS_TSS_EMULATION)
63 static ACE_thread_key_t the_log_msg_tss_key
;
65 ACE_thread_key_t
*log_msg_tss_key ()
67 return &the_log_msg_tss_key
;
70 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
72 static ACE_Cleanup_Adapter
<ACE_Log_Msg
>* log_msg_cleanup
= 0;
73 class ACE_Msg_Log_Cleanup
: public ACE_Cleanup_Adapter
<ACE_Log_Msg
>
76 virtual ~ACE_Msg_Log_Cleanup () {
77 if (this == log_msg_cleanup
)
81 #endif /* ACE_MT_SAFE */
83 #if defined (ACE_WIN32)
84 # define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_NT_Event_Log
85 #elif defined (ACE_ANDROID)
86 # define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_Android_Logcat
87 #elif !defined (ACE_LACKS_UNIX_SYSLOG)
88 # define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_UNIX_Syslog
91 // When doing ACE_OS::s[n]printf() calls in log(), we need to update
92 // the space remaining in the output buffer based on what's returned from
93 // the output function. If we could rely on more modern compilers, this
94 // would be in an unnamed namespace, but it's a macro instead.
95 // count is a size_t, len is an int and assumed to be non-negative.
96 #define ACE_UPDATE_COUNT(COUNT, LEN) \
97 do { if (static_cast<size_t> (LEN) > COUNT) COUNT = 0; \
98 else COUNT -= static_cast<size_t> (LEN); \
101 /// Instance count for Log_Msg - used to know when dynamically
102 /// allocated storage (program name and host name) can be safely
104 int ACE_Log_Msg::instance_count_
= 0;
107 * @class ACE_Log_Msg_Manager
109 * @brief Synchronize output operations.
111 * Provides global point of contact for all ACE_Log_Msg instances
114 * For internal use by ACE, only!
116 class ACE_Log_Msg_Manager
119 static ACE_Log_Msg_Backend
*log_backend_
;
120 static ACE_Log_Msg_Backend
*custom_backend_
;
122 static u_long log_backend_flags_
;
124 static int init_backend (const u_long
*flags
= 0);
126 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
127 //FUZZ: disable check_for_lack_ACE_OS
128 static void close () ACE_GCC_DESTRUCTOR_ATTRIBUTE
;
129 //FUZZ: enable check_for_lack_ACE_OS
131 static ACE_Recursive_Thread_Mutex
*get_lock ();
134 static ACE_Recursive_Thread_Mutex
*lock_
;
135 #endif /* ! ACE_MT_SAFE */
138 ACE_Log_Msg_Backend
*ACE_Log_Msg_Manager::log_backend_
= 0;
139 ACE_Log_Msg_Backend
*ACE_Log_Msg_Manager::custom_backend_
= 0;
141 #ifndef ACE_DEFAULT_LOG_BACKEND_FLAGS
143 # define ACE_DEFAULT_LOG_BACKEND_FLAGS ACE_Log_Msg::SYSLOG
145 # define ACE_DEFAULT_LOG_BACKEND_FLAGS 0
149 u_long
ACE_Log_Msg_Manager::log_backend_flags_
= ACE_DEFAULT_LOG_BACKEND_FLAGS
;
151 int ACE_Log_Msg_Manager::init_backend (const u_long
*flags
)
153 // If flags have been supplied, and they are different from the flags
154 // we had last time, then we may have to re-create the backend as a
158 // Sanity check for custom backend.
159 if (ACE_BIT_ENABLED (*flags
, ACE_Log_Msg::CUSTOM
) &&
160 ACE_Log_Msg_Manager::custom_backend_
== 0)
165 if ((ACE_BIT_ENABLED (*flags
, ACE_Log_Msg::SYSLOG
)
166 && ACE_BIT_DISABLED (ACE_Log_Msg_Manager::log_backend_flags_
, ACE_Log_Msg::SYSLOG
))
167 || (ACE_BIT_DISABLED (*flags
, ACE_Log_Msg::SYSLOG
)
168 && ACE_BIT_ENABLED (ACE_Log_Msg_Manager::log_backend_flags_
, ACE_Log_Msg::SYSLOG
)))
170 delete ACE_Log_Msg_Manager::log_backend_
;
171 ACE_Log_Msg_Manager::log_backend_
= 0;
174 ACE_Log_Msg_Manager::log_backend_flags_
= *flags
;
177 if (ACE_Log_Msg_Manager::log_backend_
== 0)
179 #ifdef ACE_LOG_MSG_SYSLOG_BACKEND
180 // Allocate the ACE_Log_Msg_Backend instance.
181 if (ACE_BIT_ENABLED (ACE_Log_Msg_Manager::log_backend_flags_
, ACE_Log_Msg::SYSLOG
))
182 ACE_NEW_RETURN (ACE_Log_Msg_Manager::log_backend_
,
183 ACE_LOG_MSG_SYSLOG_BACKEND
,
187 ACE_NEW_RETURN (ACE_Log_Msg_Manager::log_backend_
,
195 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
196 ACE_Recursive_Thread_Mutex
*ACE_Log_Msg_Manager::lock_
= 0;
198 ACE_Recursive_Thread_Mutex
*
199 ACE_Log_Msg_Manager::get_lock ()
201 // This function is called by the first thread to create an ACE_Log_Msg
202 // instance. It makes the call while holding a mutex, so we don't have
203 // to grab another one here.
204 if (ACE_Log_Msg_Manager::lock_
== 0)
206 ACE_NEW_RETURN (ACE_Log_Msg_Manager::lock_
,
207 ACE_Recursive_Thread_Mutex
,
211 if (init_backend () == -1)
214 return ACE_Log_Msg_Manager::lock_
;
218 ACE_Log_Msg_Manager::close ()
220 // Ugly, ugly, but don't know a better way.
221 delete ACE_Log_Msg_Manager::lock_
;
222 ACE_Log_Msg_Manager::lock_
= 0;
224 delete ACE_Log_Msg_Manager::log_backend_
;
225 ACE_Log_Msg_Manager::log_backend_
= 0;
227 // we are never responsible for custom backend
228 ACE_Log_Msg_Manager::custom_backend_
= 0;
231 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
232 defined (ACE_HAS_TSS_EMULATION)
234 # if defined (ACE_HAS_THR_C_DEST)
235 # define LOCAL_EXTERN_PREFIX extern "C"
237 # define LOCAL_EXTERN_PREFIX
238 # endif /* ACE_HAS_THR_C_DEST */
241 ACE_TSS_CLEANUP_NAME (void *ptr
)
245 // Delegate to thr_desc if this not has terminated
246 ACE_Log_Msg
*log_msg
= (ACE_Log_Msg
*) ptr
;
247 if (log_msg
->thr_desc () != 0)
248 log_msg
->thr_desc ()->log_msg_cleanup (log_msg
);
253 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
254 #endif /* ! ACE_MT_SAFE */
258 ACE_Log_Msg::exists ()
260 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
261 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
262 defined (ACE_HAS_TSS_EMULATION)
263 void *tss_log_msg
= 0; // The actual type is ACE_Log_Msg*, but we need this
264 // void to keep G++ from complaining.
266 // Get the tss_log_msg from thread-specific storage.
267 return ACE_Log_Msg::key_created_
268 && ACE_Thread::getspecific (*(log_msg_tss_key ()), &tss_log_msg
) != -1
271 # error "Platform must support thread-specific storage if threads are used."
272 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
273 #else /* ! ACE_MT_SAFE */
275 #endif /* ! ACE_MT_SAFE */
279 ACE_Log_Msg::instance ()
281 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
282 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
283 defined (ACE_HAS_TSS_EMULATION)
284 // TSS Singleton implementation.
286 if (!ACE_Log_Msg::key_created_
)
288 ACE_thread_mutex_t
*lock
=
289 reinterpret_cast<ACE_thread_mutex_t
*> (
290 ACE_OS_Object_Manager::preallocated_object
291 [ACE_OS_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK
]);
293 if (1 == ACE_OS_Object_Manager::starting_up())
294 //This function is called before ACE_OS_Object_Manager is
295 //initialized. So the lock might not be valid. Assume it's
296 //single threaded and so don't need the lock.
299 ACE_OS::thread_mutex_lock (lock
);
301 if (!ACE_Log_Msg::key_created_
)
303 // Allocate the Singleton lock.
304 ACE_Log_Msg_Manager::get_lock ();
306 if (ACE_Thread::keycreate (log_msg_tss_key (),
307 &ACE_TSS_CLEANUP_NAME
) != 0)
309 if (1 == ACE_OS_Object_Manager::starting_up())
310 //This function is called before ACE_OS_Object_Manager is
311 //initialized. So the lock might not be valid. Assume it's
312 //single threaded and so don't need the lock.
315 ACE_OS::thread_mutex_unlock (lock
);
316 return 0; // Major problems, this should *never* happen!
319 ACE_Log_Msg::key_created_
= true;
322 if (1 == ACE_OS_Object_Manager::starting_up())
323 //This function is called before ACE_OS_Object_Manager is
324 //initialized. So the lock might not be valid. Assume it's
325 //single threaded and so don't need the lock.
328 ACE_OS::thread_mutex_unlock (lock
);
331 ACE_Log_Msg
*tss_log_msg
= 0;
334 // Get the tss_log_msg from thread-specific storage.
335 if (ACE_Thread::getspecific (*(log_msg_tss_key ()), &temp
) == -1)
336 return 0; // This should not happen!
338 tss_log_msg
= static_cast <ACE_Log_Msg
*> (temp
);
340 // Check to see if this is the first time in for this thread.
341 if (tss_log_msg
== 0)
343 // Allocate memory off the heap and store it in a pointer in
344 // thread-specific storage (on the stack...). The memory will
345 // always be freed by the thread rundown because of the TSS
346 // callback set up when the key was created.
347 ACE_NEW_RETURN (tss_log_msg
,
350 // Store the dynamically allocated pointer in thread-specific
351 // storage. It gets deleted via the ACE_TSS_cleanup function
352 // when the thread terminates.
354 if (ACE_Thread::setspecific (*(log_msg_tss_key()),
355 reinterpret_cast<void *> (tss_log_msg
))
357 return 0; // Major problems, this should *never* happen!
362 # error "Platform must support thread-specific storage if threads are used."
363 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
364 #else /* ! ACE_MT_SAFE */
365 // We don't have threads, we cannot call
366 // ACE_Log_Msg_Manager::get_lock () to initialize the logger
367 // callback, so instead we do it here.
368 if (ACE_Log_Msg_Manager::init_backend () == -1)
371 // Singleton implementation.
373 if (log_msg_cleanup
== 0)
375 ACE_NEW_RETURN (log_msg_cleanup
, ACE_Msg_Log_Cleanup
, 0);
376 // Register the instance for destruction at program termination.
377 ACE_Object_Manager::at_exit (log_msg_cleanup
,
379 typeid (*log_msg_cleanup
).name ());
382 return &log_msg_cleanup
->object ();
383 #endif /* ! ACE_MT_SAFE */
386 // Not inlined to help prevent having to include OS.h just to
387 // get ACELIB_DEBUG, et al, macros.
389 ACE_Log_Msg::last_error_adapter ()
391 return ACE_OS::last_error ();
394 // Sets the flag in the default priority mask used to initialize
395 // ACE_Log_Msg instances, as well as the current per-thread instance.
398 ACE_Log_Msg::enable_debug_messages (ACE_Log_Priority priority
)
400 ACE_SET_BITS (ACE_Log_Msg::default_priority_mask_
, priority
);
401 ACE_Log_Msg
*i
= ACE_Log_Msg::instance ();
402 i
->priority_mask (i
->priority_mask () | priority
);
405 // Clears the flag in the default priority mask used to initialize
406 // ACE_Log_Msg instances, as well as the current per-thread instance.
409 ACE_Log_Msg::disable_debug_messages (ACE_Log_Priority priority
)
411 ACE_CLR_BITS (ACE_Log_Msg::default_priority_mask_
, priority
);
412 ACE_Log_Msg
*i
= ACE_Log_Msg::instance ();
413 i
->priority_mask (i
->priority_mask () & ~priority
);
417 ACE_Log_Msg::program_name ()
419 return ACE_Log_Msg::program_name_
;
422 /// Name of the local host.
423 const ACE_TCHAR
*ACE_Log_Msg::local_host_
= 0;
425 /// Records the program name.
426 const ACE_TCHAR
*ACE_Log_Msg::program_name_
= 0;
428 /// Default is to use stderr.
429 u_long
ACE_Log_Msg::flags_
= ACE_DEFAULT_LOG_FLAGS
;
431 /// Current offset of msg_[].
432 ptrdiff_t ACE_Log_Msg::msg_off_
= 0;
434 /// Default per-thread priority mask
435 /// By default, no priorities are enabled.
436 u_long
ACE_Log_Msg::default_priority_mask_
= 0;
438 /// Default per-process priority mask
439 /// By default, all priorities are enabled.
440 u_long
ACE_Log_Msg::process_priority_mask_
= LM_SHUTDOWN
453 ACE_Log_Msg::close ()
455 // This call needs to go here to avoid memory leaks.
456 ACE_MT (ACE_Log_Msg_Manager::close ());
458 // Please note that this will be called by a statement that is
459 // harded coded into the ACE_Object_Manager's shutdown sequence, in
462 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && \
463 (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
464 defined (ACE_HAS_TSS_EMULATION))
466 if (ACE_Log_Msg::key_created_
)
468 ACE_thread_mutex_t
*lock
=
469 reinterpret_cast<ACE_thread_mutex_t
*>
470 (ACE_OS_Object_Manager::preallocated_object
471 [ACE_OS_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK
]);
473 ACE_OS::thread_mutex_lock (lock
);
475 if (ACE_Log_Msg::key_created_
)
477 // Clean up this ACE_Log_Msg instance and reset the TSS to
478 // prevent any future cleanup attempts via TSS mechanisms at
479 // thread exit. Otherwise in the event of a dynamic library
480 // unload of libACE, by a program not linked with libACE,
481 // ACE_TSS_cleanup will be invoked after libACE has been unloaded.
482 // See Bugzilla 2980 for lots of details.
485 // Get the tss_log_msg from thread-specific storage.
486 if (ACE_Thread::getspecific (*(log_msg_tss_key ()), &temp
) != -1
489 ACE_Log_Msg
*tss_log_msg
= static_cast <ACE_Log_Msg
*> (temp
);
490 // we haven't been cleaned up
491 ACE_TSS_CLEANUP_NAME(tss_log_msg
);
492 if (ACE_Thread::setspecific(*(log_msg_tss_key()),
493 reinterpret_cast <void *>(0)) != 0)
494 ACE_OS::printf ("ACE_Log_Msg::close failed to ACE_Thread::setspecific to 0\n");
497 // The key is not needed any longer; ACE_Log_Msg is closing
498 // and will need to be reopened if this process wishes to use
499 // logging again. So delete the key.
500 ACE_Thread::keyfree (*(log_msg_tss_key()));
501 ACE_Log_Msg::key_created_
= false;
505 ACE_OS::thread_mutex_unlock (lock
);
507 #endif /* (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION) && ACE_MT_SAFE */
511 ACE_Log_Msg::sync_hook (const ACE_TCHAR
*prg_name
)
513 ACE_LOG_MSG
->sync (prg_name
);
516 ACE_OS_Thread_Descriptor
*
517 ACE_Log_Msg::thr_desc_hook ()
519 return ACE_LOG_MSG
->thr_desc ();
522 // Call after a fork to resynchronize the PID and PROGRAM_NAME
525 ACE_Log_Msg::sync (const ACE_TCHAR
*prog_name
)
527 ACE_TRACE ("ACE_Log_Msg::sync");
531 // Must free if already allocated!!!
532 #if defined (ACE_HAS_ALLOC_HOOKS)
533 ACE_Allocator::instance()->free ((void *) ACE_Log_Msg::program_name_
);
535 ACE_OS::free ((void *) ACE_Log_Msg::program_name_
);
536 #endif /* ACE_HAS_ALLOC_HOOKS */
538 ACE_Log_Msg::program_name_
= ACE_OS::strdup (prog_name
);
541 ACE_Log_Msg::msg_off_
= 0;
545 ACE_Log_Msg::flags ()
547 ACE_TRACE ("ACE_Log_Msg::flags");
549 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
,
550 *ACE_Log_Msg_Manager::get_lock (), 0));
552 result
= ACE_Log_Msg::flags_
;
557 ACE_Log_Msg::set_flags (u_long flgs
)
559 ACE_TRACE ("ACE_Log_Msg::set_flags");
560 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex
, ace_mon
,
561 *ACE_Log_Msg_Manager::get_lock ()));
563 ACE_SET_BITS (ACE_Log_Msg::flags_
, flgs
);
567 ACE_Log_Msg::clr_flags (u_long flgs
)
569 ACE_TRACE ("ACE_Log_Msg::clr_flags");
570 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex
, ace_mon
,
571 *ACE_Log_Msg_Manager::get_lock ()));
573 ACE_CLR_BITS (ACE_Log_Msg::flags_
, flgs
);
577 ACE_Log_Msg::acquire ()
579 ACE_TRACE ("ACE_Log_Msg::acquire");
580 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
581 return ACE_Log_Msg_Manager::get_lock ()->acquire ();
582 #else /* ! ACE_MT_SAFE */
584 #endif /* ! ACE_MT_SAFE */
588 ACE_Log_Msg::priority_mask (u_long n_mask
, MASK_TYPE mask_type
)
592 if (mask_type
== THREAD
)
594 o_mask
= this->priority_mask_
;
595 this->priority_mask_
= n_mask
;
599 o_mask
= ACE_Log_Msg::process_priority_mask_
;
600 ACE_Log_Msg::process_priority_mask_
= n_mask
;
607 ACE_Log_Msg::release ()
609 ACE_TRACE ("ACE_Log_Msg::release");
611 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
612 return ACE_Log_Msg_Manager::get_lock ()->release ();
613 #else /* ! ACE_MT_SAFE */
615 #endif /* ! ACE_MT_SAFE */
618 ACE_Log_Msg::ACE_Log_Msg ()
623 restart_ (1), // Restart by default...
625 ostream_refcount_ (0),
628 trace_active_ (false),
629 tracing_enabled_ (true), // On by default?
631 priority_mask_ (default_priority_mask_
),
634 // ACE_TRACE ("ACE_Log_Msg::ACE_Log_Msg");
636 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex
, ace_mon
,
637 *ACE_Log_Msg_Manager::get_lock ()));
640 if (this->instance_count_
== 1)
641 ACE_Base_Thread_Adapter::set_log_msg_hooks (ACE_Log_Msg::init_hook
,
642 ACE_Log_Msg::inherit_hook
,
644 ACE_Log_Msg::sync_hook
,
645 ACE_Log_Msg::thr_desc_hook
);
647 this->conditional_values_
.is_set_
= false;
649 char *timestamp
= ACE_OS::getenv ("ACE_LOG_TIMESTAMP");
652 // If variable is set or is set to date tag so we print date and time.
653 if (ACE_OS::strcmp (timestamp
, "TIME") == 0)
655 this->timestamp_
= 1;
657 else if (ACE_OS::strcmp (timestamp
, "DATE") == 0)
659 this->timestamp_
= 2;
663 #if defined (ACE_HAS_ALLOC_HOOKS)
664 ACE_ALLOCATOR_NORETURN (this->msg_
, static_cast<ACE_TCHAR
*>(ACE_Allocator::instance()->malloc(sizeof(ACE_TCHAR
) * (ACE_MAXLOGMSGLEN
+1))));
666 ACE_NEW_NORETURN (this->msg_
, ACE_TCHAR
[ACE_MAXLOGMSGLEN
+1]);
667 #endif /* ACE_HAS_ALLOC_HOOKS */
670 ACE_Log_Msg::~ACE_Log_Msg ()
672 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
674 int instance_count
= 0;
676 // Only hold the guard while updating the instance_count_.
677 // If ACE_Log_Msg_Manager::close () is called, the lock will
680 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex
, ace_mon
,
681 *ACE_Log_Msg_Manager::get_lock ()));
682 instance_count
= --instance_count_
;
684 // Release the guard.
686 #else /* ! ACE_MT_SAFE */
687 int instance_count
= --instance_count_
;
688 #endif /* ! ACE_MT_SAFE */
690 // If this is the last instance then cleanup. Only the last
691 // thread to destroy its ACE_Log_Msg instance should execute
693 if (instance_count
== 0)
695 // Destroy the message queue instance.
696 if (ACE_Log_Msg_Manager::log_backend_
!= 0)
697 ACE_Log_Msg_Manager::log_backend_
->close ();
699 // Close down custom backend
700 if (ACE_Log_Msg_Manager::custom_backend_
!= 0)
701 ACE_Log_Msg_Manager::custom_backend_
->close ();
703 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
704 # if defined (ACE_HAS_TSS_EMULATION)
705 ACE_Log_Msg_Manager::close ();
706 # endif /* ACE_HAS_TSS_EMULATION */
707 # endif /* ACE_MT_SAFE */
709 if (ACE_Log_Msg::program_name_
)
711 #if defined (ACE_HAS_ALLOC_HOOKS)
712 ACE_Allocator::instance()->free ((void *) ACE_Log_Msg::program_name_
);
714 ACE_OS::free ((void *) ACE_Log_Msg::program_name_
);
715 #endif /* ACE_HAS_ALLOC_HOOKS */
716 ACE_Log_Msg::program_name_
= 0;
719 if (ACE_Log_Msg::local_host_
)
721 #if defined (ACE_HAS_ALLOC_HOOKS)
722 ACE_Allocator::instance()->free ((void *) ACE_Log_Msg::local_host_
);
724 ACE_OS::free ((void *) ACE_Log_Msg::local_host_
);
725 #endif /* ACE_HAS_ALLOC_HOOKS */
726 ACE_Log_Msg::local_host_
= 0;
730 this->cleanup_ostream ();
732 #if defined (ACE_HAS_ALLOC_HOOKS)
733 ACE_Allocator::instance()->free(this->msg_
);
736 #endif /* ACE_HAS_ALLOC_HOOKS */
740 ACE_Log_Msg::cleanup_ostream ()
742 if (this->ostream_refcount_
)
744 if (--*this->ostream_refcount_
== 0)
746 #if defined (ACE_HAS_ALLOC_HOOKS)
747 this->ostream_refcount_
->~Atomic_ULong();
748 ACE_Allocator::instance()->free(this->ostream_refcount_
);
750 delete this->ostream_refcount_
;
751 #endif /* ACE_HAS_ALLOC_HOOKS */
752 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
753 ACE_OS::fclose (this->ostream_
);
755 delete this->ostream_
;
759 this->ostream_refcount_
= 0;
763 // Open the sender-side of the message queue.
765 ACE_Log_Msg::open (const ACE_TCHAR
*prog_name
,
767 const ACE_TCHAR
*logger_key
)
769 ACE_TRACE ("ACE_Log_Msg::open");
770 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
,
771 *ACE_Log_Msg_Manager::get_lock (), -1));
775 #if defined(ACE_HAS_ALLOC_HOOKS)
776 ACE_Allocator::instance()->free ((void *) ACE_Log_Msg::program_name_
);
778 ACE_OS::free ((void *) ACE_Log_Msg::program_name_
);
779 #endif /* ACE_HAS_ALLOC_HOOKS */
781 ACE_ALLOCATOR_RETURN (ACE_Log_Msg::program_name_
,
782 ACE_OS::strdup (prog_name
),
785 else if (ACE_Log_Msg::program_name_
== 0)
787 ACE_ALLOCATOR_RETURN (ACE_Log_Msg::program_name_
,
788 ACE_OS::strdup (ACE_TEXT ("<unknown>")),
794 // Be sure that there is a message_queue_, with multiple threads.
795 ACE_MT (ACE_Log_Msg_Manager::init_backend (&flags
));
797 // Always close the current handle before doing anything else.
798 if (ACE_Log_Msg_Manager::log_backend_
!= 0)
799 ACE_Log_Msg_Manager::log_backend_
->reset ();
801 if (ACE_Log_Msg_Manager::custom_backend_
!= 0)
802 ACE_Log_Msg_Manager::custom_backend_
->reset ();
804 // Note that if we fail to open the message queue the default action
805 // is to use stderr (set via static initialization in the
806 // Log_Msg.cpp file).
808 if (ACE_BIT_ENABLED (flags
, ACE_Log_Msg::LOGGER
)
809 || ACE_BIT_ENABLED (flags
, ACE_Log_Msg::SYSLOG
))
811 // The SYSLOG backends (both NT and UNIX) can get along fine
812 // without the logger_key - they will default to prog_name if
814 if (logger_key
== 0 && ACE_BIT_ENABLED (flags
, ACE_Log_Msg::LOGGER
))
817 status
= ACE_Log_Msg_Manager::log_backend_
->open (logger_key
);
820 ACE_SET_BITS (ACE_Log_Msg::flags_
, ACE_Log_Msg::STDERR
);
823 if (ACE_BIT_ENABLED (flags
, ACE_Log_Msg::LOGGER
))
824 ACE_SET_BITS (ACE_Log_Msg::flags_
, ACE_Log_Msg::LOGGER
);
825 if (ACE_BIT_ENABLED (flags
, ACE_Log_Msg::SYSLOG
))
826 ACE_SET_BITS (ACE_Log_Msg::flags_
, ACE_Log_Msg::SYSLOG
);
829 else if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_
, ACE_Log_Msg::LOGGER
)
830 || ACE_BIT_ENABLED (ACE_Log_Msg::flags_
, ACE_Log_Msg::SYSLOG
))
832 // If we are closing down logger, redirect logging to stderr.
833 ACE_CLR_BITS (ACE_Log_Msg::flags_
, ACE_Log_Msg::LOGGER
);
834 ACE_CLR_BITS (ACE_Log_Msg::flags_
, ACE_Log_Msg::SYSLOG
);
835 ACE_SET_BITS (ACE_Log_Msg::flags_
, ACE_Log_Msg::STDERR
);
838 if (ACE_BIT_ENABLED (flags
, ACE_Log_Msg::CUSTOM
))
841 ACE_Log_Msg_Manager::custom_backend_
->open (logger_key
);
844 ACE_SET_BITS (ACE_Log_Msg::flags_
, ACE_Log_Msg::CUSTOM
);
847 // Remember, ACE_Log_Msg::STDERR bit is on by default...
849 && ACE_BIT_ENABLED (flags
,
850 ACE_Log_Msg::STDERR
) == 0)
851 ACE_CLR_BITS (ACE_Log_Msg::flags_
,
852 ACE_Log_Msg::STDERR
);
854 // VERBOSE takes precedence over VERBOSE_LITE...
855 if (ACE_BIT_ENABLED (flags
,
856 ACE_Log_Msg::VERBOSE_LITE
))
857 ACE_SET_BITS (ACE_Log_Msg::flags_
,
858 ACE_Log_Msg::VERBOSE_LITE
);
859 else if (ACE_BIT_ENABLED (flags
,
860 ACE_Log_Msg::VERBOSE
))
861 ACE_SET_BITS (ACE_Log_Msg::flags_
,
862 ACE_Log_Msg::VERBOSE
);
864 if (ACE_BIT_ENABLED (flags
,
865 ACE_Log_Msg::OSTREAM
))
867 ACE_SET_BITS (ACE_Log_Msg::flags_
,
868 ACE_Log_Msg::OSTREAM
);
869 // Only set this to cerr if it hasn't already been set.
870 if (this->msg_ostream () == 0)
871 this->msg_ostream (ACE_DEFAULT_LOG_STREAM
);
874 if (ACE_BIT_ENABLED (flags
,
875 ACE_Log_Msg::MSG_CALLBACK
))
876 ACE_SET_BITS (ACE_Log_Msg::flags_
,
877 ACE_Log_Msg::MSG_CALLBACK
);
879 if (ACE_BIT_ENABLED (flags
,
880 ACE_Log_Msg::SILENT
))
881 ACE_SET_BITS (ACE_Log_Msg::flags_
,
882 ACE_Log_Msg::SILENT
);
887 #ifndef ACE_LACKS_VA_FUNCTIONS
889 * Valid Options (prefixed by '%', as in printf format strings) include:
890 * 'A': print an ACE_timer_t value
891 * 'a': exit the program at this point (var-argument is the exit status!)
892 * 'b': print a ssize_t value
893 * 'B': print a size_t value
894 * 'c': print a character
895 * 'C': print a character string
896 * 'i', 'd': print a decimal number
897 * 'I', indent according to nesting depth
898 * 'e', 'E', 'f', 'F', 'g', 'G': print a double
899 * 'l', print line number where an error occurred.
900 * 'M': print the name of the priority of the message.
901 * 'm': Return the message corresponding to errno value, e.g., as done by <strerror>
902 * 'N': print file name where the error occurred.
903 * 'n': print the name of the program (or "<unknown>" if not set)
904 * 'o': print as an octal number
905 * 'P': format the current process id
906 * 'p': format the appropriate errno message from sys_errlist, e.g., as done by <perror>
907 * 'Q': print out the uint64 number
908 * 'q': print out the int64 number
909 * '@': print a void* pointer (in hexadecimal)
910 * 'r': call the function pointed to by the corresponding argument
911 * 'R': print return status
912 * 'S': print out the appropriate signal message corresponding
913 * to var-argument, e.g., as done by strsignal()
914 * 's': format a character string
915 * 'T': print timestamp in hour:minute:sec:usec format.
916 * 'D': print timestamp in month/day/year hour:minute:sec:usec format.
917 * 't': print thread id (1 if single-threaded)
918 * 'u': print as unsigned int
919 * 'x': print as a hex number
920 * 'X': print as a hex number
921 * 'w': print a wide character
922 * 'W': print out a wide character string.
923 * 'z': print an ACE_OS::WChar character
924 * 'Z': print an ACE_OS::WChar character string
925 * ':': print a time_t value as an integral number
926 * '%': format a single percent sign, '%'
929 ACE_Log_Msg::log (ACE_Log_Priority log_priority
,
930 const ACE_TCHAR
*format_str
, ...)
932 ACE_TRACE ("ACE_Log_Msg::log");
933 // Start of variable args section.
936 va_start (argp
, format_str
);
938 ssize_t
const result
= this->log (format_str
,
946 #if defined (ACE_HAS_WCHAR)
948 * Since this is the ANTI_TCHAR version, we need to convert
949 * the format string over.
952 ACE_Log_Msg::log (ACE_Log_Priority log_priority
,
953 const ACE_ANTI_TCHAR
*format_str
, ...)
955 ACE_TRACE ("ACE_Log_Msg::log");
957 // Start of variable args section.
960 va_start (argp
, format_str
);
962 ssize_t
const result
= this->log (ACE_TEXT_ANTI_TO_TCHAR (format_str
),
969 #endif /* ACE_HAS_WCHAR */
971 #endif /* ACE_LACKS_VA_FUNCTIONS */
973 #if defined ACE_HAS_STRERROR_R && defined ACE_LACKS_STRERROR
974 #define ACE_LOG_MSG_USE_STRERROR_R
978 ACE_Log_Msg::log (const ACE_TCHAR
*format_str
,
979 ACE_Log_Priority log_priority
,
981 ACE_Log_Category_TSS
* category
)
983 ACE_TRACE ("ACE_Log_Msg::log");
984 #if defined (ACE_LACKS_VA_FUNCTIONS)
985 ACE_UNUSED_ARG (log_priority
);
986 ACE_UNUSED_ARG (format_str
);
987 ACE_UNUSED_ARG (argp
);
988 ACE_UNUSED_ARG (category
);
989 ACE_NOTSUP_RETURN (-1);
993 using PointerToFunction
= void (*)(...);
995 // Check if there were any conditional values set.
996 bool const conditional_values
= this->conditional_values_
.is_set_
;
998 // Reset conditional values.
999 this->conditional_values_
.is_set_
= false;
1001 // Only print the message if <priority_mask_> hasn't been reset to
1002 // exclude this logging priority.
1003 if (this->log_priority_enabled (log_priority
) == 0)
1006 // If conditional values were set and the log priority is correct,
1007 // then the values are actually set.
1008 if (conditional_values
)
1009 this->set (this->conditional_values_
.file_
,
1010 this->conditional_values_
.line_
,
1011 this->conditional_values_
.op_status_
,
1012 this->conditional_values_
.errnum_
,
1014 this->msg_ostream (),
1015 this->msg_callback ());
1017 // Logging is supposed to be a benign activity (i.e., not interfer
1018 // with normal application operations), so don't inadvertently smash
1020 ACE_Errno_Guard
guard (errno
);
1022 ACE_Log_Record
log_record (log_priority
,
1023 ACE_OS::gettimeofday (),
1026 log_record
.category(category
);
1028 // bp is pointer to where to put next part of logged message.
1029 // bspace is the number of characters remaining in msg_.
1030 ACE_TCHAR
*bp
= const_cast<ACE_TCHAR
*> (this->msg ());
1031 size_t bspace
= ACE_MAXLOGMSGLEN
; // Leave room for Nul term.
1032 if (this->msg_off_
<= ACE_Log_Record::MAXLOGMSGLEN
)
1033 bspace
-= static_cast<size_t> (this->msg_off_
);
1035 // If this platform has snprintf() capability to prevent overrunning the
1036 // output buffer, use it. To avoid adding a maintenance-hassle compile-
1037 // time couple between here and OS.cpp, don't try to figure this out at
1038 // compile time. Instead, do a quick check now; if we get a -1 return,
1039 // the platform doesn't support the length-limiting capability.
1041 bool can_check
= ACE_OS::snprintf (test
, 1, ACE_TEXT ("x")) != -1;
1043 bool abort_prog
= false;
1046 // Retrieve the flags in a local variable on the stack, it is
1047 // accessed by multiple threads and within this operation we
1048 // check it several times, so this way we only lock once
1049 u_long flags
= this->flags ();
1051 if (ACE_BIT_ENABLED (flags
, ACE_Log_Msg::VERBOSE
))
1053 // Prepend the program name onto this message
1054 if (ACE_Log_Msg::program_name_
!= 0)
1056 for (const ACE_TCHAR
*s
= ACE_Log_Msg::program_name_
;
1057 bspace
> 1 && (*bp
= *s
) != '\0';
1068 ACE_TCHAR day_and_time
[27];
1069 const ACE_TCHAR
*s
= 0;
1070 if (timestamp_
== 1)
1072 // Print just the time
1073 s
= ACE::timestamp (day_and_time
,
1074 sizeof (day_and_time
) / sizeof (ACE_TCHAR
),
1079 // Print time and date
1080 ACE::timestamp (day_and_time
,
1081 sizeof (day_and_time
) / sizeof (ACE_TCHAR
));
1085 for (; bspace
> 1 && (*bp
= *s
) != '\0'; ++s
, --bspace
)
1092 while (*format_str
!= '\0' && bspace
> 0)
1094 // Copy input to output until we encounter a %, however a
1095 // % followed by another % is not a format specification.
1097 if (*format_str
!= '%')
1099 *bp
++ = *format_str
++;
1102 else if (format_str
[1] == '%') // An "escaped" '%' (just print one '%').
1104 *bp
++ = *format_str
++; // Store first %
1105 ++format_str
; // but skip second %
1110 // This is most likely a format specification that ends with
1111 // one of the valid options described previously. To enable full
1112 // use of all sprintf capabilities, save the format specifier
1113 // from the '%' up to the format letter in a new char array.
1114 // This allows the full sprintf capability for padding, field
1115 // widths, alignment, etc. Any width/precision requiring a
1116 // caller-supplied argument is extracted and placed as text
1117 // into the format array. Lastly, we convert the caller-supplied
1118 // format specifier from the ACE_Log_Msg-supported list to the
1119 // equivalent sprintf specifier, and run the new format spec
1120 // through sprintf, adding it to the bp string.
1122 const ACE_TCHAR
*abort_str
= ACE_TEXT ("Aborting...");
1123 const ACE_TCHAR
*start_format
= format_str
;
1124 size_t fspace
= 128;
1125 ACE_TCHAR format
[128]; // Converted format string
1126 ACE_OS::memset (format
, '\0', 128); // Set this string to known values.
1127 ACE_TCHAR
*fp
= 0; // Current format pointer
1128 int wp
= 0; // Width/precision extracted from args
1130 bool skip_nul_locate
= false;
1131 int this_len
= 0; // How many chars s[n]printf wrote
1133 #ifdef ACE_LOG_MSG_USE_STRERROR_R
1134 char strerror_buf
[128]; // always narrow chars
1135 ACE_OS::strcpy (strerror_buf
, "strerror_r failed");
1139 *fp
++ = *format_str
++; // Copy in the %
1142 // Initialization to satisfy VC6
1144 // Work through the format string to copy in the format
1145 // from the caller. While it's going across, extract ints
1146 // for '*' width/precision values from the argument list.
1147 // When the real format specifier is located, change it to
1148 // one recognized by sprintf, if needed, and do the sprintf
1153 done
= true; // Unless a conversion spec changes it
1155 switch (*format_str
)
1157 // The initial set of cases are the conversion
1158 // specifiers. Copy them in to the format array.
1159 // Note we don't use 'l', a normal conversion spec,
1160 // as a conversion because it is a ACE_Log_Msg format
1178 *fp
++ = *format_str
;
1188 wp
= va_arg (argp
, int);
1190 this_len
= ACE_OS::snprintf (fp
, fspace
,
1191 ACE_TEXT ("%d"), wp
);
1193 this_len
= ACE_OS::sprintf (fp
, ACE_TEXT ("%d"), wp
);
1194 ACE_UPDATE_COUNT (fspace
, this_len
);
1195 fp
+= ACE_OS::strlen (fp
);
1199 case 'A': // ACE_timer_t
1201 ACE_OS::strcpy (fp
, ACE_TEXT ("f"));
1203 double const value
= va_arg (argp
, double);
1205 this_len
= ACE_OS::snprintf (bp
, bspace
, format
, value
);
1207 this_len
= ACE_OS::sprintf (bp
, format
, value
);
1208 ACE_UPDATE_COUNT (bspace
, this_len
);
1212 case 'a': // Abort program after handling all of format string.
1214 exit_value
= va_arg (argp
, int);
1215 ACE_OS::strsncpy (bp
, abort_str
, bspace
);
1216 if (bspace
> ACE_OS::strlen (abort_str
))
1217 bspace
-= ACE_OS::strlen (abort_str
);
1222 case 'l': // Source file line number
1223 ACE_OS::strcpy (fp
, ACE_TEXT ("d"));
1225 this_len
= ACE_OS::snprintf (bp
,
1230 this_len
= ACE_OS::sprintf (bp
, format
, this->linenum ());
1231 ACE_UPDATE_COUNT (bspace
, this_len
);
1234 case 'N': // Source file name
1235 ACE_OS::strcpy (fp
, ACE_TEXT_PRIs
);
1237 this_len
= ACE_OS::snprintf (bp
, bspace
, format
,
1239 ACE_TEXT_CHAR_TO_TCHAR (this->file ())
1240 : ACE_TEXT ("<unknown file>"));
1242 this_len
= ACE_OS::sprintf (bp
, format
,
1244 ACE_TEXT_CHAR_TO_TCHAR (this->file ())
1245 : ACE_TEXT ("<unknown file>"));
1246 ACE_UPDATE_COUNT (bspace
, this_len
);
1249 case 'n': // Program name
1250 ACE_OS::strcpy (fp
, ACE_TEXT_PRIs
);
1252 this_len
= ACE_OS::snprintf (bp
, bspace
, format
,
1253 ACE_Log_Msg::program_name_
?
1254 ACE_Log_Msg::program_name_
:
1255 ACE_TEXT ("<unknown>"));
1257 this_len
= ACE_OS::sprintf (bp
, format
,
1258 ACE_Log_Msg::program_name_
?
1259 ACE_Log_Msg::program_name_
:
1260 ACE_TEXT ("<unknown>"));
1261 ACE_UPDATE_COUNT (bspace
, this_len
);
1264 case 'P': // Process ID
1265 ACE_OS::strcpy (fp
, ACE_TEXT ("d"));
1267 this_len
= ACE_OS::snprintf
1268 (bp
, bspace
, format
,
1269 static_cast<int> (this->getpid ()));
1271 this_len
= ACE_OS::sprintf
1272 (bp
, format
, static_cast<int> (this->getpid ()));
1273 ACE_UPDATE_COUNT (bspace
, this_len
);
1276 case 'p': // <errno> string, ala perror()
1279 const int mapped
= ACE::map_errno (this->errnum ());
1280 #ifdef ACE_LOG_MSG_USE_STRERROR_R
1281 char *msg
= ACE_OS::strerror_r (mapped
, strerror_buf
,
1282 sizeof strerror_buf
);
1284 char *msg
= ACE_OS::strerror (mapped
);
1286 // Windows can try to translate the errnum using
1287 // system calls if strerror() doesn't get anything useful.
1288 #if defined (ACE_WIN32)
1293 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
1294 ACE_OS::strcpy (fp
, ACE_TEXT ("ls: %ls"));
1295 wchar_t *str
= va_arg (argp
, wchar_t *);
1297 ACE_OS::strcpy (fp
, ACE_TEXT ("s: %s"));
1298 ACE_TCHAR
*str
= va_arg (argp
, ACE_TCHAR
*);
1301 this_len
= ACE_OS::snprintf
1302 (bp
, bspace
, format
,
1303 str
? str
: ACE_TEXT ("(null)"),
1304 ACE_TEXT_CHAR_TO_TCHAR (msg
));
1306 this_len
= ACE_OS::sprintf
1308 str
? str
: ACE_TEXT ("(null)"),
1309 ACE_TEXT_CHAR_TO_TCHAR (msg
));
1310 #if defined (ACE_WIN32)
1314 errno
= ACE::map_errno (this->errnum ());
1315 ACE_TCHAR
*lpMsgBuf
= 0;
1316 ACE_TEXT_FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
1317 | FORMAT_MESSAGE_MAX_WIDTH_MASK
1318 | FORMAT_MESSAGE_FROM_SYSTEM
,
1321 MAKELANGID (LANG_NEUTRAL
,
1324 (ACE_TCHAR
*) &lpMsgBuf
,
1328 // If we don't get a valid response from
1329 // <FormatMessage>, we'll assume this is a
1330 // WinSock error and so we'll try to convert
1331 // it into a string. If this doesn't work it
1332 // returns "unknown error" which is fine for
1334 ACE_TCHAR
*str
= va_arg (argp
, ACE_TCHAR
*);
1337 const ACE_TCHAR
*message
=
1338 ACE::sock_error (errno
);
1339 ACE_OS::strcpy (fp
, ACE_TEXT ("s: %s"));
1341 this_len
= ACE_OS::snprintf
1342 (bp
, bspace
, format
,
1343 str
? str
: ACE_TEXT ("(null)"),
1346 this_len
= ACE_OS::sprintf
1348 str
? str
: ACE_TEXT ("(null)"),
1353 ACE_OS::strcpy (fp
, ACE_TEXT ("s: %s"));
1355 this_len
= ACE_OS::snprintf
1356 (bp
, bspace
, format
,
1357 str
? str
: ACE_TEXT ("(null)"),
1360 this_len
= ACE_OS::sprintf
1362 str
? str
: ACE_TEXT ("(null)"),
1365 ::LocalFree (lpMsgBuf
);
1368 #endif /* ACE_WIN32 */
1369 ACE_UPDATE_COUNT (bspace
, this_len
);
1373 case 'M': // Print the name of the priority of the message.
1375 // Look at the format precision specifier. .1 is interpreted
1376 // as a single character printout, otherwise we print the name of
1379 // So, did we find a .1 specifier? Do we need to override it?
1380 if (format
[1] == ACE_TEXT('.') &&
1381 format
[2] == ACE_TEXT('1'))
1384 // Print a single character signifying the severity of the message
1388 # if defined (ACE_USES_WCHAR)
1390 # if defined (ACE_WIN32) // Windows uses 'c' for a wide character
1391 ACE_OS::strcpy (fp
, ACE_TEXT ("c"));
1392 # else // Other platforms behave differently
1393 ACE_OS::strcpy (fp
, ACE_TEXT ("lc"));
1396 # else /* ACE_USES_WCHAR */
1398 // Non-unicode builds simply use a standard character format specifier
1399 ACE_OS::strcpy (fp
, ACE_TEXT ("c"));
1401 # endif /* ACE_USES_WCHAR */
1403 // Below is an optimized (binary search based)
1404 // version of the following simple piece of code:
1406 // log_priority == LM_SHUTDOWN ? 'S' : // Shutdown
1407 // log_priority == LM_TRACE ? 'T' : // Trace
1408 // log_priority == LM_DEBUG ? 'D' : // Debug
1409 // log_priority == LM_INFO ? 'I' : // Info
1410 // log_priority == LM_NOTICE ? 'N' : // Notice
1411 // log_priority == LM_WARNING ? 'W' : // Warning
1412 // log_priority == LM_STARTUP ? 'U' : // Startup
1413 // log_priority == LM_ERROR ? 'E' : // Error
1414 // log_priority == LM_CRITICAL ? 'C' : // Critical
1415 // log_priority == LM_ALERT ? 'A' : // Alert
1416 // log_priority == LM_EMERGENCY ? '!' : // Emergency
1421 this_len
= ACE_OS::snprintf
1422 (bp
, bspace
, format
,
1423 #if !defined (ACE_USES_WCHAR) || defined (ACE_WIN32)
1428 (log_priority
<= LM_WARNING
) ?
1429 (log_priority
<= LM_DEBUG
) ?
1430 (log_priority
<= LM_TRACE
) ?
1431 (log_priority
== LM_SHUTDOWN
) ?
1432 ACE_TEXT('S') : ACE_TEXT('T') : ACE_TEXT('D') :
1433 (log_priority
<= LM_NOTICE
) ?
1434 (log_priority
== LM_INFO
) ?
1435 ACE_TEXT('I') : ACE_TEXT('N') : ACE_TEXT('W') :
1436 (log_priority
<= LM_CRITICAL
) ?
1437 (log_priority
<= LM_ERROR
) ?
1438 (log_priority
== LM_STARTUP
) ?
1439 ACE_TEXT('U') : ACE_TEXT('E') : ACE_TEXT('C') :
1440 (log_priority
<= LM_EMERGENCY
) ?
1441 (log_priority
== LM_ALERT
) ?
1442 ACE_TEXT('A') : ACE_TEXT('!') : ACE_TEXT('?'));
1446 this_len
= ACE_OS::sprintf
1448 #if !defined (ACE_USES_WCHAR) || defined (ACE_WIN32)
1453 (log_priority
<= LM_WARNING
) ?
1454 (log_priority
<= LM_DEBUG
) ?
1455 (log_priority
<= LM_TRACE
) ?
1456 (log_priority
== LM_SHUTDOWN
) ?
1457 ACE_TEXT('S') : ACE_TEXT('T') : ACE_TEXT('D') :
1458 (log_priority
<= LM_NOTICE
) ?
1459 (log_priority
== LM_INFO
) ?
1460 ACE_TEXT('I') : ACE_TEXT('N') : ACE_TEXT('W') :
1461 (log_priority
<= LM_CRITICAL
) ?
1462 (log_priority
<= LM_ERROR
) ?
1463 (log_priority
== LM_STARTUP
) ?
1464 ACE_TEXT('U') : ACE_TEXT('E') : ACE_TEXT('C') :
1465 (log_priority
<= LM_EMERGENCY
) ?
1466 (log_priority
== LM_ALERT
) ?
1467 ACE_TEXT('A') : ACE_TEXT('!') : ACE_TEXT('?'));
1470 ACE_UPDATE_COUNT (bspace
, this_len
);
1474 // Nope, print out standard priority_name() string
1476 ACE_OS::strcpy (fp
, ACE_TEXT_PRIs
);
1478 this_len
= ACE_OS::snprintf
1479 (bp
, bspace
, format
,
1480 ACE_Log_Record::priority_name (log_priority
));
1482 this_len
= ACE_OS::sprintf
1484 ACE_Log_Record::priority_name (log_priority
));
1485 ACE_UPDATE_COUNT (bspace
, this_len
);
1489 case 'm': // Format the string assocated with the errno value.
1492 const int mapped
= ACE::map_errno (this->errnum ());
1493 #ifdef ACE_LOG_MSG_USE_STRERROR_R
1494 char *msg
= ACE_OS::strerror_r (mapped
, strerror_buf
,
1495 sizeof strerror_buf
);
1497 char *msg
= ACE_OS::strerror (mapped
);
1499 // Windows can try to translate the errnum using
1500 // system calls if strerror() doesn't get anything useful.
1501 #if defined (ACE_WIN32)
1506 ACE_OS::strcpy (fp
, ACE_TEXT_PRIs
);
1508 this_len
= ACE_OS::snprintf
1509 (bp
, bspace
, format
, ACE_TEXT_CHAR_TO_TCHAR (msg
));
1511 this_len
= ACE_OS::sprintf
1512 (bp
, format
, ACE_TEXT_CHAR_TO_TCHAR (msg
));
1513 #if defined (ACE_WIN32)
1517 errno
= ACE::map_errno (this->errnum ());
1518 ACE_TCHAR
*lpMsgBuf
= 0;
1519 ACE_TEXT_FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
1520 | FORMAT_MESSAGE_MAX_WIDTH_MASK
1521 | FORMAT_MESSAGE_FROM_SYSTEM
,
1524 MAKELANGID (LANG_NEUTRAL
,
1527 (ACE_TCHAR
*) &lpMsgBuf
,
1531 // If we don't get a valid response from
1532 // <FormatMessage>, we'll assume this is a
1533 // WinSock error and so we'll try to convert
1534 // it into a string. If this doesn't work it
1535 // returns "unknown error" which is fine for
1539 const ACE_TCHAR
*message
=
1540 ACE::sock_error (errno
);
1541 ACE_OS::strcpy (fp
, ACE_TEXT ("s"));
1543 this_len
= ACE_OS::snprintf
1544 (bp
, bspace
, format
, message
);
1546 this_len
= ACE_OS::sprintf (bp
, format
, message
);
1550 ACE_OS::strcpy (fp
, ACE_TEXT ("s"));
1552 this_len
= ACE_OS::snprintf
1553 (bp
, bspace
, format
, lpMsgBuf
);
1555 this_len
= ACE_OS::sprintf
1556 (bp
, format
, lpMsgBuf
);
1558 ::LocalFree (lpMsgBuf
);
1561 #endif /* ACE_WIN32 */
1562 ACE_UPDATE_COUNT (bspace
, this_len
);
1566 case 'R': // Format the return status of the operation.
1567 this->op_status (va_arg (argp
, int));
1568 ACE_OS::strcpy (fp
, ACE_TEXT ("d"));
1570 this_len
= ACE_OS::snprintf
1571 (bp
, bspace
, format
, this->op_status ());
1573 this_len
= ACE_OS::sprintf
1574 (bp
, format
, this->op_status ());
1575 ACE_UPDATE_COUNT (bspace
, this_len
);
1578 case '{': // Increment the trace_depth, then indent
1579 skip_nul_locate
= true;
1580 (void) this->inc ();
1583 case '}': // indent, then decrement trace_depth
1584 skip_nul_locate
= true;
1585 (void) this->dec ();
1588 case '$': // insert a newline, then indent the next line
1594 case 'I': // Indent with nesting_depth*width spaces
1595 // Caller can do %*I to override nesting indent, and
1596 // if %*I was done, wp has the extracted width.
1597 #if defined (ACE_HAS_TRACE)
1599 wp
= ACE_Trace::get_nesting_indent ();
1603 #endif /* ACE_HAS_TRACE */
1604 wp
*= this->trace_depth_
;
1605 if (static_cast<size_t> (wp
) > bspace
)
1606 wp
= static_cast<int> (bspace
);
1607 for (tmp_indent
= wp
;
1613 bspace
-= static_cast<size_t> (wp
);
1614 skip_nul_locate
= true;
1617 case 'r': // Run (invoke) this subroutine.
1619 ptrdiff_t const osave
= ACE_Log_Msg::msg_off_
;
1621 if (ACE_BIT_ENABLED (flags
,
1622 ACE_Log_Msg::SILENT
) &&
1628 ACE_Log_Msg::msg_off_
= bp
- this->msg_
;
1630 (*va_arg (argp
, PointerToFunction
))();
1632 if (ACE_BIT_ENABLED (flags
,
1633 ACE_Log_Msg::SILENT
) &&
1634 bspace
> (1 + ACE_OS::strlen (bp
)))
1636 bspace
-= (ACE_OS::strlen (bp
) + 1);
1637 bp
+= ACE_OS::strlen (bp
);
1641 skip_nul_locate
= true;
1642 ACE_Log_Msg::msg_off_
= osave
;
1646 case 'S': // format the string for with this signal number.
1648 const int sig
= va_arg (argp
, int);
1649 ACE_OS::strcpy (fp
, ACE_TEXT ("s"));
1651 this_len
= ACE_OS::snprintf
1652 (bp
, bspace
, format
, ACE_OS::strsignal(sig
));
1654 this_len
= ACE_OS::sprintf
1655 (bp
, format
, ACE_OS::strsignal(sig
));
1656 ACE_UPDATE_COUNT (bspace
, this_len
);
1660 case 'D': // Format the timestamp in format:
1661 // yyyy-mm-dd hour:minute:sec.usec
1662 // This is a maximum of 27 characters
1663 // including terminator.
1665 ACE_TCHAR day_and_time
[27];
1666 // Did we find the flag indicating a time value argument
1667 if (format
[1] == ACE_TEXT('#'))
1669 ACE_Time_Value
* time_value
= va_arg (argp
, ACE_Time_Value
*);
1670 ACE::timestamp (*time_value
,
1672 sizeof (day_and_time
) / sizeof (ACE_TCHAR
),
1677 ACE::timestamp (day_and_time
,
1678 sizeof (day_and_time
) / sizeof (ACE_TCHAR
),
1681 ACE_OS::strcpy (fp
, ACE_TEXT_PRIs
);
1683 this_len
= ACE_OS::snprintf
1684 (bp
, bspace
, format
, day_and_time
);
1686 this_len
= ACE_OS::sprintf (bp
, format
, day_and_time
);
1687 ACE_UPDATE_COUNT (bspace
, this_len
);
1691 case 'T': // Format the timestamp in
1692 // hour:minute:sec.usec format.
1694 ACE_TCHAR day_and_time
[27];
1695 ACE_OS::strcpy (fp
, ACE_TEXT_PRIs
);
1696 // Did we find the flag indicating a time value argument
1697 if (format
[1] == ACE_TEXT('#'))
1699 ACE_Time_Value
* time_value
= va_arg (argp
, ACE_Time_Value
*);
1701 this_len
= ACE_OS::snprintf
1702 (bp
, bspace
, format
,
1703 ACE::timestamp (*time_value
,
1705 sizeof day_and_time
/ sizeof (ACE_TCHAR
),
1708 this_len
= ACE_OS::sprintf
1709 (bp
, format
, ACE::timestamp (*time_value
,
1711 sizeof day_and_time
/ sizeof (ACE_TCHAR
),
1717 this_len
= ACE_OS::snprintf
1718 (bp
, bspace
, format
,
1719 ACE::timestamp (day_and_time
, sizeof day_and_time
/ sizeof (ACE_TCHAR
), true));
1721 this_len
= ACE_OS::sprintf
1722 (bp
, format
, ACE::timestamp (day_and_time
,
1723 sizeof day_and_time
/ sizeof (ACE_TCHAR
), true));
1725 ACE_UPDATE_COUNT (bspace
, this_len
);
1729 case 't': // Format thread id.
1730 #if defined (ACE_WIN32)
1731 ACE_OS::strcpy (fp
, ACE_TEXT ("u"));
1733 this_len
= ACE_OS::snprintf
1734 (bp
, bspace
, format
,
1735 static_cast<unsigned> (ACE_Thread::self ()));
1738 ACE_OS::sprintf (bp
,
1740 static_cast <unsigned> (ACE_Thread::self ()));
1743 # ifdef ACE_HAS_GETTID
1744 # define ACE_LOG_MSG_GET_THREAD_ID ACE_OS::thr_gettid
1745 # define ACE_LOG_MSG_GET_THREAD_ID_BUFFER_SIZE 12
1747 # define ACE_LOG_MSG_GET_THREAD_ID ACE_OS::thr_id
1748 # define ACE_LOG_MSG_GET_THREAD_ID_BUFFER_SIZE 32
1751 # if defined ACE_USES_WCHAR
1753 char tid_buf
[ACE_LOG_MSG_GET_THREAD_ID_BUFFER_SIZE
] = {};
1754 ACE_LOG_MSG_GET_THREAD_ID (tid_buf
, sizeof tid_buf
);
1755 this_len
= ACE_OS::strlen (tid_buf
);
1756 ACE_OS::strncpy (bp
, ACE_TEXT_CHAR_TO_TCHAR (tid_buf
),
1760 this_len
= ACE_LOG_MSG_GET_THREAD_ID (bp
, bspace
);
1761 # endif /* ACE_USES_WCHAR */
1762 #endif /* ACE_WIN32 */
1763 ACE_UPDATE_COUNT (bspace
, this_len
);
1768 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
1769 wchar_t *str
= va_arg (argp
, wchar_t *);
1770 #else /* ACE_WIN32 && ACE_USES_WCHAR */
1771 ACE_TCHAR
*str
= va_arg (argp
, ACE_TCHAR
*);
1772 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
1773 ACE_OS::strcpy (fp
, ACE_TEXT_PRIs
);
1775 this_len
= ACE_OS::snprintf
1776 (bp
, bspace
, format
, str
? str
: ACE_TEXT ("(null)"));
1778 this_len
= ACE_OS::sprintf
1779 (bp
, format
, str
? str
: ACE_TEXT ("(null)"));
1780 ACE_UPDATE_COUNT (bspace
, this_len
);
1784 case 'C': // Narrow-char string
1786 char *cstr
= va_arg (argp
, char *);
1787 #if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
1788 ACE_OS::strcpy (fp
, ACE_TEXT ("S"));
1789 #else /* ACE_WIN32 && ACE_USES_WCHAR */
1790 ACE_OS::strcpy (fp
, ACE_TEXT ("s"));
1791 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
1793 this_len
= ACE_OS::snprintf
1794 (bp
, bspace
, format
, cstr
? cstr
: "(null)");
1796 this_len
= ACE_OS::sprintf
1797 (bp
, format
, cstr
? cstr
: "(null)");
1798 ACE_UPDATE_COUNT (bspace
, this_len
);
1804 #if defined (ACE_HAS_WCHAR)
1805 wchar_t *wchar_str
= va_arg (argp
, wchar_t *);
1806 # if defined (ACE_WIN32)
1807 # if defined (ACE_USES_WCHAR)
1808 ACE_OS::strcpy (fp
, ACE_TEXT ("s"));
1809 # else /* ACE_USES_WCHAR */
1810 ACE_OS::strcpy (fp
, ACE_TEXT ("S"));
1811 # endif /* ACE_USES_WCHAR */
1813 ACE_OS::strcpy (fp
, ACE_TEXT ("ls"));
1814 # endif /* ACE_HAS_WCHAR */
1816 this_len
= ACE_OS::snprintf
1817 (bp
, bspace
, format
, wchar_str
? wchar_str
: ACE_TEXT_WIDE("(null)"));
1819 this_len
= ACE_OS::sprintf
1820 (bp
, format
, wchar_str
? wchar_str
: ACE_TEXT_WIDE("(null)"));
1821 #endif /* ACE_HAS_WCHAR */
1822 ACE_UPDATE_COUNT (bspace
, this_len
);
1826 case 'w': // Wide character
1827 #if defined (ACE_WIN32)
1828 # if defined (ACE_USES_WCHAR)
1829 ACE_OS::strcpy (fp
, ACE_TEXT ("c"));
1830 # else /* ACE_USES_WCHAR */
1831 ACE_OS::strcpy (fp
, ACE_TEXT ("C"));
1832 # endif /* ACE_USES_WCHAR */
1834 this_len
= ACE_OS::snprintf
1835 (bp
, bspace
, format
, va_arg (argp
, int));
1837 this_len
= ACE_OS::sprintf
1838 (bp
, format
, va_arg (argp
, int));
1839 #elif defined (ACE_USES_WCHAR)
1840 ACE_OS::strcpy (fp
, ACE_TEXT ("lc"));
1842 this_len
= ACE_OS::snprintf
1843 (bp
, bspace
, format
, va_arg (argp
, wint_t));
1845 this_len
= ACE_OS::sprintf
1846 (bp
, format
, va_arg (argp
, wint_t));
1847 #else /* ACE_WIN32 */
1848 ACE_OS::strcpy (fp
, ACE_TEXT ("u"));
1850 this_len
= ACE_OS::snprintf
1851 (bp
, bspace
, format
, va_arg (argp
, int));
1853 this_len
= ACE_OS::sprintf
1854 (bp
, format
, va_arg (argp
, int));
1855 #endif /* ACE_WIN32 */
1856 ACE_UPDATE_COUNT (bspace
, this_len
);
1859 case 'z': // ACE_OS::WChar character
1861 // On some platforms sizeof (wchar_t) can be 2
1862 // on the others 4 ...
1864 static_cast<wchar_t> (va_arg (argp
, int));
1865 #if defined (ACE_WIN32)
1866 # if defined (ACE_USES_WCHAR)
1867 ACE_OS::strcpy (fp
, ACE_TEXT ("c"));
1868 # else /* ACE_USES_WCHAR */
1869 ACE_OS::strcpy (fp
, ACE_TEXT ("C"));
1870 # endif /* ACE_USES_WCHAR */
1871 #elif defined (ACE_USES_WCHAR)
1872 ACE_OS::strcpy (fp
, ACE_TEXT ("lc"));
1873 #else /* ACE_WIN32 */
1874 ACE_OS::strcpy (fp
, ACE_TEXT ("u"));
1875 #endif /* ACE_WIN32 */
1877 this_len
= ACE_OS::snprintf (bp
, bspace
, format
, wtchar
);
1879 this_len
= ACE_OS::sprintf (bp
, format
, wtchar
);
1880 ACE_UPDATE_COUNT (bspace
, this_len
);
1884 case 'Z': // ACE_OS::WChar character string
1886 ACE_OS::WChar
*wchar_str
= va_arg (argp
, ACE_OS::WChar
*);
1890 wchar_t *wchar_t_str
= 0;
1891 if (sizeof (ACE_OS::WChar
) != sizeof (wchar_t))
1893 size_t len
= ACE_OS::wslen (wchar_str
) + 1;
1894 ACE_NEW_NORETURN(wchar_t_str
, wchar_t[len
]);
1895 if (wchar_t_str
== 0)
1898 for (size_t i
= 0; i
< len
; ++i
)
1900 wchar_t_str
[i
] = wchar_str
[i
];
1904 if (wchar_t_str
== 0)
1906 wchar_t_str
= reinterpret_cast<wchar_t*> (wchar_str
);
1908 #if defined (ACE_WIN32)
1909 # if defined (ACE_USES_WCHAR)
1910 ACE_OS::strcpy (fp
, ACE_TEXT ("s"));
1911 # else /* ACE_USES_WCHAR */
1912 ACE_OS::strcpy (fp
, ACE_TEXT ("S"));
1913 # endif /* ACE_USES_WCHAR */
1914 #elif defined (ACE_HAS_WCHAR)
1915 ACE_OS::strcpy (fp
, ACE_TEXT ("ls"));
1916 #endif /* ACE_WIN32 / ACE_HAS_WCHAR */
1918 this_len
= ACE_OS::snprintf
1919 (bp
, bspace
, format
, wchar_t_str
);
1921 this_len
= ACE_OS::sprintf (bp
, format
, wchar_t_str
);
1922 if(sizeof(ACE_OS::WChar
) != sizeof(wchar_t))
1924 delete [] wchar_t_str
;
1926 ACE_UPDATE_COUNT (bspace
, this_len
);
1931 #if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
1932 ACE_OS::strcpy (fp
, ACE_TEXT ("C"));
1934 ACE_OS::strcpy (fp
, ACE_TEXT ("c"));
1935 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
1937 this_len
= ACE_OS::snprintf
1938 (bp
, bspace
, format
, va_arg (argp
, int));
1940 this_len
= ACE_OS::sprintf
1941 (bp
, format
, va_arg (argp
, int));
1942 ACE_UPDATE_COUNT (bspace
, this_len
);
1945 case 'd': case 'i': case 'o':
1946 case 'u': case 'x': case 'X':
1947 fp
[0] = *format_str
;
1950 this_len
= ACE_OS::snprintf
1951 (bp
, bspace
, format
, va_arg (argp
, int));
1953 this_len
= ACE_OS::sprintf
1954 (bp
, format
, va_arg (argp
, int));
1955 ACE_UPDATE_COUNT (bspace
, this_len
);
1958 case 'F': case 'f': case 'e': case 'E':
1960 fp
[0] = *format_str
;
1963 this_len
= ACE_OS::snprintf
1964 (bp
, bspace
, format
, va_arg (argp
, double));
1966 this_len
= ACE_OS::sprintf
1967 (bp
, format
, va_arg (argp
, double));
1968 ACE_UPDATE_COUNT (bspace
, this_len
);
1973 const ACE_TCHAR
*fmt
= ACE_UINT64_FORMAT_SPECIFIER
;
1974 ACE_OS::strcpy (fp
, &fmt
[1]); // Skip leading %
1976 this_len
= ACE_OS::snprintf (bp
, bspace
,
1978 va_arg (argp
, ACE_UINT64
));
1980 this_len
= ACE_OS::sprintf (bp
,
1982 va_arg (argp
, ACE_UINT64
));
1984 ACE_UPDATE_COUNT (bspace
, this_len
);
1989 const ACE_TCHAR
*fmt
= ACE_INT64_FORMAT_SPECIFIER
;
1990 ACE_OS::strcpy (fp
, &fmt
[1]); // Skip leading %
1992 this_len
= ACE_OS::snprintf (bp
, bspace
,
1994 va_arg (argp
, ACE_INT64
));
1996 this_len
= ACE_OS::sprintf (bp
,
1998 va_arg (argp
, ACE_INT64
));
2000 ACE_UPDATE_COUNT (bspace
, this_len
);
2005 const ACE_TCHAR
*fmt
= ACE_SSIZE_T_FORMAT_SPECIFIER
;
2006 ACE_OS::strcpy (fp
, &fmt
[1]); // Skip leading %
2009 this_len
= ACE_OS::snprintf (bp
, bspace
,
2011 va_arg (argp
, ssize_t
));
2013 this_len
= ACE_OS::sprintf (bp
,
2015 va_arg (argp
, ssize_t
));
2016 ACE_UPDATE_COUNT (bspace
, this_len
);
2021 const ACE_TCHAR
*fmt
= ACE_SIZE_T_FORMAT_SPECIFIER
;
2022 ACE_OS::strcpy (fp
, &fmt
[1]); // Skip leading %
2025 this_len
= ACE_OS::snprintf (bp
, bspace
,
2027 va_arg (argp
, size_t));
2029 this_len
= ACE_OS::sprintf (bp
,
2031 va_arg (argp
, size_t));
2032 ACE_UPDATE_COUNT (bspace
, this_len
);
2037 // Assume a 32 bit time_t and change if needed.
2038 const ACE_TCHAR
*fmt
= ACE_TEXT ("%d");
2039 if (sizeof (time_t) == 8)
2040 fmt
= ACE_INT64_FORMAT_SPECIFIER
;
2042 ACE_OS::strcpy (fp
, &fmt
[1]); // Skip leading %
2045 this_len
= ACE_OS::snprintf (bp
, bspace
,
2047 va_arg (argp
, time_t));
2049 this_len
= ACE_OS::sprintf (bp
,
2051 va_arg (argp
, time_t));
2052 ACE_UPDATE_COUNT (bspace
, this_len
);
2056 ACE_OS::strcpy (fp
, ACE_TEXT ("p"));
2058 this_len
= ACE_OS::snprintf
2059 (bp
, bspace
, format
, va_arg (argp
, void*));
2061 this_len
= ACE_OS::sprintf
2062 (bp
, format
, va_arg (argp
, void*));
2063 ACE_UPDATE_COUNT (bspace
, this_len
);
2067 // Stack trace up to this point
2069 // skip the frame that we're currently in
2070 ACE_Stack_Trace
t(2);
2071 #if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
2072 ACE_OS::strcpy (fp
, ACE_TEXT ("S"));
2073 #else /* ACE_WIN32 && ACE_USES_WCHAR */
2074 ACE_OS::strcpy (fp
, ACE_TEXT ("s"));
2075 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
2077 this_len
= ACE_OS::snprintf
2078 (bp
, bspace
, format
, t
.c_str ());
2080 this_len
= ACE_OS::sprintf
2081 (bp
, format
, t
.c_str ());
2082 ACE_UPDATE_COUNT (bspace
, this_len
);
2088 // So, it's not a legit format specifier after all...
2089 // Copy from the original % to where we are now, then
2090 // continue with whatever comes next.
2091 while (start_format
!= format_str
&& bspace
> 0)
2093 *bp
++ = *start_format
++;
2098 *bp
++ = *format_str
;
2104 // Bump to the next char in the caller's format_str
2108 if (!skip_nul_locate
)
2109 while (*bp
!= '\0') // Locate end of bp.
2114 *bp
= '\0'; // Terminate bp, but don't auto-increment this!
2118 // Check that memory was not corrupted, if it corrupted we can't log anything
2119 // anymore because all our members could be corrupted.
2120 if (bp
>= (this->msg_
+ ACE_MAXLOGMSGLEN
+1))
2123 ACE_OS::fprintf (stderr
,
2124 "The following logged message is too long!\n");
2128 // Copy the message from thread-specific storage into the transfer
2129 // buffer (this can be optimized away by changing other code...).
2130 log_record
.msg_data (this->msg ());
2132 // Write the <log_record> to the appropriate location.
2133 result
= this->log (log_record
,
2139 // Since we are now calling abort instead of exit, this value is
2141 ACE_UNUSED_ARG (exit_value
);
2143 // *Always* print a message to stderr if we're aborting. We
2144 // don't use verbose, however, to avoid recursive aborts if
2145 // something is hosed.
2146 log_record
.print (ACE_Log_Msg::local_host_
, 0, stderr
);
2151 #endif /* ACE_LACKS_VA_FUNCTIONS */
2154 #ifdef ACE_LACKS_VA_FUNCTIONS
2155 ACE_Log_Formatter
operator, (ACE_Log_Priority prio
, const char *fmt
)
2157 return ACE_Log_Formatter (prio
, fmt
);
2160 ACE_Log_Formatter::ACE_Log_Formatter (ACE_Log_Priority prio
, const char *fmt
)
2161 : saved_errno_ (errno
)
2164 , logger_ (ACE_LOG_MSG
)
2165 , abort_ (ABRT_NONE
)
2169 const bool conditional_values
= this->logger_
->conditional_values_
.is_set_
;
2170 this->logger_
->conditional_values_
.is_set_
= false;
2172 this->enabled_
= this->logger_
->log_priority_enabled (prio
);
2173 if (!this->enabled_
) return;
2175 if (conditional_values
)
2176 this->logger_
->set (this->logger_
->conditional_values_
.file_
,
2177 this->logger_
->conditional_values_
.line_
,
2178 this->logger_
->conditional_values_
.op_status_
,
2179 this->logger_
->conditional_values_
.errnum_
,
2180 this->logger_
->restart (),
2181 this->logger_
->msg_ostream (),
2182 this->logger_
->msg_callback ());
2183 this->bp_
= this->logger_
->msg_
+ ACE_Log_Msg::msg_off_
;
2184 this->bspace_
= ACE_Log_Record::MAXLOGMSGLEN
;
2185 if (ACE_Log_Msg::msg_off_
<= ACE_Log_Record::MAXLOGMSGLEN
)
2186 this->bspace_
-= static_cast<size_t> (ACE_Log_Msg::msg_off_
);
2188 if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_
, ACE_Log_Msg::VERBOSE
)
2189 && ACE_Log_Msg::program_name_
!= 0)
2191 const int n
= ACE_OS::snprintf (this->bp_
, this->bspace_
, "%s|",
2192 ACE_Log_Msg::program_name_
);
2193 ACE_UPDATE_COUNT (this->bspace_
, n
);
2197 if (this->logger_
->timestamp_
)
2199 ACE_TCHAR day_and_time
[27];
2200 const bool time_only
= this->logger_
->timestamp_
== 1;
2201 const ACE_TCHAR
*const time
=
2202 ACE::timestamp (day_and_time
,
2203 sizeof day_and_time
/ sizeof (ACE_TCHAR
),
2205 const int n
= ACE_OS::snprintf (this->bp_
, this->bspace_
, "%s|",
2206 time_only
? time
: day_and_time
);
2207 ACE_UPDATE_COUNT (this->bspace_
, n
);
2212 int ACE_Log_Formatter::copy_trunc (const char *str
, int limit
)
2214 const int n
= std::min (static_cast<int> (this->bspace_
), limit
);
2215 ACE_OS::memcpy (this->bp_
, str
, n
);
2216 ACE_UPDATE_COUNT (this->bspace_
, n
);
2221 void ACE_Log_Formatter::prepare_format ()
2223 const char in_progress
= this->in_prog_
;
2224 this->in_prog_
= ' ';
2225 switch (in_progress
)
2228 if (!this->process_conversion ()) return;
2232 // continuation of the '%p' format after the user's message
2233 const int mapped
= ACE::map_errno (this->logger_
->errnum ());
2234 #ifdef ACE_LOG_MSG_USE_STRERROR_R
2235 char strerror_buf
[128]; // always narrow chars
2236 ACE_OS::strcpy (strerror_buf
, "strerror_r failed");
2237 const char *const msg
= ACE_OS::strerror_r (mapped
, strerror_buf
,
2238 sizeof strerror_buf
);
2240 const char *const msg
= ACE_OS::strerror (mapped
);
2242 this->copy_trunc (": ", 2);
2243 this->copy_trunc (msg
, ACE_OS::strlen (msg
));
2247 if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_
, ACE_Log_Msg::SILENT
))
2249 const size_t len
= ACE_OS::strlen (this->bp_
);
2250 this->bspace_
-= len
+ 1;
2252 this->copy_trunc ("}", 1);
2255 ACE_Log_Msg::msg_off_
= this->offset_
;
2259 *this->fmt_out_
= 0;
2261 while (const char *const pct
= ACE_OS::strchr (this->format_
, '%'))
2263 const bool escaped
= pct
[1] == '%';
2264 this->format_
+= 1 + this->copy_trunc (this->format_
,
2265 pct
- this->format_
+ escaped
);
2266 if (!this->bspace_
) return;
2269 ACE_OS::strcpy (this->fmt_out_
, "%");
2270 this->fp_
= this->fmt_out_
+ 1;
2271 this->last_star_
= 0;
2272 if (!this->process_conversion ()) return;
2276 this->copy_trunc (this->format_
, ACE_OS::strlen (this->format_
));
2279 bool ACE_Log_Formatter::process_conversion ()
2281 const size_t n
= ACE_OS::strspn (this->format_
, "-+ #0123456789.Lh");
2282 const size_t fspace
= sizeof this->fmt_out_
- (this->fp_
- this->fmt_out_
);
2283 if (n
>= fspace
|| !this->format_
[n
]) return true;
2285 // when copying to fmt_out_, convert L (used by ACE) to l (used by std)
2286 for (size_t i
= 0; i
< n
; ++i
)
2287 if (this->format_
[i
] == 'L') this->fp_
[i
] = 'l';
2288 else this->fp_
[i
] = this->format_
[i
];
2292 this->in_prog_
= this->format_
[n
];
2293 const char *const format_start
= this->format_
;
2294 this->format_
+= n
+ (this->in_prog_
? 1 : 0);
2297 switch (this->in_prog_
)
2299 // the following formatters (here through '?') take no argument
2300 // from the "varags" list so they will end up returning true (keep parsing)
2302 this->copy_trunc ("\n", 1);
2305 len
= std::min (static_cast<int> (this->bspace_
),
2306 this->logger_
->trace_depth_
*
2307 (this->last_star_
? this->last_star_
:
2308 #ifdef ACE_HAS_TRACE
2309 ACE_Trace::get_nesting_indent ()));
2313 ACE_OS::memset (this->bp_
, ' ', len
);
2314 ACE_UPDATE_COUNT (this->bspace_
, len
);
2319 ACE_OS::strcpy (this->fp_
, "d");
2320 len
= ACE_OS::snprintf (this->bp_
, this->bspace_
, this->fmt_out_
,
2321 this->logger_
->linenum ());
2322 ACE_UPDATE_COUNT (this->bspace_
, len
);
2328 const int mapped
= ACE::map_errno (this->logger_
->errnum ());
2329 #ifdef ACE_LOG_MSG_USE_STRERROR_R
2330 char strerror_buf
[128]; // always narrow chars
2331 ACE_OS::strcpy (strerror_buf
, "strerror_r failed");
2332 const char *const msg
= ACE_OS::strerror_r (mapped
, strerror_buf
,
2333 sizeof strerror_buf
);
2335 const char *const msg
= ACE_OS::strerror (mapped
);
2337 ACE_OS::strcpy (this->fp_
, "s");
2338 len
= ACE_OS::snprintf (this->bp_
, this->bspace_
, this->fmt_out_
, msg
);
2339 ACE_UPDATE_COUNT (this->bspace_
, len
);
2346 const char *const pri
= ACE_Log_Record::priority_name (this->priority_
);
2348 // special case for %.1M: unique 1-char abbreviation for log priority
2349 if (this->fp_
== this->fmt_out_
+ 3 &&
2350 this->fmt_out_
[1] == '.' && this->fmt_out_
[2] == '1')
2353 this->priority_
== LM_STARTUP
? 'U' :
2354 this->priority_
== LM_EMERGENCY
? '!' :
2355 (ACE_OS::strlen (pri
) < 4) ? '?' : pri
[3];
2356 this->copy_trunc (&abbrev
, 1);
2360 ACE_OS::strcpy (this->fp_
, "s");
2361 len
= ACE_OS::snprintf (this->bp_
, this->bspace_
, this->fmt_out_
,
2363 ACE_UPDATE_COUNT (this->bspace_
, len
);
2370 ACE_OS::strcpy (this->fp_
, "s");
2371 len
= ACE_OS::snprintf (this->bp_
, this->bspace_
, this->fmt_out_
,
2372 ACE_Log_Msg::program_name_
?
2373 ACE_Log_Msg::program_name_
: "<unknown>");
2374 ACE_UPDATE_COUNT (this->bspace_
, len
);
2379 ACE_OS::strcpy (this->fp_
, "s");
2380 len
= ACE_OS::snprintf (this->bp_
, this->bspace_
, this->fmt_out_
,
2381 this->logger_
->file () ?
2382 this->logger_
->file () : "<unknown file>");
2383 ACE_UPDATE_COUNT (this->bspace_
, len
);
2388 ACE_OS::strcpy (this->fp_
, "d");
2389 len
= ACE_OS::snprintf (this->bp_
, this->bspace_
, this->fmt_out_
,
2390 static_cast<int> (this->logger_
->getpid ()));
2391 ACE_UPDATE_COUNT (this->bspace_
, len
);
2396 ACE_OS::strcpy (this->fp_
, "u");
2397 len
= ACE_OS::snprintf (this->bp_
, this->bspace_
, this->fmt_out_
,
2398 ACE_OS::thr_self ());
2399 ACE_UPDATE_COUNT (this->bspace_
, len
);
2403 // %D and %T with # in the conversion spec do take an arg (ACE_Time_Value*)
2405 ACE_OS::strcpy (this->fp_
, "s");
2406 if (ACE_OS::memchr (this->fmt_out_
, '#', this->fp_
- this->fmt_out_
))
2409 char day_and_time
[27];
2410 const char *const time
=
2411 ACE::timestamp (day_and_time
, sizeof day_and_time
, true);
2412 len
= ACE_OS::snprintf (this->bp_
, this->bspace_
, this->fmt_out_
,
2413 this->in_prog_
== 'T' ? time
: day_and_time
);
2414 ACE_UPDATE_COUNT (this->bspace_
, len
);
2420 this->logger_
->inc ();
2423 this->logger_
->dec ();
2428 ACE_Stack_Trace
trc(3); // 3 stack frames between here and user code
2429 ACE_OS::strcpy (this->fp_
, "s");
2430 len
= ACE_OS::snprintf (this->bp_
, this->bspace_
, this->fmt_out_
,
2432 ACE_UPDATE_COUNT (this->bspace_
, len
);
2438 // * requires an argument from the "varags" but doesn't complete
2439 // the current conversion specification (for example, %*s):
2442 // these require an argument from the "varags" list:
2444 this->abort_
= ABRT_NEED_ARG
;
2445 this->copy_trunc ("Aborting...", 11);
2447 case 'A': // ACE_timer_t is a typedef for double on all platforms
2448 ACE_OS::strcpy (this->fp_
, "f");
2452 ACE_OS::strcpy (this->fp_
, ACE_SSIZE_T_FORMAT_SPECIFIER
+ 1); // skip %
2455 ACE_OS::strcpy (this->fp_
, ACE_SIZE_T_FORMAT_SPECIFIER
+ 1); // skip %
2458 case 'C': case 'p': case 'S':
2459 ACE_OS::strcpy (this->fp_
, "s");
2460 // the remaining parts of case 'p' are handled in prepare_format
2464 ACE_OS::strcpy (this->fp_
, ACE_INT64_FORMAT_SPECIFIER
+ 1); // skip %
2467 ACE_OS::strcpy (this->fp_
, ACE_UINT64_FORMAT_SPECIFIER
+ 1); // skip %
2471 this->offset_
= ACE_Log_Msg::msg_off_
;
2472 if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_
, ACE_Log_Msg::SILENT
))
2473 this->copy_trunc ("{", 1);
2474 ACE_Log_Msg::msg_off_
= this->bp_
- this->logger_
->msg_
;
2478 ACE_OS::strcpy (this->fp_
, "d");
2482 ACE_OS::strcpy (this->fp_
, "u");
2485 ACE_OS::strcpy (this->fp_
, "ls");
2488 #if (defined ACE_WIN32 && !defined ACE_USES_WCHAR)
2489 ACE_OS::strcpy (this->fp_
, "S");
2490 #elif defined ACE_WIN32
2491 ACE_OS::strcpy (this->fp_
, "s");
2493 ACE_OS::strcpy (this->fp_
, "ls");
2498 ACE_OS::strcpy (this->fp_
, "p");
2501 if (sizeof (time_t) == 8)
2502 ACE_OS::strcpy (this->fp_
, ACE_INT64_FORMAT_SPECIFIER
+ 1); // skip %
2504 ACE_OS::strcpy (this->fp_
, "d");
2507 case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': // <- ints
2508 case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': // <- doubles
2509 case 'c': case 's': // <- char / const char*
2510 *this->fp_
++ = this->in_prog_
;
2515 // not actually a format specifier: copy verbatim to output
2516 this->copy_trunc (format_start
- 1 /* start at % */, n
+ 2);
2517 this->in_prog_
= ' ';
2523 void ACE_Log_Formatter::insert_pct_S (int sig
)
2525 const int n
= ACE_OS::snprintf (this->bp_
, this->bspace_
,
2526 this->fmt_out_
, ACE_OS::strsignal (sig
));
2527 ACE_UPDATE_COUNT (this->bspace_
, n
);
2531 template <typename ArgT
>
2532 void ACE_Log_Formatter::insert_arg (ArgT arg
, bool allow_star
)
2534 if (!this->enabled_
) return;
2536 this->prepare_format ();
2538 const int intArg
= static_cast<int> (arg
);
2539 switch (this->in_prog_
)
2542 this->logger_
->op_status (intArg
);
2545 this->insert_pct_S (intArg
);
2550 this->last_star_
= intArg
;
2552 ACE_OS::snprintf (this->fp_
,
2553 sizeof fmt_out_
- (this->fp_
- this->fmt_out_
),
2563 template <typename ArgT
>
2564 void ACE_Log_Formatter::insert_arg (ArgT
*arg
)
2566 if (!this->enabled_
) return;
2568 this->prepare_format ();
2573 template <typename ArgT
>
2574 void ACE_Log_Formatter::insert_arg_i (ArgT arg
)
2576 if (this->abort_
== ABRT_NEED_ARG
)
2579 this->abort_
= ABRT_AFTER_FORMAT
;
2581 else if (*this->fmt_out_
)
2583 const int n
= ACE_OS::snprintf (this->bp_
, this->bspace_
,
2584 this->fmt_out_
, arg
);
2585 ACE_UPDATE_COUNT (this->bspace_
, n
);
2590 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (int pct_adiRS
)
2592 this->insert_arg (pct_adiRS
, true);
2596 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (unsigned int pct_ouxX
)
2598 this->insert_arg (pct_ouxX
, true);
2602 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (double pct_AeEfFgG
)
2604 this->insert_arg (pct_AeEfFgG
);
2608 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (long double pct_AeEfFgG
)
2610 this->insert_arg (pct_AeEfFgG
);
2614 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (char pct_c
)
2616 this->insert_arg (pct_c
);
2620 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (const char *pct_Cps
)
2622 this->insert_arg (pct_Cps
? pct_Cps
: "(null)");
2626 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (ACE_INT64 pct_q
)
2628 this->insert_arg (pct_q
);
2632 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (ACE_UINT64 pct_Q
)
2634 this->insert_arg (pct_Q
);
2638 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (void (*pct_r
) ())
2642 this->prepare_format ();
2648 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (ACE_WCHAR_T pct_wz
)
2650 this->insert_arg (pct_wz
);
2654 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (const ACE_WCHAR_T
*pct_WZ
)
2656 this->insert_arg (pct_WZ
? pct_WZ
: (const ACE_WCHAR_T
*) L
"(null)");
2660 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (const void *pct_at
)
2662 this->insert_arg (pct_at
);
2666 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (const ACE_Time_Value
*pct_DT
)
2668 if (!this->enabled_
) return *this;
2670 this->prepare_format ();
2672 char day_and_time
[27];
2673 const char *const time
=
2674 ACE::timestamp (*pct_DT
, day_and_time
, sizeof day_and_time
, true);
2676 ACE_OS::snprintf (this->bp_
, this->bspace_
, this->fmt_out_
,
2677 this->in_prog_
== 'T' ? time
: day_and_time
);
2678 ACE_UPDATE_COUNT (this->bspace_
, len
);
2684 #if ACE_SIZEOF_LONG == 4
2685 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (long pct_Lmodifier
)
2687 this->insert_arg (pct_Lmodifier
, true);
2691 ACE_Log_Formatter
&ACE_Log_Formatter::operator, (unsigned long pct_Lmodifier
)
2693 this->insert_arg (pct_Lmodifier
, true);
2698 bool ACE_Log_Formatter::to_record (ACE_Log_Record
&record
)
2700 if (!this->enabled_
) return false;
2702 this->prepare_format ();
2703 if (this->bspace_
) *this->bp_
= 0;
2705 record
.priority (this->priority_
);
2706 record
.time_stamp (ACE_OS::gettimeofday ());
2707 record
.pid (this->logger_
->getpid ());
2708 record
.msg_data (this->logger_
->msg ());
2712 ssize_t
ACE_Log_Msg::log (const ACE_Log_Formatter
&formatter
)
2714 ACE_Log_Record record
;
2715 if (const_cast<ACE_Log_Formatter
&> (formatter
).to_record (record
))
2717 const ssize_t result
= this->log (record
, formatter
.abort ());
2718 if (formatter
.abort ())
2720 #ifndef ACE_LACKS_STDERR
2721 record
.print (local_host_
, 0, stderr
);
2725 errno
= formatter
.saved_errno ();
2731 #endif /* ACE_LACKS_VA_FUNCTIONS */
2734 #if !defined (ACE_WIN32)
2736 * @class ACE_Log_Msg_Sig_Guard
2738 * @brief For use only by ACE_Log_Msg.
2740 * Doesn't require the use of global variables or global
2741 * functions in an application).
2743 class ACE_Log_Msg_Sig_Guard
2746 ACE_Log_Msg_Sig_Guard ();
2747 ~ACE_Log_Msg_Sig_Guard ();
2749 /// Original signal mask.
2752 friend ssize_t
ACE_Log_Msg::log (ACE_Log_Record
&log_record
,
2753 int suppress_stderr
);
2756 ACE_Log_Msg_Sig_Guard::ACE_Log_Msg_Sig_Guard ()
2758 #if !defined (ACE_LACKS_UNIX_SIGNALS)
2759 ACE_OS::sigemptyset (&this->omask_
);
2761 # if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
2762 ACE_OS::sigprocmask (SIG_BLOCK
,
2763 ACE_OS_Object_Manager::default_mask (),
2766 ACE_OS::thr_sigsetmask (SIG_BLOCK
,
2767 ACE_OS_Object_Manager::default_mask (),
2769 # endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
2770 #endif /* ACE_LACKS_UNIX_SIGNALS */
2773 ACE_Log_Msg_Sig_Guard::~ACE_Log_Msg_Sig_Guard ()
2775 #if !defined (ACE_LACKS_UNIX_SIGNALS)
2776 # if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
2777 ACE_OS::sigprocmask (SIG_SETMASK
,
2781 ACE_OS::thr_sigsetmask (SIG_SETMASK
,
2784 # endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
2785 #endif /* ! ACE_LACKS_UNIX_SIGNALS */
2787 #endif /* ! ACE_WIN32 */
2790 ACE_Log_Msg::log (ACE_Log_Record
&log_record
,
2791 int suppress_stderr
)
2795 // Retrieve the flags in a local variable on the stack, it is
2796 // accessed by multiple threads and within this operation we
2797 // check it several times, so this way we only lock once
2798 u_long flags
= this->flags ();
2800 // Format the message and print it to stderr and/or ship it off to
2801 // the log_client daemon, and/or print it to the ostream. Of
2802 // course, only print the message if "SILENT" mode is disabled.
2803 if (ACE_BIT_DISABLED (flags
, ACE_Log_Msg::SILENT
))
2805 bool tracing
= this->tracing_enabled ();
2806 this->stop_tracing ();
2808 #if !defined (ACE_WIN32)
2809 // Make this block signal-safe.
2810 ACE_Log_Msg_Sig_Guard sb
;
2811 #endif /* !ACE_WIN32 */
2813 // Do the callback, if needed, before acquiring the lock
2814 // to avoid holding the lock during the callback so we don't
2815 // have deadlock if the callback uses the logger.
2816 if (ACE_BIT_ENABLED (flags
, ACE_Log_Msg::MSG_CALLBACK
)
2817 && this->msg_callback () != 0)
2819 this->msg_callback ()->log (log_record
);
2822 // Make sure that the lock is held during all this.
2823 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
,
2824 *ACE_Log_Msg_Manager::get_lock (),
2827 #if !defined ACE_LACKS_STDERR || defined ACE_FACE_DEV
2828 if (ACE_BIT_ENABLED (flags
,
2829 ACE_Log_Msg::STDERR
)
2830 && !suppress_stderr
) // This is taken care of by our caller.
2831 log_record
.print (ACE_Log_Msg::local_host_
,
2835 ACE_UNUSED_ARG (suppress_stderr
);
2838 if (ACE_BIT_ENABLED (flags
, ACE_Log_Msg::CUSTOM
) ||
2839 ACE_BIT_ENABLED (flags
, ACE_Log_Msg::SYSLOG
) ||
2840 ACE_BIT_ENABLED (flags
, ACE_Log_Msg::LOGGER
))
2842 // Be sure that there is a message_queue_, with multiple threads.
2843 ACE_MT (ACE_Log_Msg_Manager::init_backend ());
2846 if (ACE_BIT_ENABLED (flags
, ACE_Log_Msg::LOGGER
) ||
2847 ACE_BIT_ENABLED (flags
, ACE_Log_Msg::SYSLOG
))
2850 ACE_Log_Msg_Manager::log_backend_
->log (log_record
);
2853 if (ACE_BIT_ENABLED (flags
, ACE_Log_Msg::CUSTOM
) &&
2854 ACE_Log_Msg_Manager::custom_backend_
!= 0)
2857 ACE_Log_Msg_Manager::custom_backend_
->log (log_record
);
2860 // This must come last, after the other two print operations
2861 // (see the <ACE_Log_Record::print> method for details).
2862 if (ACE_BIT_ENABLED (flags
,
2863 ACE_Log_Msg::OSTREAM
)
2864 && this->msg_ostream () != 0)
2865 log_record
.print (ACE_Log_Msg::local_host_
,
2867 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
2868 static_cast<FILE *> (this->msg_ostream ())
2869 #else /* ! ACE_LACKS_IOSTREAM_TOTALLY */
2870 *this->msg_ostream ()
2871 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
2875 this->start_tracing ();
2881 // Calls log to do the actual print, but formats first.
2884 ACE_Log_Msg::log_hexdump (ACE_Log_Priority log_priority
,
2887 const ACE_TCHAR
*text
,
2888 ACE_Log_Category_TSS
* category
)
2890 // Only print the message if <priority_mask_> hasn't been reset to
2891 // exclude this logging priority.
2892 if (this->log_priority_enabled (log_priority
) == 0)
2897 text_sz
= ACE_OS::strlen (text
);
2899 size_t const total_buffer_size
=
2900 ACE_Log_Record::MAXLOGMSGLEN
- ACE_Log_Record::VERBOSE_LEN
+ text_sz
;
2902 ACE_Array
<ACE_TCHAR
> msg_buf(total_buffer_size
);
2903 if (msg_buf
.size() == 0)
2906 ACE_TCHAR
* end_ptr
= &msg_buf
[0] + total_buffer_size
;
2907 ACE_TCHAR
* wr_ptr
= &msg_buf
[0];
2908 msg_buf
[0] = 0; // in case size = 0
2911 wr_ptr
+= ACE_OS::snprintf (wr_ptr
,
2913 ACE_TEXT ("%") ACE_TEXT_PRIs
ACE_TEXT (" - "),
2916 wr_ptr
+= ACE_OS::snprintf (wr_ptr
,
2918 ACE_TEXT ("HEXDUMP ")
2919 ACE_SIZE_T_FORMAT_SPECIFIER
2920 ACE_TEXT (" bytes"),
2923 // estimate how many bytes can be output
2924 // We can fit 16 bytes output in text mode per line, 4 chars per byte;
2925 // i.e. we need 68 bytes of buffer per line.
2926 size_t hexdump_size
= (end_ptr
- wr_ptr
-58)/68*16;
2928 if (hexdump_size
< size
)
2930 wr_ptr
+= ACE_OS::snprintf (wr_ptr
,
2932 ACE_TEXT (" (showing first ")
2933 ACE_SIZE_T_FORMAT_SPECIFIER
2934 ACE_TEXT (" bytes)"),
2936 size
= hexdump_size
;
2940 ACE::format_hexdump(buffer
, size
, wr_ptr
, end_ptr
- wr_ptr
);
2942 // Now print out the formatted buffer.
2943 ACE_Log_Record
log_record (log_priority
,
2944 ACE_OS::gettimeofday (),
2947 log_record
.category(category
);
2948 log_record
.msg_data(&msg_buf
[0]);
2950 this->log (log_record
, false);
2955 ACE_Log_Msg::set (const char *file
,
2960 ACE_OSTREAM_TYPE
*os
,
2961 ACE_Log_Msg_Callback
*c
)
2963 ACE_TRACE ("ACE_Log_Msg::set");
2965 this->linenum (line
);
2966 this->op_status (op_status
);
2967 this->errnum (errnum
);
2968 this->restart (restart
);
2969 this->msg_ostream (os
);
2970 this->msg_callback (c
);
2974 ACE_Log_Msg::conditional_set (const char *filename
,
2979 this->conditional_values_
.is_set_
= true;
2980 this->conditional_values_
.file_
= filename
;
2981 this->conditional_values_
.line_
= line
;
2982 this->conditional_values_
.op_status_
= status
;
2983 this->conditional_values_
.errnum_
= err
;
2987 ACE_Log_Msg::dump () const
2989 #if defined (ACE_HAS_DUMP)
2990 ACE_TRACE ("ACE_Log_Msg::dump");
2992 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
2993 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("status_ = %d\n"), this->status_
));
2994 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nerrnum_ = %d\n"), this->errnum_
));
2995 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nlinenum_ = %d\n"), this->linenum_
));
2996 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nfile_ = %C\n"), this->file_
));
2997 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nmsg_ = %s\n"), this->msg_
));
2998 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nrestart_ = %d\n"), this->restart_
));
2999 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nostream_ = %@\n"), this->ostream_
));
3000 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nmsg_callback_ = %@\n"),
3001 this->msg_callback_
));
3002 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nprogram_name_ = %s\n"),
3003 this->program_name_
? this->program_name_
3004 : ACE_TEXT ("<unknown>")));
3005 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nlocal_host_ = %s\n"),
3006 this->local_host_
? this->local_host_
3007 : ACE_TEXT ("<unknown>")));
3008 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nflags_ = 0x%x\n"), this->flags_
));
3009 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\ntrace_depth_ = %d\n"),
3010 this->trace_depth_
));
3011 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\ntrace_active_ = %d\n"),
3012 this->trace_active_
));
3013 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\ntracing_enabled_ = %d\n"),
3014 this->tracing_enabled_
));
3015 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\npriority_mask_ = 0x%x\n"),
3016 this->priority_mask_
));
3017 if (this->thr_desc_
!= 0 && this->thr_desc_
->state () != 0)
3018 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nthr_state_ = %d\n"),
3019 this->thr_desc_
->state ()));
3020 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nmsg_off_ = %d\n"), this->msg_off_
));
3022 // Be sure that there is a message_queue_, with multiple threads.
3023 ACE_MT (ACE_Log_Msg_Manager::init_backend ());
3025 ACE_MT (ACE_Log_Msg_Manager::get_lock ()->dump ());
3026 // Synchronize output operations.
3028 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
3029 #endif /* ACE_HAS_DUMP */
3033 ACE_Log_Msg::thr_desc (ACE_Thread_Descriptor
*td
)
3035 this->thr_desc_
= td
;
3038 td
->acquire_release ();
3041 ACE_Log_Msg_Backend
*
3042 ACE_Log_Msg::msg_backend (ACE_Log_Msg_Backend
*b
)
3044 ACE_TRACE ("ACE_Log_Msg::msg_backend");
3045 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
,
3046 *ACE_Log_Msg_Manager::get_lock (), 0));
3048 ACE_Log_Msg_Backend
*tmp
= ACE_Log_Msg_Manager::custom_backend_
;
3049 ACE_Log_Msg_Manager::custom_backend_
= b
;
3053 ACE_Log_Msg_Backend
*
3054 ACE_Log_Msg::msg_backend ()
3056 ACE_TRACE ("ACE_Log_Msg::msg_backend");
3057 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
,
3058 *ACE_Log_Msg_Manager::get_lock (), 0));
3060 return ACE_Log_Msg_Manager::custom_backend_
;
3064 ACE_Log_Msg::msg_ostream (ACE_OSTREAM_TYPE
*m
, bool delete_ostream
)
3066 if (this->ostream_
== m
)
3068 // Same stream, allow user to change the delete_ostream "flag"
3069 if (delete_ostream
&& !this->ostream_refcount_
)
3071 #if defined (ACE_HAS_ALLOC_HOOKS)
3072 ACE_NEW_MALLOC (this->ostream_refcount_
, static_cast<Atomic_ULong
*>(ACE_Allocator::instance()->malloc(sizeof(Atomic_ULong
))), Atomic_ULong (1));
3074 ACE_NEW (this->ostream_refcount_
, Atomic_ULong (1));
3075 #endif /* ACE_HAS_ALLOC_HOOKS */
3077 else if (!delete_ostream
&& this->ostream_refcount_
)
3079 if (--*this->ostream_refcount_
== 0)
3081 #if defined (ACE_HAS_ALLOC_HOOKS)
3082 this->ostream_refcount_
->~Atomic_ULong();
3083 ACE_Allocator::instance()->free(this->ostream_refcount_
);
3085 delete this->ostream_refcount_
;
3086 #endif /* ACE_HAS_ALLOC_HOOKS */
3088 this->ostream_refcount_
= 0;
3090 // The other two cases are no-ops, the user has requested the same
3091 // state that's already present.
3095 this->cleanup_ostream ();
3099 #if defined (ACE_HAS_ALLOC_HOOKS)
3100 ACE_NEW_MALLOC (this->ostream_refcount_
, static_cast<Atomic_ULong
*>(ACE_Allocator::instance()->malloc(sizeof(Atomic_ULong
))), Atomic_ULong (1));
3102 ACE_NEW (this->ostream_refcount_
, Atomic_ULong (1));
3103 #endif /* ACE_HAS_ALLOC_HOOKS */
3110 ACE_Log_Msg::local_host (const ACE_TCHAR
*s
)
3114 #if defined (ACE_HAS_ALLOC_HOOKS)
3115 ACE_Allocator::instance()->free ((void *) ACE_Log_Msg::local_host_
);
3117 ACE_OS::free ((void *) ACE_Log_Msg::local_host_
);
3118 #endif /* ACE_HAS_ALLOC_HOOKS */
3120 ACE_ALLOCATOR (ACE_Log_Msg::local_host_
, ACE_OS::strdup (s
));
3124 #ifndef ACE_LACKS_VA_FUNCTIONS
3126 ACE_Log_Msg::log_priority_enabled (ACE_Log_Priority log_priority
,
3130 return this->log_priority_enabled (log_priority
);
3133 #if defined (ACE_USES_WCHAR)
3135 ACE_Log_Msg::log_priority_enabled (ACE_Log_Priority log_priority
,
3139 return this->log_priority_enabled (log_priority
);
3141 #endif /* ACE_USES_WCHAR */
3143 #endif /* ACE_LACKS_VA_FUNCTIONS */
3145 // ****************************************************************
3148 ACE_Log_Msg::init_hook (ACE_OS_Log_Msg_Attributes
&attributes
3149 # if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
3150 , ACE_SEH_EXCEPT_HANDLER selector
3151 , ACE_SEH_EXCEPT_HANDLER handler
3152 # endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
3155 # if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
3156 attributes
.seh_except_selector_
= selector
;
3157 attributes
.seh_except_handler_
= handler
;
3158 # endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
3159 if (ACE_Log_Msg::exists ())
3161 ACE_Log_Msg
*inherit_log
= ACE_LOG_MSG
;
3162 attributes
.ostream_
= inherit_log
->msg_ostream ();
3163 if (attributes
.ostream_
&& inherit_log
->ostream_refcount_
)
3165 ++*inherit_log
->ostream_refcount_
;
3166 attributes
.ostream_refcount_
= inherit_log
->ostream_refcount_
;
3170 attributes
.ostream_refcount_
= 0;
3172 attributes
.priority_mask_
= inherit_log
->priority_mask ();
3173 attributes
.tracing_enabled_
= inherit_log
->tracing_enabled ();
3174 attributes
.restart_
= inherit_log
->restart ();
3175 attributes
.trace_depth_
= inherit_log
->trace_depth ();
3180 ACE_Log_Msg::inherit_hook (ACE_OS_Thread_Descriptor
*thr_desc
,
3181 ACE_OS_Log_Msg_Attributes
&attributes
)
3183 #if !defined (ACE_THREADS_DONT_INHERIT_LOG_MSG) && \
3184 !defined (ACE_HAS_MINIMAL_ACE_OS)
3185 // Inherit the logging features if the parent thread has an
3186 // ACE_Log_Msg. Note that all of the following operations occur
3187 // within thread-specific storage.
3188 ACE_Log_Msg
*new_log
= ACE_LOG_MSG
;
3190 // Note that we do not inherit the callback because this might have
3191 // been allocated off of the stack of the original thread, in which
3192 // case all hell would break loose...
3194 if (attributes
.ostream_
)
3196 new_log
->ostream_
= attributes
.ostream_
;
3197 new_log
->ostream_refcount_
=
3198 static_cast<Atomic_ULong
*> (attributes
.ostream_refcount_
);
3200 new_log
->priority_mask (attributes
.priority_mask_
);
3202 if (attributes
.tracing_enabled_
)
3203 new_log
->start_tracing ();
3205 new_log
->restart (attributes
.restart_
);
3206 new_log
->trace_depth (attributes
.trace_depth_
);
3209 // @@ Now the TSS Log_Msg has been created, cache my thread
3213 // This downcast is safe. We do it to avoid having to #include
3214 // ace/Thread_Manager.h.
3215 new_log
->thr_desc (static_cast<ACE_Thread_Descriptor
*> (thr_desc
));
3216 // Block the thread from proceeding until
3217 // thread manager has thread descriptor ready.
3218 #endif /* ! ACE_THREADS_DONT_INHERIT_LOG_MSG && ! ACE_HAS_MINIMAL_ACE_OS */
3221 ACE_END_VERSIONED_NAMESPACE_DECL