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 * );
/**
* 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 *,
const char *, va_list);
typedef void (*vlc_log_cb) (void *data, int type, const msg_item_t *item,
const char *fmt, va_list args);
/**
* 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_LogSet(libvlc_int_t *, vlc_log_cb cb, void *data);
VLC_API void vlc_Subscribe(msg_subscription_t *, msg_callback_t, void *);
VLC_API void vlc_Unsubscribe(msg_subscription_t *);
typedef struct msg_subscription { } 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 )
return VLC_ENOMEM;
p_sys->p_file = NULL;
msg_callback_t cb = TextPrint;
vlc_log_cb cb = TextPrint;
const char *filename = LOG_FILE_TEXT, *header = TEXT_HEADER;
p_sys->footer = TEXT_FOOTER;
......
......@@ -179,6 +179,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
priv->i_verbose = -1;
}
vlc_LogInit (p_libvlc);
/* Announce who we are (TODO: only first instance?) */
msg_Dbg( p_libvlc, "VLC media player - %s", VERSION_MESSAGE );
msg_Dbg( p_libvlc, "%s", COPYRIGHT_MESSAGE );
......@@ -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 ) )
{
module_EndBank (true);
vlc_LogDeinit (p_libvlc);
return VLC_EGENERIC;
}
......@@ -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.");
module_EndBank (true);
vlc_LogDeinit (p_libvlc);
return VLC_ENOMOD;
}
......@@ -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" );
module_EndBank (true);
vlc_LogDeinit (p_libvlc);
return VLC_ENOMEM;
}
b_daemon = true;
......@@ -622,7 +627,7 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
/* Free module bank. It is refcounted, so we call this each time */
module_EndBank (true);
vlc_LogDeinit (p_libvlc);
#if defined(WIN32) || defined(__OS2__)
system_End( );
#endif
......
......@@ -74,6 +74,12 @@ void vlc_assert_locked (vlc_mutex_t *);
# define vlc_assert_locked( m ) (void)m
#endif
/*
* Logging
*/
void vlc_LogInit(libvlc_int_t *);
void vlc_LogDeinit(libvlc_int_t *);
/*
* LibVLC exit event handling
*/
......@@ -141,7 +147,13 @@ typedef struct libvlc_priv_t
{
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
bool b_color; ///< color messages?
bool b_stats; ///< Whether to collect stats
......
......@@ -255,9 +255,8 @@ module_unneed
vlc_module_load
vlc_module_unload
vlc_Log
vlc_LogSet
vlc_vaLog
vlc_Subscribe
vlc_Unsubscribe
msleep
mstrtime
mwait
......
......@@ -49,51 +49,6 @@
#include <vlc_charset.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.
* \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,
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
static void Win32DebugOutputMsg (void *, int , const msg_item_t *,
const char *, va_list);
......@@ -205,32 +157,20 @@ void vlc_vaLog (vlc_object_t *obj, int type, const char *module,
break;
}
/* Pass message to subscribers */
/* Pass message to the callback */
libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc);
#ifdef WIN32
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);
Win32DebugOutputMsg (&priv->i_verbose, type, &msg, format, ap);
va_end (ap);
#endif
vlc_rwlock_rdlock (&msg_lock);
for (msg_subscription_t *sub = msg_head; sub != NULL; sub = sub->next)
{
va_copy (ap, args);
sub->func (sub->opaque, type, &msg, format, ap);
va_end (ap);
}
vlc_rwlock_unlock (&msg_lock);
vlc_rwlock_rdlock (&priv->log.lock);
priv->log.cb (priv->log.opaque, type, &msg, format, args);
vlc_rwlock_unlock (&priv->log.lock);
uselocale (locale);
freelocale (c);
......@@ -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,
const char *format, va_list ap)
{
const signed char *pverbose = d;
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;
int canc = vlc_savecancel ();
......@@ -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,
const char *format, va_list ap)
{
const signed char *pverbose = d;
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;
int canc = vlc_savecancel ();
......@@ -337,3 +277,39 @@ static void Win32DebugOutputMsg (void* d, int type, const msg_item_t *p_item,
free(msg);
}
#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)
static vlc_mutex_t super_mutex;
static vlc_cond_t super_variable;
extern vlc_rwlock_t config_lock, msg_lock;
extern vlc_rwlock_t config_lock;
int _CRT_init(void);
void _CRT_term(void);
......@@ -149,13 +149,11 @@ unsigned long _System _DLL_InitTerm(unsigned long hmod, unsigned long flag)
vlc_cond_init (&super_variable);
vlc_threadvar_create (&thread_key, NULL);
vlc_rwlock_init (&config_lock);
vlc_rwlock_init (&msg_lock);
vlc_CPU_init ();
return 1;
case 1 : /* Termination */
vlc_rwlock_destroy (&msg_lock);
vlc_rwlock_destroy (&config_lock);
vlc_threadvar_delete (&thread_key);
vlc_cond_destroy (&super_variable);
......
......@@ -923,7 +923,7 @@ void vlc_threads_setup (libvlc_int_t *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 hinstDll, DWORD fdwReason, LPVOID lpvReserved)
......@@ -939,12 +939,10 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
vlc_cond_init (&super_variable);
vlc_threadvar_create (&thread_key, NULL);
vlc_rwlock_init (&config_lock);
vlc_rwlock_init (&msg_lock);
vlc_CPU_init ();
break;
case DLL_PROCESS_DETACH:
vlc_rwlock_destroy (&msg_lock);
vlc_rwlock_destroy (&config_lock);
vlc_threadvar_delete (&thread_key);
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