*****************************************************************************/
static void QueueMsg ( vlc_object_t *, int, const char *,
const char *, va_list );
-static void FlushMsg ( msg_bank_t * );
static void PrintMsg ( vlc_object_t *, msg_item_t * );
static vlc_mutex_t msg_stack_lock = VLC_STATIC_MUTEX;
vlc_dictionary_init( &priv->msg_enabled_objects, 0 );
priv->msg_all_objects_enabled = true;
- QUEUE.b_overflow = false;
- QUEUE.i_start = 0;
- QUEUE.i_stop = 0;
QUEUE.i_sub = 0;
- QUEUE.pp_sub = 0;
+ QUEUE.pp_sub = NULL;
#ifdef UNDER_CE
QUEUE.logfile =
vlc_mutex_unlock( &msg_stack_lock );
}
-/**
- * Flush all message queues
- */
-void msg_Flush (libvlc_int_t *p_libvlc)
-{
- libvlc_priv_t *priv = libvlc_priv (p_libvlc);
- vlc_mutex_lock( &QUEUE.lock );
- FlushMsg( &QUEUE );
- vlc_mutex_unlock( &QUEUE.lock );
-}
-
-
/**
* Object Printing selection
*/
if( QUEUE.i_sub )
msg_Err( p_libvlc, "stale interface subscribers (VLC might crash)" );
- FlushMsg( &QUEUE );
-
vlc_mutex_lock( &msg_stack_lock );
if( --banks == 0 )
vlc_threadvar_delete( &msg_context );
msg_subscription_t *sub = data;
msg_bank_t *bank = libvlc_bank (sub->instance);
- /* TODO: finer-grained locking and/or msg_item_t refcount */
vlc_mutex_lock (&bank->lock);
- mutex_cleanup_push (&bank->lock);
-
for (;;)
{
/* Wait for messages */
assert (sub->end < VLC_MSG_QSIZE);
while (sub->begin != sub->end)
{
- sub->func (sub->opaque, sub->items[sub->begin], sub->overruns);
+ msg_item_t *msg = sub->items[sub->begin];
+ unsigned overruns = sub->overruns;
+
if (++sub->begin == VLC_MSG_QSIZE)
sub->begin = 0;
sub->overruns = 0;
+ vlc_mutex_unlock (&bank->lock);
+
+ sub->func (sub->opaque, msg, overruns);
+ msg_Release (msg);
+
+ vlc_mutex_lock (&bank->lock);
}
+
+ mutex_cleanup_push (&bank->lock);
vlc_cond_wait (&bank->wait, &bank->lock);
+ vlc_cleanup_pop ();
}
-
- vlc_cleanup_pop ();
assert (0);
}
QueueMsg( p_this, i_type, psz_module, psz_format, args );
}
+/**
+ * Destroys a message.
+ */
+static void msg_Free (gc_object_t *gc)
+{
+ msg_item_t *msg = vlc_priv (gc, msg_item_t);
+
+ free (msg->psz_module);
+ free (msg->psz_msg);
+ free (msg->psz_header);
+ free (msg);
+}
+
/**
* Add a message to a queue
*
char * psz_str = NULL; /* formatted message string */
char * psz_header = NULL;
va_list args;
- msg_item_t * p_item = NULL; /* pointer to message */
- msg_item_t item; /* message in case of a full queue */
- msg_bank_t *p_queue;
+ msg_item_t * p_item = malloc (sizeof (*p_item));
+
+ if (p_item == NULL)
+ return; /* Uho! */
+
+ vlc_gc_init (p_item, msg_Free);
#if !defined(HAVE_VASPRINTF) || defined(__APPLE__) || defined(SYS_BEOS)
int i_size = strlen(psz_format) + INTF_MAX_MSG_SIZE;
psz_str[ i_size - 1 ] = 0; /* Just in case */
#endif
- p_queue = &QUEUE;
+ msg_bank_t *p_queue = &QUEUE;
vlc_mutex_lock( &p_queue->lock );
- /* Check there is room in the queue for our message */
- if( p_queue->b_overflow )
- {
- FlushMsg( p_queue );
-
- if( ((p_queue->i_stop - p_queue->i_start + 1) % VLC_MSG_QSIZE) == 0 )
- {
- /* Still in overflow mode, print from a dummy item */
- p_item = &item;
- }
- else
- {
- /* Pheeew, at last, there is room in the queue! */
- p_queue->b_overflow = false;
- }
- }
- else if( ((p_queue->i_stop - p_queue->i_start + 2) % VLC_MSG_QSIZE) == 0 )
- {
- FlushMsg( p_queue );
-
- if( ((p_queue->i_stop - p_queue->i_start + 2) % VLC_MSG_QSIZE) == 0 )
- {
- p_queue->b_overflow = true;
-
- /* Put the overflow message in the queue */
- p_item = p_queue->msg + p_queue->i_stop;
- p_queue->i_stop = (p_queue->i_stop + 1) % VLC_MSG_QSIZE;
-
- p_item->i_type = VLC_MSG_WARN;
- p_item->i_object_id = (uintptr_t)p_this;
- p_item->psz_object_type = p_this->psz_object_type;
- p_item->psz_module = strdup( "message" );
- p_item->psz_msg = strdup( "message queue overflowed" );
- p_item->psz_header = NULL;
-
- PrintMsg( p_this, p_item );
- /* We print from a dummy item */
- p_item = &item;
- }
- }
-
- if( !p_queue->b_overflow )
- {
- /* Put the message in the queue */
- p_item = p_queue->msg + p_queue->i_stop;
- p_queue->i_stop = (p_queue->i_stop + 1) % VLC_MSG_QSIZE;
- }
-
/* Fill message information fields */
p_item->i_type = i_type;
p_item->i_object_id = (uintptr_t)p_this;
PrintMsg( p_this, p_item );
#define bank p_queue
- if( p_item == &item )
+ for (int i = 0; i < bank->i_sub; i++)
{
- free( p_item->psz_module );
- free( p_item->psz_msg );
- free( p_item->psz_header );
- for (int i = 0; i < bank->i_sub; i++)
- bank->pp_sub[i]->overruns++;
- }
- else
- {
- for (int i = 0; i < bank->i_sub; i++)
+ msg_subscription_t *sub = bank->pp_sub[i];
+ if ((sub->end + 1 - sub->begin) % VLC_MSG_QSIZE)
{
- msg_subscription_t *sub = bank->pp_sub[i];
- if ((sub->end + 1 - sub->begin) % VLC_MSG_QSIZE)
- {
- sub->items[sub->end++] = p_item;
- if (sub->end == VLC_MSG_QSIZE)
- sub->end = 0;
- }
- else
- sub->overruns++;
+ sub->items[sub->end++] = msg_Hold (p_item);
+ if (sub->end == VLC_MSG_QSIZE)
+ sub->end = 0;
}
- vlc_cond_broadcast (&bank->wait);
+ else
+ sub->overruns++;
}
+ vlc_cond_broadcast (&bank->wait);
vlc_mutex_unlock (&bank->lock);
}
-/* following functions are local */
-
-/*****************************************************************************
- * FlushMsg
- *****************************************************************************
- * Print all messages remaining in queue. MESSAGE QUEUE MUST BE LOCKED, since
- * this function does not check the lock.
- *****************************************************************************/
-static void FlushMsg ( msg_bank_t *p_queue )
-{
- int i_index, i_start, i_stop;
-
- /* Get the maximum message index that can be freed */
- i_stop = p_queue->i_stop;
-
- /* Check until which value we can free messages */
- for( i_index = 0; i_index < p_queue->i_sub; i_index++ )
- {
- i_start = p_queue->pp_sub[ i_index ]->begin;
-
- /* If this subscriber is late, we don't free messages before
- * his i_start value, otherwise he'll miss messages */
- if( ( i_start < i_stop
- && (p_queue->i_stop <= i_start || i_stop <= p_queue->i_stop) )
- || ( i_stop < i_start
- && (i_stop <= p_queue->i_stop && p_queue->i_stop <= i_start) ) )
- {
- i_stop = i_start;
- }
- }
-
- /* Free message data */
- for( i_index = p_queue->i_start;
- i_index != i_stop;
- i_index = (i_index+1) % VLC_MSG_QSIZE )
- {
- free( p_queue->msg[i_index].psz_msg );
- free( p_queue->msg[i_index].psz_module );
- free( p_queue->msg[i_index].psz_header );
- }
-
- /* Update the new start value */
- p_queue->i_start = i_index;
-}
-
/*****************************************************************************
* PrintMsg: output a standard message item to stderr
*****************************************************************************