forked from enlightenment/efl
eina_log: thread safe logging!
eina_log_threads_enable() and then get thread safe logging with non-main threads being printed with special notation to easily spot those. SVN revision: 42199
This commit is contained in:
parent
d8ee1b3a24
commit
8024360138
|
@ -28,6 +28,7 @@
|
||||||
#define EINA_COLOR_BLUE "\033[34;1m"
|
#define EINA_COLOR_BLUE "\033[34;1m"
|
||||||
#define EINA_COLOR_GREEN "\033[32;1m"
|
#define EINA_COLOR_GREEN "\033[32;1m"
|
||||||
#define EINA_COLOR_YELLOW "\033[33;1m"
|
#define EINA_COLOR_YELLOW "\033[33;1m"
|
||||||
|
#define EINA_COLOR_ORANGE "\033[0;33m"
|
||||||
#define EINA_COLOR_WHITE "\033[37;1m"
|
#define EINA_COLOR_WHITE "\033[37;1m"
|
||||||
#define EINA_COLOR_LIGHTBLUE "\033[36;1m"
|
#define EINA_COLOR_LIGHTBLUE "\033[36;1m"
|
||||||
#define EINA_COLOR_RESET "\033[0m"
|
#define EINA_COLOR_RESET "\033[0m"
|
||||||
|
@ -177,6 +178,7 @@ typedef void (*Eina_Log_Print_Cb)(const Eina_Log_Domain *d, Eina_Log_Level level
|
||||||
|
|
||||||
EAPI int eina_log_init(void);
|
EAPI int eina_log_init(void);
|
||||||
EAPI int eina_log_shutdown(void);
|
EAPI int eina_log_shutdown(void);
|
||||||
|
EAPI void eina_log_threads_enable(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Customization
|
* Customization
|
||||||
|
|
|
@ -342,6 +342,48 @@ static int _eina_log_init_count = 0;
|
||||||
static Eina_Bool _disable_color = EINA_FALSE;
|
static Eina_Bool _disable_color = EINA_FALSE;
|
||||||
static Eina_Bool _abort_on_critical = EINA_FALSE;
|
static Eina_Bool _abort_on_critical = EINA_FALSE;
|
||||||
|
|
||||||
|
#ifdef EFL_HAVE_PTHREAD
|
||||||
|
#include <pthread.h>
|
||||||
|
static Eina_Bool _threads_enabled = EINA_FALSE;
|
||||||
|
static pthread_t _main_thread;
|
||||||
|
static pthread_spinlock_t _log_lock;
|
||||||
|
#define LOCK() \
|
||||||
|
do { \
|
||||||
|
if (0) \
|
||||||
|
fprintf(stderr, "+++LOG LOCKED! [%s, %lu]\n", \
|
||||||
|
__FUNCTION__, pthread_self()); \
|
||||||
|
if (EINA_UNLIKELY(_threads_enabled)) \
|
||||||
|
pthread_spin_lock(&_log_lock); \
|
||||||
|
} while (0)
|
||||||
|
#define UNLOCK() \
|
||||||
|
do { \
|
||||||
|
if (EINA_UNLIKELY(_threads_enabled)) \
|
||||||
|
pthread_spin_unlock(&_log_lock); \
|
||||||
|
if (0) \
|
||||||
|
fprintf(stderr, \
|
||||||
|
"---LOG UNLOCKED! [%s, %lu]\n", \
|
||||||
|
__FUNCTION__, pthread_self()); \
|
||||||
|
} while (0)
|
||||||
|
#define IS_MAIN(t) pthread_equal(t, _main_thread)
|
||||||
|
#define IS_OTHER(t) EINA_UNLIKELY(!IS_MAIN(t))
|
||||||
|
#define CHECK_MAIN(...) \
|
||||||
|
do { \
|
||||||
|
if (!IS_MAIN(pthread_self())) { \
|
||||||
|
fprintf(stderr, \
|
||||||
|
"ERR: not main thread! current=%lu, main=%lu\n", \
|
||||||
|
pthread_self(), _main_thread); \
|
||||||
|
return __VA_ARGS__; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define LOCK() do {} while (0)
|
||||||
|
#define UNLOCK() do {} while (0)
|
||||||
|
#define IS_MAIN(t) (1)
|
||||||
|
#define IS_OTHER(t) (0)
|
||||||
|
#define CHECK_MAIN(...) do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// List of domains registered
|
// List of domains registered
|
||||||
static Eina_Log_Domain *_log_domains = NULL;
|
static Eina_Log_Domain *_log_domains = NULL;
|
||||||
static int _log_domains_count = 0;
|
static int _log_domains_count = 0;
|
||||||
|
@ -613,6 +655,10 @@ EAPI int EINA_LOG_DOMAIN_GLOBAL = 0;
|
||||||
* @c EINA_LOG_ABORT=1.
|
* @c EINA_LOG_ABORT=1.
|
||||||
*
|
*
|
||||||
* @see eina_init()
|
* @see eina_init()
|
||||||
|
*
|
||||||
|
* @warning Not-MT: just call this function from main thread! The
|
||||||
|
* place where this function was called the first time is
|
||||||
|
* considered the main thread.
|
||||||
*/
|
*/
|
||||||
EAPI int
|
EAPI int
|
||||||
eina_log_init(void)
|
eina_log_init(void)
|
||||||
|
@ -625,6 +671,11 @@ eina_log_init(void)
|
||||||
assert((sizeof(_names)/sizeof(_names[0])) == EINA_LOG_LEVELS);
|
assert((sizeof(_names)/sizeof(_names[0])) == EINA_LOG_LEVELS);
|
||||||
assert((sizeof(_colors)/sizeof(_colors[0])) == EINA_LOG_LEVELS + 1);
|
assert((sizeof(_colors)/sizeof(_colors[0])) == EINA_LOG_LEVELS + 1);
|
||||||
|
|
||||||
|
#ifdef EFL_HAVE_PTHREAD
|
||||||
|
_main_thread = pthread_self();
|
||||||
|
pthread_spin_init(&_log_lock, PTHREAD_PROCESS_PRIVATE);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check if color is disabled
|
// Check if color is disabled
|
||||||
if ((tmp = getenv(EINA_LOG_ENV_COLOR_DISABLE)) && (atoi(tmp) == 1))
|
if ((tmp = getenv(EINA_LOG_ENV_COLOR_DISABLE)) && (atoi(tmp) == 1))
|
||||||
_disable_color = EINA_TRUE;
|
_disable_color = EINA_TRUE;
|
||||||
|
@ -666,12 +717,18 @@ eina_log_init(void)
|
||||||
* the log list.
|
* the log list.
|
||||||
*
|
*
|
||||||
* @see eina_shutdown()
|
* @see eina_shutdown()
|
||||||
|
*
|
||||||
|
* @warning Not-MT: just call this function from main thread! The
|
||||||
|
* place where eina_log_init() was called the first time is
|
||||||
|
* considered the main thread.
|
||||||
*/
|
*/
|
||||||
EAPI int
|
EAPI int
|
||||||
eina_log_shutdown(void)
|
eina_log_shutdown(void)
|
||||||
{
|
{
|
||||||
Eina_Inlist *tmp;
|
Eina_Inlist *tmp;
|
||||||
|
|
||||||
|
CHECK_MAIN(0);
|
||||||
|
|
||||||
if (_eina_log_init_count != 1) return --_eina_log_init_count;
|
if (_eina_log_init_count != 1) return --_eina_log_init_count;
|
||||||
|
|
||||||
while (_log_domains_count--)
|
while (_log_domains_count--)
|
||||||
|
@ -692,19 +749,57 @@ eina_log_shutdown(void)
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EFL_HAVE_PTHREAD
|
||||||
|
pthread_spin_destroy(&_log_lock);
|
||||||
|
_threads_enabled = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
return --_eina_log_init_count;
|
return --_eina_log_init_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable logging module to handle threads.
|
||||||
|
*
|
||||||
|
* There is no disable option on purpose, if it is enabled, there is
|
||||||
|
* no way back until you call the last eina_log_shutdown().
|
||||||
|
*
|
||||||
|
* There is no function to retrieve if threads are enabled as one is
|
||||||
|
* not supposed to know this from outside.
|
||||||
|
*
|
||||||
|
* After this call is executed at least once, if Eina was compiled
|
||||||
|
* with threads support then logging will lock around debug messages
|
||||||
|
* and threads that are not the main thread will have its identifier
|
||||||
|
* printed.
|
||||||
|
*
|
||||||
|
* The main thread is considered the thread where the first
|
||||||
|
* eina_log_init() was called.
|
||||||
|
*/
|
||||||
|
EAPI void
|
||||||
|
eina_log_threads_enable(void)
|
||||||
|
{
|
||||||
|
#ifdef EFL_HAVE_PTHREAD
|
||||||
|
_threads_enabled = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets logging method to use.
|
* Sets logging method to use.
|
||||||
*
|
*
|
||||||
* By default, eina_log_print_cb_stderr() is used.
|
* By default, eina_log_print_cb_stderr() is used.
|
||||||
|
*
|
||||||
|
* @note MT: safe to call from any thread.
|
||||||
|
*
|
||||||
|
* @note MT: given function @a cb will be called protected by mutex.
|
||||||
|
* This means you're safe from other calls but you should never
|
||||||
|
* call eina_log_print(), directly or indirectly.
|
||||||
*/
|
*/
|
||||||
EAPI void
|
EAPI void
|
||||||
eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data)
|
eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data)
|
||||||
{
|
{
|
||||||
|
LOCK();
|
||||||
_print_cb = cb;
|
_print_cb = cb;
|
||||||
_print_cb_data = data;
|
_print_cb_data = data;
|
||||||
|
UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -715,26 +810,18 @@ eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data)
|
||||||
* This function sets the log log level @p level. It is used in
|
* This function sets the log log level @p level. It is used in
|
||||||
* eina_log_print().
|
* eina_log_print().
|
||||||
*/
|
*/
|
||||||
EAPI void eina_log_level_set(Eina_Log_Level level)
|
EAPI void
|
||||||
|
eina_log_level_set(Eina_Log_Level level)
|
||||||
{
|
{
|
||||||
_log_level = level;
|
_log_level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static inline int
|
||||||
* @param name Domain name
|
eina_log_domain_register_unlocked(const char *name, const char *color)
|
||||||
* @param color Color of the domain name
|
|
||||||
*
|
|
||||||
* @return Domain index that will be used as the DOMAIN parameter on log
|
|
||||||
* macros. A negative return value means an log ocurred.
|
|
||||||
*/
|
|
||||||
EAPI int
|
|
||||||
eina_log_domain_register(const char *name, const char *color)
|
|
||||||
{
|
{
|
||||||
Eina_Log_Domain_Level_Pending *pending = NULL;
|
Eina_Log_Domain_Level_Pending *pending = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, -1);
|
|
||||||
|
|
||||||
for (i = 0; i < _log_domains_count; i++)
|
for (i = 0; i < _log_domains_count; i++)
|
||||||
{
|
{
|
||||||
if (_log_domains[i].deleted)
|
if (_log_domains[i].deleted)
|
||||||
|
@ -786,8 +873,31 @@ finish_register:
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
/**
|
||||||
eina_log_domain_unregister(int domain)
|
* @param name Domain name
|
||||||
|
* @param color Color of the domain name
|
||||||
|
*
|
||||||
|
* @return Domain index that will be used as the DOMAIN parameter on log
|
||||||
|
* macros. A negative return value means an log ocurred.
|
||||||
|
*
|
||||||
|
* @note MT: safe to call from any thread.
|
||||||
|
*/
|
||||||
|
EAPI int
|
||||||
|
eina_log_domain_register(const char *name, const char *color)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(name, -1);
|
||||||
|
|
||||||
|
LOCK();
|
||||||
|
r = eina_log_domain_register_unlocked(name, color);
|
||||||
|
UNLOCK();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
eina_log_domain_unregister_unlocked(int domain)
|
||||||
{
|
{
|
||||||
Eina_Log_Domain *d;
|
Eina_Log_Domain *d;
|
||||||
|
|
||||||
|
@ -798,12 +908,33 @@ eina_log_domain_unregister(int domain)
|
||||||
d->deleted = 1;
|
d->deleted = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forget about a logging domain registered by eina_log_domain_register()
|
||||||
|
*
|
||||||
|
* @param domain domain identifier as reported by eina_log_domain_register(),
|
||||||
|
* must be >= 0.
|
||||||
|
*
|
||||||
|
* @note MT: safe to call from any thread.
|
||||||
|
*/
|
||||||
|
EAPI void
|
||||||
|
eina_log_domain_unregister(int domain)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_FALSE_RETURN(domain >= 0);
|
||||||
|
LOCK();
|
||||||
|
eina_log_domain_unregister_unlocked(domain);
|
||||||
|
UNLOCK();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default logging method, this will output to standard error stream.
|
* Default logging method, this will output to standard error stream.
|
||||||
*
|
*
|
||||||
* This method will colorize output based on domain provided color and
|
* This method will colorize output based on domain provided color and
|
||||||
* message logging level. To disable color, set environment variable
|
* message logging level. To disable color, set environment variable
|
||||||
* EINA_LOG_COLOR_DISABLE=1
|
* EINA_LOG_COLOR_DISABLE=1
|
||||||
|
*
|
||||||
|
* @note MT: if threads are enabled, this function is called within locks.
|
||||||
|
* @note MT: Threads different from main thread will have thread id
|
||||||
|
* appended to domain name.
|
||||||
*/
|
*/
|
||||||
EAPI void
|
EAPI void
|
||||||
eina_log_print_cb_stderr(const Eina_Log_Domain *d, Eina_Log_Level level,
|
eina_log_print_cb_stderr(const Eina_Log_Domain *d, Eina_Log_Level level,
|
||||||
|
@ -832,14 +963,43 @@ eina_log_print_cb_stderr(const Eina_Log_Domain *d, Eina_Log_Level level,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EINA_UNLIKELY(_disable_color))
|
if (EINA_UNLIKELY(_disable_color))
|
||||||
fprintf(stderr,
|
{
|
||||||
"%s:%s %s:%d %s() ",
|
#ifdef EFL_HAVE_PTHREAD
|
||||||
name, d->domain_str, file, line, fnc);
|
if (_threads_enabled)
|
||||||
|
{
|
||||||
|
pthread_t cur = pthread_self();
|
||||||
|
if (IS_OTHER(cur))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s:%s[T:%lu] %s:%d %s() ",
|
||||||
|
name, d->domain_str, cur, file, line, fnc);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "%s:%s %s:%d %s() ",
|
||||||
|
name, d->domain_str, file, line, fnc);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fprintf(stderr,
|
{
|
||||||
"%s%s" EINA_COLOR_RESET ":%s %s:%d "
|
#ifdef EFL_HAVE_PTHREAD
|
||||||
EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ",
|
if (_threads_enabled)
|
||||||
color, name, d->domain_str, file, line, fnc);
|
{
|
||||||
|
pthread_t cur = pthread_self();
|
||||||
|
if (IS_OTHER(cur))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s%s" EINA_COLOR_RESET ":%s[T:"
|
||||||
|
EINA_COLOR_ORANGE "%lu" EINA_COLOR_RESET "] %s:%d "
|
||||||
|
EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ",
|
||||||
|
color, name, d->domain_str, cur, file, line, fnc);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "%s%s" EINA_COLOR_RESET ":%s %s:%d "
|
||||||
|
EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ",
|
||||||
|
color, name, d->domain_str, file, line, fnc);
|
||||||
|
}
|
||||||
|
end:
|
||||||
vfprintf(stderr, fmt, args);
|
vfprintf(stderr, fmt, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,6 +1009,10 @@ eina_log_print_cb_stderr(const Eina_Log_Domain *d, Eina_Log_Level level,
|
||||||
* This method will colorize output based on domain provided color and
|
* This method will colorize output based on domain provided color and
|
||||||
* message logging level. To disable color, set environment variable
|
* message logging level. To disable color, set environment variable
|
||||||
* EINA_LOG_COLOR_DISABLE=1
|
* EINA_LOG_COLOR_DISABLE=1
|
||||||
|
*
|
||||||
|
* @note MT: if threads are enabled, this function is called within locks.
|
||||||
|
* @note MT: Threads different from main thread will have thread id
|
||||||
|
* appended to domain name.
|
||||||
*/
|
*/
|
||||||
EAPI void
|
EAPI void
|
||||||
eina_log_print_cb_stdout(const Eina_Log_Domain *d, Eina_Log_Level level,
|
eina_log_print_cb_stdout(const Eina_Log_Domain *d, Eina_Log_Level level,
|
||||||
|
@ -877,12 +1041,43 @@ eina_log_print_cb_stdout(const Eina_Log_Domain *d, Eina_Log_Level level,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EINA_UNLIKELY(_disable_color))
|
if (EINA_UNLIKELY(_disable_color))
|
||||||
printf("%s:%s %s:%d %s() ",
|
{
|
||||||
name, d->domain_str, file, line, fnc);
|
#ifdef EFL_HAVE_PTHREAD
|
||||||
|
if (_threads_enabled)
|
||||||
|
{
|
||||||
|
pthread_t cur = pthread_self();
|
||||||
|
if (IS_OTHER(cur))
|
||||||
|
{
|
||||||
|
printf("%s:%s[T:%lu] %s:%d %s() ",
|
||||||
|
name, d->domain_str, cur, file, line, fnc);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
printf("%s:%s %s:%d %s() ",
|
||||||
|
name, d->domain_str, file, line, fnc);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
printf("%s%s" EINA_COLOR_RESET ":%s %s:%d "
|
{
|
||||||
EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ",
|
#ifdef EFL_HAVE_PTHREAD
|
||||||
color, name, d->domain_str, file, line, fnc);
|
if (_threads_enabled)
|
||||||
|
{
|
||||||
|
pthread_t cur = pthread_self();
|
||||||
|
if (IS_OTHER(cur))
|
||||||
|
{
|
||||||
|
printf("%s%s" EINA_COLOR_RESET ":%s[T:"
|
||||||
|
EINA_COLOR_ORANGE "%lu" EINA_COLOR_RESET "] %s:%d "
|
||||||
|
EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ",
|
||||||
|
color, name, d->domain_str, cur, file, line, fnc);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
printf("%s%s" EINA_COLOR_RESET ":%s %s:%d "
|
||||||
|
EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ",
|
||||||
|
color, name, d->domain_str, file, line, fnc);
|
||||||
|
}
|
||||||
|
end:
|
||||||
vprintf(fmt, args);
|
vprintf(fmt, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -890,6 +1085,10 @@ eina_log_print_cb_stdout(const Eina_Log_Domain *d, Eina_Log_Level level,
|
||||||
* Alternative logging method, this will output to given file stream.
|
* Alternative logging method, this will output to given file stream.
|
||||||
*
|
*
|
||||||
* This method will never output color.
|
* This method will never output color.
|
||||||
|
*
|
||||||
|
* @note MT: if threads are enabled, this function is called within locks.
|
||||||
|
* @note MT: Threads different from main thread will have thread id
|
||||||
|
* appended to domain name.
|
||||||
*/
|
*/
|
||||||
EAPI void
|
EAPI void
|
||||||
eina_log_print_cb_file(const Eina_Log_Domain *d, __UNUSED__ Eina_Log_Level level,
|
eina_log_print_cb_file(const Eina_Log_Domain *d, __UNUSED__ Eina_Log_Level level,
|
||||||
|
@ -897,33 +1096,28 @@ eina_log_print_cb_file(const Eina_Log_Domain *d, __UNUSED__ Eina_Log_Level level
|
||||||
void *data, va_list args)
|
void *data, va_list args)
|
||||||
{
|
{
|
||||||
FILE *f = data;
|
FILE *f = data;
|
||||||
|
#ifdef EFL_HAVE_PTHREAD
|
||||||
|
if (_threads_enabled)
|
||||||
|
{
|
||||||
|
pthread_t cur = pthread_self();
|
||||||
|
if (IS_OTHER(cur))
|
||||||
|
{
|
||||||
|
fprintf(f, "%s[T:%lu] %s:%d %s() ", d->name, cur, file, line, fnc);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
fprintf(f, "%s %s:%d %s() ", d->name, file, line, fnc);
|
fprintf(f, "%s %s:%d %s() ", d->name, file, line, fnc);
|
||||||
|
end:
|
||||||
vfprintf(f, fmt, args);
|
vfprintf(f, fmt, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
static inline void
|
||||||
eina_log_print(int domain, Eina_Log_Level level, const char *file,
|
eina_log_print_unlocked(int domain, Eina_Log_Level level, const char *file, const char *fnc, int line, const char *fmt, va_list args)
|
||||||
const char *fnc, int line, const char *fmt, ...)
|
|
||||||
{
|
{
|
||||||
Eina_Log_Domain *d;
|
Eina_Log_Domain *d;
|
||||||
va_list args;
|
|
||||||
|
|
||||||
#ifdef EINA_SAFETY_CHECKS
|
#ifdef EINA_SAFETY_CHECKS
|
||||||
if (EINA_UNLIKELY(file == NULL))
|
|
||||||
{
|
|
||||||
fputs("ERR: eina_log_print() file == NULL\n", stderr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (EINA_UNLIKELY(fnc == NULL))
|
|
||||||
{
|
|
||||||
fputs("ERR: eina_log_print() fnc == NULL\n", stderr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (EINA_UNLIKELY(fmt == NULL))
|
|
||||||
{
|
|
||||||
fputs("ERR: eina_log_print() fmt == NULL\n", stderr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (EINA_UNLIKELY(domain >= _log_domains_count) ||
|
if (EINA_UNLIKELY(domain >= _log_domains_count) ||
|
||||||
EINA_UNLIKELY(domain < 0))
|
EINA_UNLIKELY(domain < 0))
|
||||||
{
|
{
|
||||||
|
@ -942,11 +1136,60 @@ eina_log_print(int domain, Eina_Log_Level level, const char *file,
|
||||||
|
|
||||||
if (level > d->level) return;
|
if (level > d->level) return;
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
_print_cb(d, level, file, fnc, line, fmt, _print_cb_data, args);
|
_print_cb(d, level, file, fnc, line, fmt, _print_cb_data, args);
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
if (EINA_UNLIKELY(_abort_on_critical) &&
|
if (EINA_UNLIKELY(_abort_on_critical) &&
|
||||||
EINA_UNLIKELY(level <= EINA_LOG_LEVEL_CRITICAL))
|
EINA_UNLIKELY(level <= EINA_LOG_LEVEL_CRITICAL))
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print out log message using given domain and level.
|
||||||
|
*
|
||||||
|
* @note Usually you'll not use this function directly but the helper
|
||||||
|
* macros EINA_LOG(), EINA_LOG_DOM_CRIT(), EINA_LOG_CRIT() and
|
||||||
|
* so on. See eina_log.h
|
||||||
|
*
|
||||||
|
* @param domain logging domain to use or @c EINA_LOG_DOMAIN_GLOBAL if
|
||||||
|
* you registered none. It is recommended that modules and
|
||||||
|
* applications have their own logging domain.
|
||||||
|
* @param level message level, those with level greater than user
|
||||||
|
* specified value (eina_log_level_set() or environment
|
||||||
|
* variables EINA_LOG_LEVEL, EINA_LOG_LEVELS) will be ignored.
|
||||||
|
* @param file filename that originated the call, must @b not be @c NULL.
|
||||||
|
* @param fnc function that originated the call, must @b not be @c NULL.
|
||||||
|
* @param line originating line in @a file.
|
||||||
|
* @param fmt printf-like format to use.
|
||||||
|
*
|
||||||
|
* @note MT: this function may be called from different threads if
|
||||||
|
* eina_log_threads_enable() was called before.
|
||||||
|
*/
|
||||||
|
EAPI void
|
||||||
|
eina_log_print(int domain, Eina_Log_Level level, const char *file,
|
||||||
|
const char *fnc, int line, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
#ifdef EINA_SAFETY_CHECKS
|
||||||
|
if (EINA_UNLIKELY(file == NULL))
|
||||||
|
{
|
||||||
|
fputs("ERR: eina_log_print() file == NULL\n", stderr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (EINA_UNLIKELY(fnc == NULL))
|
||||||
|
{
|
||||||
|
fputs("ERR: eina_log_print() fnc == NULL\n", stderr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (EINA_UNLIKELY(fmt == NULL))
|
||||||
|
{
|
||||||
|
fputs("ERR: eina_log_print() fmt == NULL\n", stderr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
va_start(args, fmt);
|
||||||
|
LOCK();
|
||||||
|
eina_log_print_unlocked(domain, level, file, fnc, line, fmt, args);
|
||||||
|
UNLOCK();
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue