Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Log_Category.h
blobb753a5b5301ff304dcd9cb5afad7fe83b801e930
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Log_Category.h
7 * @author Huang-Ming Huang <huangh@ociweb.com>
8 */
9 //=============================================================================
11 #ifndef ACE_LOG_CATEGORY_H
12 #define ACE_LOG_CATEGORY_H
14 #include /**/ "ace/pre.h"
16 #include "ace/Log_Priority.h"
17 #include "ace/Log_Msg.h"
18 #include "ace/Thread_Mutex.h"
20 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
22 #if defined (ACE_NLOGGING)
23 #if !defined (ACELIB_HEX_DUMP)
24 # define ACELIB_HEX_DUMP(X) do {} while (0)
25 #endif
26 #if !defined (ACELIB_RETURN)
27 # define ACELIB_RETURN(Y) do { return (Y); } while (0)
28 #endif
29 #if !defined (ACELIB_ERROR_RETURN)
30 # define ACELIB_ERROR_RETURN(X, Y) return (Y)
31 #endif
32 #if !defined (ACELIB_ERROR_BREAK)
33 # define ACELIB_ERROR_BREAK(X) { break; }
34 #endif
35 #if !defined (ACELIB_ERROR)
36 # define ACELIB_ERROR(X) do {} while (0)
37 #endif
38 #if !defined (ACELIB_DEBUG)
39 # define ACELIB_DEBUG(X) do {} while (0)
40 #endif
41 #if !defined (ACELIB_ERROR_INIT)
42 # define ACELIB_ERROR_INIT(VALUE, FLAGS)
43 #endif
44 #else
45 #if !defined (ACELIB_HEX_DUMP)
46 #define ACELIB_HEX_DUMP(X) \
47 do { \
48 int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
49 ACE_Log_Category_TSS *ace___ = ACE_Log_Category::ace_lib().per_thr_obj(); \
50 if (ace___ == 0) break;\
51 ace___->conditional_set (__FILE__, __LINE__, 0, __ace_error); \
52 ace___->log_hexdump X; \
53 } while (0)
54 #endif
55 #if !defined (ACELIB_RETURN)
56 #define ACELIB_RETURN(Y) \
57 do { \
58 int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
59 ACE_Log_Msg *ace___ = ACE_Log_Msg::instance(); \
60 ace___->set (__FILE__, __LINE__, Y, __ace_error, ace___->restart (), \
61 ace___->msg_ostream (), ace___->msg_callback ()); \
62 return Y; \
63 } while (0)
64 #endif
65 #if !defined (ACELIB_ERROR_RETURN)
66 # ifdef ACE_LACKS_VA_FUNCTIONS
67 # define ACELIB_ERROR_RETURN(X, Y) \
68 do { \
69 int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
70 ACE_Log_Category_TSS *ace___ = ACE_Log_Category::ace_lib().per_thr_obj(); \
71 if (ace___ == 0) return Y;\
72 ace___->conditional_set (__FILE__, __LINE__, Y, __ace_error); \
73 ace___->log (X); \
74 return Y; \
75 } while (0)
76 # else /* ACE_LACKS_VA_FUNCTIONS */
77 # define ACELIB_ERROR_RETURN(X, Y) \
78 do { \
79 int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
80 ACE_Log_Category_TSS *ace___ = ACE_Log_Category::ace_lib().per_thr_obj(); \
81 if (ace___ == 0) return Y;\
82 ace___->conditional_set (__FILE__, __LINE__, Y, __ace_error); \
83 ace___->log X; \
84 return Y; \
85 } while (0)
86 # endif /* ACE_LACKS_VA_FUNCTIONS */
87 #endif
88 #if !defined (ACELIB_ERROR)
89 # ifdef ACE_LACKS_VA_FUNCTIONS
90 # define ACELIB_ERROR(X) \
91 do { \
92 int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
93 ACE_Log_Category_TSS *ace___ = ACE_Log_Category::ace_lib().per_thr_obj(); \
94 if (ace___ == 0) break;\
95 ace___->conditional_set (__FILE__, __LINE__, -1, __ace_error); \
96 ace___->log (X); \
97 } while (0)
98 # else /* ACE_LACKS_VA_FUNCTIONS */
99 # define ACELIB_ERROR(X) \
100 do { \
101 int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
102 ACE_Log_Category_TSS *ace___ = ACE_Log_Category::ace_lib().per_thr_obj(); \
103 if (ace___ == 0) break;\
104 ace___->conditional_set (__FILE__, __LINE__, -1, __ace_error); \
105 ace___->log X; \
106 } while (0)
107 # endif /* ACE_LACKS_VA_FUNCTIONS */
108 #endif
109 #if !defined (ACELIB_DEBUG)
110 # ifdef ACE_LACKS_VA_FUNCTIONS
111 # define ACELIB_DEBUG(X) \
112 do { \
113 int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
114 ACE_Log_Category_TSS *ace___ = ACE_Log_Category::ace_lib().per_thr_obj(); \
115 if (ace___ == 0) break;\
116 ace___->conditional_set (__FILE__, __LINE__, 0, __ace_error); \
117 ace___->log (X); \
118 } while (0)
119 # else /* ACE_LACKS_VA_FUNCTIONS */
120 # define ACELIB_DEBUG(X) \
121 do { \
122 int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
123 ACE_Log_Category_TSS *ace___ = ACE_Log_Category::ace_lib().per_thr_obj(); \
124 if (ace___ == 0) break;\
125 ace___->conditional_set (__FILE__, __LINE__, 0, __ace_error); \
126 ace___->log X; \
127 } while (0)
128 # endif /* ACE_LACKS_VA_FUNCTIONS */
129 #endif
130 #if !defined (ACELIB_ERROR_BREAK)
131 #define ACELIB_ERROR_BREAK(X) { ACELIB_ERROR (X); break; }
132 #endif
133 #endif /* ACE_NLOGGING */
136 class ACE_Log_Msg;
137 class ACE_Log_Category;
141 * @class ACE_Log_Category_TSS
143 * @brief The thread specific object for a ACE_Log_Categy object.
145 * @see ACE_Log_Categy
147 class ACE_Export ACE_Log_Category_TSS
149 public:
150 ACE_Log_Category_TSS(ACE_Log_Category* category, ACE_Log_Msg* logger);
152 const char* name() const;
153 unsigned int id() const;
155 ACE_Log_Msg* logger();
156 /// Get the current ACE_Log_Priority mask.
157 u_long priority_mask () const;
159 /// Set the ACE_Log_Priority mask, returns original mask.
160 u_long priority_mask (u_long);
161 /// Return true if the requested priority is enabled.
162 int log_priority_enabled (ACE_Log_Priority log_priority);
165 * Set the line number, file name, operational status, error number,
166 * restart flag, ostream, and the callback object. This combines
167 * all the other set methods into a single method.
169 void set (const char *file,
170 int line,
171 int op_status = -1,
172 int errnum = 0);
174 /// These values are only actually set if the requested priority is
175 /// enabled.
176 void conditional_set (const char *file,
177 int line,
178 int op_status,
179 int errnum);
181 #if !defined (ACE_LACKS_VA_FUNCTIONS)
182 ssize_t log (ACE_Log_Priority priority, const ACE_TCHAR *format, ...);
184 #if defined (ACE_HAS_WCHAR)
185 ssize_t log (ACE_Log_Priority priority, const ACE_ANTI_TCHAR *format, ...);
186 #endif /* ACE_HAS_WCHAR */
187 #else /* ACE_LACKS_VA_FUNCTIONS */
188 friend class ACE_Log_Formatter;
190 ssize_t log (const ACE_Log_Formatter &formatter);
191 #endif /* ACE_LACKS_VA_FUNCTIONS */
193 ssize_t log (const ACE_TCHAR *format,
194 ACE_Log_Priority priority,
195 va_list argp);
197 ssize_t log (ACE_Log_Record &log_record,
198 int suppress_stderr = 0);
201 * Method to log hex dump. This is useful for debugging. Calls
202 * log() to do the actual print, but formats first to make the chars
203 * printable.
205 int log_hexdump (ACE_Log_Priority log_priority,
206 const char * buffer,
207 size_t size,
208 const ACE_TCHAR *text = 0);
210 ACE_ALLOC_HOOK_DECLARE;
212 private:
213 friend class ACE_Log_Category;
214 ACE_Log_Category* category_;
215 ACE_Log_Msg* logger_;
216 u_long priority_mask_;
220 * @class ACE_Log_Category
222 * @brief Provides a categorized message logging
223 * abstraction.
225 * This class added another level of abstraction to
226 * @c ACE_Log_Msg to separate log messages into different
227 * categories. Logs in different categories can be independently
228 * enabled or disabled. However, they will all be affected by the
229 * priority_mask setting in ACE_Log_Msg. That is to say, if a
230 * given priority level is disabled using @c ACE_Log_Msg::priority_mask(),
231 * all messages of that priority level logged via any @c ACE_Log_Category
232 * object would also be disabled regardless of the @c priority_mask
233 * setting in the @c ACE_Log_Category object.
235 * Each category can have a name which
236 * is fixed at construction. The name is not used for
237 * formatting the messages. However, it can be used by a
238 * message backend object for identification and reformat
239 * accordingly.
241 * To log a message into a category. Create a new @c ACE_Log_Category
242 * and then use @c per_thr_obj() for logging. For example,
244 * \code{.cpp}
245 * ACE_Log_Category test_category("Test");
246 * test_category.per_thr_obj()->log(LM_DEBUG, "Log into the Test category.");
248 * // set the process wide priority mask
249 * test_category.priority_mask(LM_DEBUG|LM_ERROR);
251 * // set the thread specific priority mask
252 * test_category.per_thr_obj()->priority_mask(LM_DEBUG);
253 * \endcode
255 class ACE_Export ACE_Log_Category
257 public:
259 * Initialize the logger with a name.
261 * Notice that ACE_Log_Category does not
262 * deep copy the passed \a name; therefore,
263 * you must keep the lifetime of \a name
264 * longer than the newly create ACE_Log_Category
265 * object. The rational for the design is to avoid
266 * static initialization problem when the ACE_Log_Category
267 * is created in static storage.
269 ACE_Log_Category(const char* name);
270 ~ACE_Log_Category();
272 unsigned int id() const;
273 const char* name() const;
275 ACE_Log_Category_TSS* per_thr_obj();
277 /// Get the process ACE_Log_Priority mask.
278 u_long priority_mask () const;
280 /// Set the process ACE_Log_Priority mask, returns original mask.
281 u_long priority_mask (u_long);
283 static ACE_Log_Category& ace_lib();
285 private:
286 friend class ACE_Log_Category_TSS;
288 // disable copying
289 ACE_Log_Category(const ACE_Log_Category&);
290 ACE_Log_Category& operator = (const ACE_Log_Category&);
292 const char* name_;
293 unsigned int id_;
294 u_long priority_mask_;
296 /// we couldn't directly use ACE_TSS because it would
297 /// create circular dependency
298 #if defined (ACE_HAS_THREADS)
299 /// Avoid race conditions during initialization.
300 ACE_Thread_Mutex keylock_;
301 /// "First time in" flag.
302 /// Key for the thread-specific error data.
303 ACE_thread_key_t key_;
304 #else // defined (ACE_HAS_THREADS)
305 ACE_Log_Category_TSS per_thr_obj_;
306 #endif // defined (ACE_HAS_THREADS)
309 ACE_END_VERSIONED_NAMESPACE_DECL
311 #if defined (__ACE_INLINE__)
312 #include "ace/Log_Category.inl"
313 #endif /* __ACE_INLINE__ */
315 #include /**/ "ace/post.h"
316 #endif /* ACE_LOG_CATEGORY_H */