Commit aa1a821d authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

libvlc: simplify logging callback

Remove static data, and keep each callback correctly scoped to its
LibVLC instance.
parent daafd8f2
...@@ -103,23 +103,20 @@ VLC_API void libvlc_Quit( libvlc_int_t * ); ...@@ -103,23 +103,20 @@ VLC_API void libvlc_Quit( libvlc_int_t * );
/** /**
* Message logging callback signature. * Message logging callback signature.
* Accepts one private data pointer, the message, and an overrun counter. * \param data data pointer as provided to vlc_msg_SetCallback().
* \param type message type (VLC_MSG_* values from enum msg_item_type)
* \param item meta informations
* \param fmt format string
* \param args format string arguments
*/ */
typedef void (*msg_callback_t) (void *, int, const msg_item_t *, typedef void (*vlc_log_cb) (void *data, int type, const msg_item_t *item,
const char *, va_list); const char *fmt, va_list args);
/** VLC_API void vlc_LogSet(libvlc_int_t *, vlc_log_cb cb, void *data);
* Used by interface plugins which subscribe to the message bank.
*/
typedef struct msg_subscription
{
struct msg_subscription *prev, *next;
msg_callback_t func;
void *opaque;
} msg_subscription_t;
VLC_API void vlc_Subscribe(msg_subscription_t *, msg_callback_t, void *); typedef struct msg_subscription { } msg_subscription_t;
VLC_API void vlc_Unsubscribe(msg_subscription_t *); #define vlc_Subscribe(sub,cb,data) ((sub), (cb), (data))
#define vlc_Unsubscribe(sub) ((void)(sub))
/*@}*/ /*@}*/
......
...@@ -194,7 +194,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -194,7 +194,7 @@ static int Open( vlc_object_t *p_this )
return VLC_ENOMEM; return VLC_ENOMEM;
p_sys->p_file = NULL; p_sys->p_file = NULL;
msg_callback_t cb = TextPrint; vlc_log_cb cb = TextPrint;
const char *filename = LOG_FILE_TEXT, *header = TEXT_HEADER; const char *filename = LOG_FILE_TEXT, *header = TEXT_HEADER;
p_sys->footer = TEXT_FOOTER; p_sys->footer = TEXT_FOOTER;
......
...@@ -179,6 +179,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, ...@@ -179,6 +179,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
priv->i_verbose = -1; priv->i_verbose = -1;
} }
vlc_LogInit (p_libvlc);
/* Announce who we are (TODO: only first instance?) */ /* Announce who we are (TODO: only first instance?) */
msg_Dbg( p_libvlc, "VLC media player - %s", VERSION_MESSAGE ); msg_Dbg( p_libvlc, "VLC media player - %s", VERSION_MESSAGE );
msg_Dbg( p_libvlc, "%s", COPYRIGHT_MESSAGE ); msg_Dbg( p_libvlc, "%s", COPYRIGHT_MESSAGE );
...@@ -210,6 +212,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, ...@@ -210,6 +212,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, &vlc_optind ) ) if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, &vlc_optind ) )
{ {
module_EndBank (true); module_EndBank (true);
vlc_LogDeinit (p_libvlc);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -233,6 +236,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, ...@@ -233,6 +236,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
{ {
msg_Err( p_libvlc, "No plugins found! Check your VLC installation."); msg_Err( p_libvlc, "No plugins found! Check your VLC installation.");
module_EndBank (true); module_EndBank (true);
vlc_LogDeinit (p_libvlc);
return VLC_ENOMOD; return VLC_ENOMOD;
} }
...@@ -246,6 +250,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, ...@@ -246,6 +250,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
{ {
msg_Err( p_libvlc, "Unable to fork vlc to daemon mode" ); msg_Err( p_libvlc, "Unable to fork vlc to daemon mode" );
module_EndBank (true); module_EndBank (true);
vlc_LogDeinit (p_libvlc);
return VLC_ENOMEM; return VLC_ENOMEM;
} }
b_daemon = true; b_daemon = true;
...@@ -622,7 +627,7 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc ) ...@@ -622,7 +627,7 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
/* Free module bank. It is refcounted, so we call this each time */ /* Free module bank. It is refcounted, so we call this each time */
module_EndBank (true); module_EndBank (true);
vlc_LogDeinit (p_libvlc);
#if defined(WIN32) || defined(__OS2__) #if defined(WIN32) || defined(__OS2__)
system_End( ); system_End( );
#endif #endif
......
...@@ -74,6 +74,12 @@ void vlc_assert_locked (vlc_mutex_t *); ...@@ -74,6 +74,12 @@ void vlc_assert_locked (vlc_mutex_t *);
# define vlc_assert_locked( m ) (void)m # define vlc_assert_locked( m ) (void)m
#endif #endif
/*
* Logging
*/
void vlc_LogInit(libvlc_int_t *);
void vlc_LogDeinit(libvlc_int_t *);
/* /*
* LibVLC exit event handling * LibVLC exit event handling
*/ */
...@@ -141,7 +147,13 @@ typedef struct libvlc_priv_t ...@@ -141,7 +147,13 @@ typedef struct libvlc_priv_t
{ {
libvlc_int_t public_data; libvlc_int_t public_data;
/* Messages */ /* Logging */
struct
{
void (*cb) (void *, int, const msg_item_t *, const char *, va_list);
void *opaque;
vlc_rwlock_t lock;
} log;
signed char i_verbose; ///< info messages signed char i_verbose; ///< info messages
bool b_color; ///< color messages? bool b_color; ///< color messages?
bool b_stats; ///< Whether to collect stats bool b_stats; ///< Whether to collect stats
......
...@@ -255,9 +255,8 @@ module_unneed ...@@ -255,9 +255,8 @@ module_unneed
vlc_module_load vlc_module_load
vlc_module_unload vlc_module_unload
vlc_Log vlc_Log
vlc_LogSet
vlc_vaLog vlc_vaLog
vlc_Subscribe
vlc_Unsubscribe
msleep msleep
mstrtime mstrtime
mwait mwait
......
...@@ -49,51 +49,6 @@ ...@@ -49,51 +49,6 @@
#include <vlc_charset.h> #include <vlc_charset.h>
#include "../libvlc.h" #include "../libvlc.h"
/**
* Store all data required by messages interfaces.
*/
vlc_rwlock_t msg_lock = VLC_STATIC_RWLOCK;
msg_subscription_t *msg_head;
/**
* Subscribe to the message queue.
* Whenever a message is emitted, a callback will be called.
* Callback invocation are serialized within a subscription.
*
* @param cb callback function
* @param opaque data for the callback function
*/
void vlc_Subscribe (msg_subscription_t *sub, msg_callback_t cb, void *opaque)
{
sub->prev = NULL;
sub->func = cb;
sub->opaque = opaque;
vlc_rwlock_wrlock (&msg_lock);
sub->next = msg_head;
msg_head = sub;
vlc_rwlock_unlock (&msg_lock);
}
/**
* Unsubscribe from the message queue.
* This function waits for the message callback to return if needed.
*/
void vlc_Unsubscribe (msg_subscription_t *sub)
{
vlc_rwlock_wrlock (&msg_lock);
if (sub->next != NULL)
sub->next->prev = sub->prev;
if (sub->prev != NULL)
sub->prev->next = sub->next;
else
{
assert (msg_head == sub);
msg_head = sub->next;
}
vlc_rwlock_unlock (&msg_lock);
}
/** /**
* Emit a log message. * Emit a log message.
* \param obj VLC object emitting the message or NULL * \param obj VLC object emitting the message or NULL
...@@ -112,9 +67,6 @@ void vlc_Log (vlc_object_t *obj, int type, const char *module, ...@@ -112,9 +67,6 @@ void vlc_Log (vlc_object_t *obj, int type, const char *module,
va_end (args); va_end (args);
} }
static void PrintColorMsg (void *, int, const msg_item_t *,
const char *, va_list);
static void PrintMsg (void *, int, const msg_item_t *, const char *, va_list);
#ifdef WIN32 #ifdef WIN32
static void Win32DebugOutputMsg (void *, int , const msg_item_t *, static void Win32DebugOutputMsg (void *, int , const msg_item_t *,
const char *, va_list); const char *, va_list);
...@@ -205,32 +157,20 @@ void vlc_vaLog (vlc_object_t *obj, int type, const char *module, ...@@ -205,32 +157,20 @@ void vlc_vaLog (vlc_object_t *obj, int type, const char *module,
break; break;
} }
/* Pass message to subscribers */ /* Pass message to the callback */
libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc); libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc);
#ifdef WIN32
va_list ap; va_list ap;
va_copy (ap, args);
if (priv->b_color)
PrintColorMsg (&priv->i_verbose, type, &msg, format, ap);
else
PrintMsg (&priv->i_verbose, type, &msg, format, ap);
va_end (ap);
#ifdef WIN32
va_copy (ap, args); va_copy (ap, args);
Win32DebugOutputMsg (&priv->i_verbose, type, &msg, format, ap); Win32DebugOutputMsg (&priv->i_verbose, type, &msg, format, ap);
va_end (ap); va_end (ap);
#endif #endif
vlc_rwlock_rdlock (&msg_lock); vlc_rwlock_rdlock (&priv->log.lock);
for (msg_subscription_t *sub = msg_head; sub != NULL; sub = sub->next) priv->log.cb (priv->log.opaque, type, &msg, format, args);
{ vlc_rwlock_unlock (&priv->log.lock);
va_copy (ap, args);
sub->func (sub->opaque, type, &msg, format, ap);
va_end (ap);
}
vlc_rwlock_unlock (&msg_lock);
uselocale (locale); uselocale (locale);
freelocale (c); freelocale (c);
...@@ -248,10 +188,10 @@ static const char msg_color[4][8] = { WHITE, RED, YELLOW, GRAY }; ...@@ -248,10 +188,10 @@ static const char msg_color[4][8] = { WHITE, RED, YELLOW, GRAY };
static void PrintColorMsg (void *d, int type, const msg_item_t *p_item, static void PrintColorMsg (void *d, int type, const msg_item_t *p_item,
const char *format, va_list ap) const char *format, va_list ap)
{ {
const signed char *pverbose = d;
FILE *stream = stderr; FILE *stream = stderr;
int verbose = (intptr_t)d;
if (*pverbose < 0 || *pverbose < (type - VLC_MSG_ERR)) if (verbose < 0 || verbose < (type - VLC_MSG_ERR))
return; return;
int canc = vlc_savecancel (); int canc = vlc_savecancel ();
...@@ -274,10 +214,10 @@ static void PrintColorMsg (void *d, int type, const msg_item_t *p_item, ...@@ -274,10 +214,10 @@ static void PrintColorMsg (void *d, int type, const msg_item_t *p_item,
static void PrintMsg (void *d, int type, const msg_item_t *p_item, static void PrintMsg (void *d, int type, const msg_item_t *p_item,
const char *format, va_list ap) const char *format, va_list ap)
{ {
const signed char *pverbose = d;
FILE *stream = stderr; FILE *stream = stderr;
int verbose = (intptr_t)d;
if (*pverbose < 0 || *pverbose < (type - VLC_MSG_ERR)) if (verbose < 0 || verbose < (type - VLC_MSG_ERR))
return; return;
int canc = vlc_savecancel (); int canc = vlc_savecancel ();
...@@ -337,3 +277,39 @@ static void Win32DebugOutputMsg (void* d, int type, const msg_item_t *p_item, ...@@ -337,3 +277,39 @@ static void Win32DebugOutputMsg (void* d, int type, const msg_item_t *p_item,
free(msg); free(msg);
} }
#endif #endif
/**
* Sets the message logging callback.
* \param cb message callback, or NULL to reset
* \param data data pointer for the message callback
*/
void vlc_LogSet (libvlc_int_t *vlc, vlc_log_cb cb, void *opaque)
{
libvlc_priv_t *priv = libvlc_priv (vlc);
if (cb == NULL)
{
cb = priv->b_color ? PrintColorMsg : PrintMsg;
opaque = (void *)(intptr_t)priv->i_verbose;
}
vlc_rwlock_wrlock (&priv->log.lock);
priv->log.cb = cb;
priv->log.opaque = opaque;
vlc_rwlock_unlock (&priv->log.lock);
}
void vlc_LogInit (libvlc_int_t *vlc)
{
libvlc_priv_t *priv = libvlc_priv (vlc);
vlc_rwlock_init (&priv->log.lock);
vlc_LogSet (vlc, NULL, NULL);
}
void vlc_LogDeinit (libvlc_int_t *vlc)
{
libvlc_priv_t *priv = libvlc_priv (vlc);
vlc_rwlock_destroy (&priv->log.lock);
}
...@@ -128,7 +128,7 @@ static ULONG vlc_Sleep (ULONG ulTimeout) ...@@ -128,7 +128,7 @@ static ULONG vlc_Sleep (ULONG ulTimeout)
static vlc_mutex_t super_mutex; static vlc_mutex_t super_mutex;
static vlc_cond_t super_variable; static vlc_cond_t super_variable;
extern vlc_rwlock_t config_lock, msg_lock; extern vlc_rwlock_t config_lock;
int _CRT_init(void); int _CRT_init(void);
void _CRT_term(void); void _CRT_term(void);
...@@ -149,13 +149,11 @@ unsigned long _System _DLL_InitTerm(unsigned long hmod, unsigned long flag) ...@@ -149,13 +149,11 @@ unsigned long _System _DLL_InitTerm(unsigned long hmod, unsigned long flag)
vlc_cond_init (&super_variable); vlc_cond_init (&super_variable);
vlc_threadvar_create (&thread_key, NULL); vlc_threadvar_create (&thread_key, NULL);
vlc_rwlock_init (&config_lock); vlc_rwlock_init (&config_lock);
vlc_rwlock_init (&msg_lock);
vlc_CPU_init (); vlc_CPU_init ();
return 1; return 1;
case 1 : /* Termination */ case 1 : /* Termination */
vlc_rwlock_destroy (&msg_lock);
vlc_rwlock_destroy (&config_lock); vlc_rwlock_destroy (&config_lock);
vlc_threadvar_delete (&thread_key); vlc_threadvar_delete (&thread_key);
vlc_cond_destroy (&super_variable); vlc_cond_destroy (&super_variable);
......
...@@ -923,7 +923,7 @@ void vlc_threads_setup (libvlc_int_t *p_libvlc) ...@@ -923,7 +923,7 @@ void vlc_threads_setup (libvlc_int_t *p_libvlc)
SelectClockSource (VLC_OBJECT(p_libvlc)); SelectClockSource (VLC_OBJECT(p_libvlc));
} }
extern vlc_rwlock_t config_lock, msg_lock; extern vlc_rwlock_t config_lock;
BOOL WINAPI DllMain (HINSTANCE, DWORD, LPVOID); BOOL WINAPI DllMain (HINSTANCE, DWORD, LPVOID);
BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
...@@ -939,12 +939,10 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) ...@@ -939,12 +939,10 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
vlc_cond_init (&super_variable); vlc_cond_init (&super_variable);
vlc_threadvar_create (&thread_key, NULL); vlc_threadvar_create (&thread_key, NULL);
vlc_rwlock_init (&config_lock); vlc_rwlock_init (&config_lock);
vlc_rwlock_init (&msg_lock);
vlc_CPU_init (); vlc_CPU_init ();
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
vlc_rwlock_destroy (&msg_lock);
vlc_rwlock_destroy (&config_lock); vlc_rwlock_destroy (&config_lock);
vlc_threadvar_delete (&thread_key); vlc_threadvar_delete (&thread_key);
vlc_cond_destroy (&super_variable); vlc_cond_destroy (&super_variable);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment