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

Hide message bank layout and cleanup a bit

Also fix a potential crash in case of stale subscriber
(print debug message to stderr).
parent b5c10ad6
...@@ -116,10 +116,11 @@ VLC_EXPORT( msg_subscription_t*, msg_Subscribe, ( libvlc_int_t *, msg_callback_t ...@@ -116,10 +116,11 @@ VLC_EXPORT( msg_subscription_t*, msg_Subscribe, ( libvlc_int_t *, msg_callback_t
VLC_EXPORT( void, msg_Unsubscribe, ( msg_subscription_t * ) ); VLC_EXPORT( void, msg_Unsubscribe, ( msg_subscription_t * ) );
/* Enable or disable a certain object debug messages */ /* Enable or disable a certain object debug messages */
#define msg_EnableObjectPrinting(a,b) __msg_EnableObjectPrinting(VLC_OBJECT(a),b) VLC_EXPORT( void, msg_EnableObjectPrinting, ( vlc_object_t *, const char * psz_object ) );
#define msg_DisableObjectPrinting(a,b) __msg_DisableObjectPrinting(VLC_OBJECT(a),b) #define msg_EnableObjectPrinting(a,b) msg_EnableObjectPrinting(VLC_OBJECT(a),b)
VLC_EXPORT( void, __msg_EnableObjectPrinting, ( vlc_object_t *, const char * psz_object ) ); VLC_EXPORT( void, msg_DisableObjectPrinting, ( vlc_object_t *, const char * psz_object ) );
VLC_EXPORT( void, __msg_DisableObjectPrinting, ( vlc_object_t *, const char * psz_object ) ); #define msg_DisableObjectPrinting(a,b) msg_DisableObjectPrinting(VLC_OBJECT(a),b)
/** /**
* @} * @}
......
...@@ -255,7 +255,9 @@ libvlc_int_t * libvlc_InternalCreate( void ) ...@@ -255,7 +255,9 @@ libvlc_int_t * libvlc_InternalCreate( void )
priv->p_vlm = NULL; priv->p_vlm = NULL;
/* Initialize message queue */ /* Initialize message queue */
msg_Create( p_libvlc ); priv->msg_bank = msg_Create ();
if (unlikely(priv->msg_bank == NULL))
goto error;
/* Find verbosity from VLC_VERBOSE environment variable */ /* Find verbosity from VLC_VERBOSE environment variable */
psz_env = getenv( "VLC_VERBOSE" ); psz_env = getenv( "VLC_VERBOSE" );
...@@ -273,6 +275,9 @@ libvlc_int_t * libvlc_InternalCreate( void ) ...@@ -273,6 +275,9 @@ libvlc_int_t * libvlc_InternalCreate( void )
vlc_mutex_init( &priv->timer_lock ); vlc_mutex_init( &priv->timer_lock );
return p_libvlc; return p_libvlc;
error:
vlc_object_release (p_libvlc);
return NULL;
} }
/** /**
...@@ -1070,7 +1075,7 @@ void libvlc_InternalDestroy( libvlc_int_t *p_libvlc ) ...@@ -1070,7 +1075,7 @@ void libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
} }
vlc_mutex_unlock( &global_lock ); vlc_mutex_unlock( &global_lock );
msg_Destroy( p_libvlc ); msg_Destroy (priv->msg_bank);
/* Destroy mutexes */ /* Destroy mutexes */
vlc_mutex_destroy( &priv->timer_lock ); vlc_mutex_destroy( &priv->timer_lock );
......
...@@ -84,28 +84,10 @@ bool vlc_CPU_CheckPluginDir (const char *name); ...@@ -84,28 +84,10 @@ bool vlc_CPU_CheckPluginDir (const char *name);
* Message/logging stuff * Message/logging stuff
*/ */
/** typedef struct msg_bank_t msg_bank_t;
* Store all data required by messages interfaces.
*/
typedef struct msg_bank_t
{
/** Message queue lock */
vlc_rwlock_t lock;
/* Subscribers */
int i_sub;
msg_subscription_t **pp_sub;
/* Logfile for WinCE */
#ifdef UNDER_CE
FILE *logfile;
#endif
locale_t locale;
} msg_bank_t;
void msg_Create (libvlc_int_t *); msg_bank_t *msg_Create (void);
void msg_Destroy (libvlc_int_t *); void msg_Destroy (msg_bank_t *);
/** Internal message stack context */ /** Internal message stack context */
void msg_StackSet ( int, const char*, ... ); void msg_StackSet ( int, const char*, ... );
...@@ -211,11 +193,9 @@ typedef struct libvlc_priv_t ...@@ -211,11 +193,9 @@ typedef struct libvlc_priv_t
bool playlist_active; bool playlist_active;
/* Messages */ /* Messages */
msg_bank_t msg_bank; ///< The message bank msg_bank_t *msg_bank; ///< The message bank
int i_verbose; ///< info messages int i_verbose; ///< info messages
vlc_dictionary_t msg_enabled_objects; ///< Enabled objects
bool b_color; ///< color messages? bool b_color; ///< color messages?
bool msg_all_objects_enabled; ///< Should we print all objects?
/* Timer stats */ /* Timer stats */
bool b_stats; ///< Whether to collect stats bool b_stats; ///< Whether to collect stats
......
...@@ -252,8 +252,8 @@ __module_need ...@@ -252,8 +252,8 @@ __module_need
module_provides module_provides
module_release module_release
__module_unneed __module_unneed
__msg_DisableObjectPrinting msg_DisableObjectPrinting
__msg_EnableObjectPrinting msg_EnableObjectPrinting
__msg_Generic __msg_Generic
__msg_GenericVa __msg_GenericVa
msg_Subscribe msg_Subscribe
......
...@@ -81,7 +81,7 @@ static uintptr_t banks = 0; ...@@ -81,7 +81,7 @@ static uintptr_t banks = 0;
#define QUEUE priv->msg_bank #define QUEUE priv->msg_bank
static inline msg_bank_t *libvlc_bank (libvlc_int_t *inst) static inline msg_bank_t *libvlc_bank (libvlc_int_t *inst)
{ {
return &(libvlc_priv (inst))->msg_bank; return (libvlc_priv (inst))->msg_bank;
} }
/***************************************************************************** /*****************************************************************************
...@@ -93,21 +93,42 @@ static void PrintMsg ( vlc_object_t *, msg_item_t * ); ...@@ -93,21 +93,42 @@ static void PrintMsg ( vlc_object_t *, msg_item_t * );
static vlc_mutex_t msg_stack_lock = VLC_STATIC_MUTEX; static vlc_mutex_t msg_stack_lock = VLC_STATIC_MUTEX;
/**
* Store all data required by messages interfaces.
*/
struct msg_bank_t
{
/** Message queue lock */
vlc_rwlock_t lock;
/* Subscribers */
int i_sub;
msg_subscription_t **pp_sub;
/* Logfile for WinCE */
#ifdef UNDER_CE
FILE *logfile;
#endif
locale_t locale; /**< C locale for error messages */
vlc_dictionary_t enabled_objects; ///< Enabled objects
bool all_objects_enabled; ///< Should we print all objects?
};
/** /**
* Initialize messages queues * Initialize messages queues
* This function initializes all message queues * This function initializes all message queues
*/ */
void msg_Create (libvlc_int_t *p_libvlc) msg_bank_t *msg_Create (void)
{ {
libvlc_priv_t *priv = libvlc_priv (p_libvlc); msg_bank_t *bank = malloc (sizeof (*bank));
msg_bank_t *bank = libvlc_bank (p_libvlc);
vlc_rwlock_init (&bank->lock); vlc_rwlock_init (&bank->lock);
vlc_dictionary_init( &priv->msg_enabled_objects, 0 ); vlc_dictionary_init (&bank->enabled_objects, 0);
priv->msg_all_objects_enabled = true; bank->all_objects_enabled = true;
QUEUE.i_sub = 0; bank->i_sub = 0;
QUEUE.pp_sub = NULL; bank->pp_sub = NULL;
/* C locale to get error messages in English in the logs */ /* C locale to get error messages in English in the logs */
bank->locale = newlocale (LC_MESSAGES_MASK, "C", (locale_t)0); bank->locale = newlocale (LC_MESSAGES_MASK, "C", (locale_t)0);
...@@ -124,6 +145,7 @@ void msg_Create (libvlc_int_t *p_libvlc) ...@@ -124,6 +145,7 @@ void msg_Create (libvlc_int_t *p_libvlc)
if( banks++ == 0 ) if( banks++ == 0 )
vlc_threadvar_create( &msg_context, cleanup_msg_context ); vlc_threadvar_create( &msg_context, cleanup_msg_context );
vlc_mutex_unlock( &msg_stack_lock ); vlc_mutex_unlock( &msg_stack_lock );
return bank;
} }
/** /**
...@@ -132,26 +154,32 @@ void msg_Create (libvlc_int_t *p_libvlc) ...@@ -132,26 +154,32 @@ void msg_Create (libvlc_int_t *p_libvlc)
static void const * kObjectPrintingEnabled = &kObjectPrintingEnabled; static void const * kObjectPrintingEnabled = &kObjectPrintingEnabled;
static void const * kObjectPrintingDisabled = &kObjectPrintingDisabled; static void const * kObjectPrintingDisabled = &kObjectPrintingDisabled;
void __msg_EnableObjectPrinting (vlc_object_t *p_this, const char * psz_object) #undef msg_EnableObjectPrinting
void msg_EnableObjectPrinting (vlc_object_t *obj, const char * psz_object)
{ {
libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); msg_bank_t *bank = libvlc_bank (obj->p_libvlc);
vlc_rwlock_wrlock( &QUEUE.lock );
vlc_rwlock_wrlock (&bank->lock);
if( !strcmp(psz_object, "all") ) if( !strcmp(psz_object, "all") )
priv->msg_all_objects_enabled = true; bank->all_objects_enabled = true;
else else
vlc_dictionary_insert( &priv->msg_enabled_objects, psz_object, (void *)kObjectPrintingEnabled ); vlc_dictionary_insert (&bank->enabled_objects, psz_object,
vlc_rwlock_unlock( &QUEUE.lock ); (void *)kObjectPrintingEnabled);
vlc_rwlock_unlock (&bank->lock);
} }
void __msg_DisableObjectPrinting (vlc_object_t *p_this, const char * psz_object) #undef msg_DisableObjectPrinting
void msg_DisableObjectPrinting (vlc_object_t *obj, const char * psz_object)
{ {
libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); msg_bank_t *bank = libvlc_bank (obj->p_libvlc);
vlc_rwlock_wrlock( &QUEUE.lock );
vlc_rwlock_wrlock (&bank->lock);
if( !strcmp(psz_object, "all") ) if( !strcmp(psz_object, "all") )
priv->msg_all_objects_enabled = false; bank->all_objects_enabled = false;
else else
vlc_dictionary_insert( &priv->msg_enabled_objects, psz_object, (void *)kObjectPrintingDisabled ); vlc_dictionary_insert (&bank->enabled_objects, psz_object,
vlc_rwlock_unlock( &QUEUE.lock ); (void *)kObjectPrintingDisabled);
vlc_rwlock_unlock (&bank->lock);
} }
/** /**
...@@ -161,13 +189,10 @@ void __msg_DisableObjectPrinting (vlc_object_t *p_this, const char * psz_object) ...@@ -161,13 +189,10 @@ void __msg_DisableObjectPrinting (vlc_object_t *p_this, const char * psz_object)
* then frees all the allocated resources * then frees all the allocated resources
* No other messages interface functions should be called after this one. * No other messages interface functions should be called after this one.
*/ */
void msg_Destroy (libvlc_int_t *p_libvlc) void msg_Destroy (msg_bank_t *bank)
{ {
libvlc_priv_t *priv = libvlc_priv (p_libvlc); if (unlikely(bank->i_sub != 0))
msg_bank_t *bank = libvlc_bank (p_libvlc); fputs ("stale interface subscribers (LibVLC might crash)\n", stderr);
if( QUEUE.i_sub )
msg_Err( p_libvlc, "stale interface subscribers (VLC might crash)" );
vlc_mutex_lock( &msg_stack_lock ); vlc_mutex_lock( &msg_stack_lock );
assert(banks > 0); assert(banks > 0);
...@@ -181,9 +206,10 @@ void msg_Destroy (libvlc_int_t *p_libvlc) ...@@ -181,9 +206,10 @@ void msg_Destroy (libvlc_int_t *p_libvlc)
if (bank->locale != (locale_t)0) if (bank->locale != (locale_t)0)
freelocale (bank->locale); freelocale (bank->locale);
vlc_dictionary_clear( &priv->msg_enabled_objects, NULL, NULL ); vlc_dictionary_clear (&bank->enabled_objects, NULL, NULL);
vlc_rwlock_destroy (&bank->lock); vlc_rwlock_destroy (&bank->lock);
free (bank);
} }
struct msg_subscription_t struct msg_subscription_t
...@@ -281,19 +307,19 @@ static void msg_Free (gc_object_t *gc) ...@@ -281,19 +307,19 @@ static void msg_Free (gc_object_t *gc)
static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module, static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module,
const char *psz_format, va_list _args ) const char *psz_format, va_list _args )
{ {
assert (p_this); size_t i_header_size; /* Size of the additionnal header */
libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc);
int i_header_size; /* Size of the additionnal header */
vlc_object_t *p_obj; vlc_object_t *p_obj;
char * psz_str = NULL; /* formatted message string */ char * psz_str = NULL; /* formatted message string */
char * psz_header = NULL; char * psz_header = NULL;
va_list args; va_list args;
assert (p_this);
if( p_this->i_flags & OBJECT_FLAGS_QUIET || if( p_this->i_flags & OBJECT_FLAGS_QUIET ||
(p_this->i_flags & OBJECT_FLAGS_NODBG && i_type == VLC_MSG_DBG) ) (p_this->i_flags & OBJECT_FLAGS_NODBG && i_type == VLC_MSG_DBG) )
return; return;
msg_bank_t *bank = &QUEUE; msg_bank_t *bank = libvlc_bank (p_this->p_libvlc);
locale_t locale = uselocale (bank->locale); locale_t locale = uselocale (bank->locale);
#ifndef __GLIBC__ #ifndef __GLIBC__
...@@ -462,6 +488,7 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item ) ...@@ -462,6 +488,7 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item )
static const char ppsz_color[4][8] = { WHITE, RED, YELLOW, GRAY }; static const char ppsz_color[4][8] = { WHITE, RED, YELLOW, GRAY };
const char *psz_object; const char *psz_object;
libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc);
msg_bank_t *bank = priv->msg_bank;
int i_type = p_item->i_type; int i_type = p_item->i_type;
switch( i_type ) switch( i_type )
...@@ -481,21 +508,21 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item ) ...@@ -481,21 +508,21 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item )
} }
psz_object = p_item->psz_object_type; psz_object = p_item->psz_object_type;
void * val = vlc_dictionary_value_for_key( &priv->msg_enabled_objects, void * val = vlc_dictionary_value_for_key (&bank->enabled_objects,
p_item->psz_module ); p_item->psz_module);
if( val == kObjectPrintingDisabled ) if( val == kObjectPrintingDisabled )
return; return;
if( val == kObjectPrintingEnabled ) if( val == kObjectPrintingEnabled )
/* Allowed */; /* Allowed */;
else else
{ {
val = vlc_dictionary_value_for_key( &priv->msg_enabled_objects, val = vlc_dictionary_value_for_key (&bank->enabled_objects,
psz_object ); psz_object);
if( val == kObjectPrintingDisabled ) if( val == kObjectPrintingDisabled )
return; return;
if( val == kObjectPrintingEnabled ) if( val == kObjectPrintingEnabled )
/* Allowed */; /* Allowed */;
else if( !priv->msg_all_objects_enabled ) else if( !bank->all_objects_enabled )
return; return;
} }
......
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