X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fcontrol%2Flog.c;h=8986eea246e0c396eed560953bef539b16c7493c;hb=7bdcd022287f5f99e68ea6f422edbee6cfc54e62;hp=0eeec2195be94e00272a353045dc3843286c42af;hpb=fc7795f191b1dce05d3da5088a119976bc1f7aad;p=vlc diff --git a/src/control/log.c b/src/control/log.c index 0eeec2195b..8986eea246 100644 --- a/src/control/log.c +++ b/src/control/log.c @@ -3,7 +3,7 @@ ***************************************************************************** * Copyright (C) 2005 the VideoLAN team * - * $Id: core.c 14187 2006-02-07 16:37:40Z courmisch $ + * $Id$ * * Authors: Damien Fouilleul * @@ -22,63 +22,99 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ -#include +#include "libvlc_internal.h" #include +#include + +/* This API is terminally broken. + * First, it does not implement any kind of notification. + * Second, the iterating scheme is hermetic to any kind of thread-safety + * owing to its constant pointer constraints. + * -- Courmisch + * + * "If you break your leg, don't run to me for sympathy" + * -- some character, Beneath a Steel Sky + */ + +struct msg_cb_data_t +{ + vlc_spinlock_t lock; + msg_item_t *items[VLC_MSG_QSIZE]; + unsigned count; + int verbosity; +}; + +static void handler( msg_cb_data_t *d, msg_item_t *p_item, unsigned i_drop ) +{ + if (p_item->i_type > d->verbosity) + return; + + vlc_spin_lock (&d->lock); + if (d->count < VLC_MSG_QSIZE) + { + d->items[d->count++] = p_item; + /* FIXME FIXME: yield the message item */ + } + vlc_spin_unlock (&d->lock); + (void)i_drop; +} struct libvlc_log_t { - const libvlc_instance_t *p_instance; + libvlc_instance_t *p_instance; msg_subscription_t *p_messages; + msg_cb_data_t data; }; struct libvlc_log_iterator_t { - msg_subscription_t *p_messages; - int i_start; - int i_pos; - int i_end; + const msg_cb_data_t *p_data; + unsigned i_pos; + unsigned i_end; }; unsigned libvlc_get_log_verbosity( const libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) { - if( p_instance ) - { - return p_instance->p_libvlc_int->i_verbose; - } - RAISEZERO("Invalid VLC instance!"); + assert( p_instance ); + (void)p_e; + return p_instance->verbosity; } void libvlc_set_log_verbosity( libvlc_instance_t *p_instance, unsigned level, libvlc_exception_t *p_e ) { - if( p_instance ) - { - p_instance->p_libvlc_int->i_verbose = level; - } - else - RAISEVOID("Invalid VLC instance!"); + assert( p_instance ); + (void)p_e; + p_instance->verbosity = level; } -libvlc_log_t *libvlc_log_open( const libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) +libvlc_log_t *libvlc_log_open( libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) { - struct libvlc_log_t *p_log = (struct libvlc_log_t *)malloc(sizeof(struct libvlc_log_t)); if( !p_log ) RAISENULL( "Out of memory" ); p_log->p_instance = p_instance; - p_log->p_messages = msg_Subscribe(p_instance->p_libvlc_int, MSG_QUEUE_NORMAL); + p_log->data.verbosity = p_instance->verbosity; + p_log->p_messages = msg_Subscribe(p_instance->p_libvlc_int, handler, &p_log->data); - if( !p_log->p_messages ) RAISENULL( "Out of memory" ); + if( !p_log->p_messages ) + { + free( p_log ); + RAISENULL( "Out of memory" ); + } + libvlc_retain( p_instance ); return p_log; } void libvlc_log_close( libvlc_log_t *p_log, libvlc_exception_t *p_e ) { - if( p_log && p_log->p_messages ) + if( p_log ) { - msg_Unsubscribe(p_log->p_instance->p_libvlc_int, p_log->p_messages); + assert( p_log->p_messages ); + msg_Unsubscribe(p_log->p_messages); + libvlc_release( p_log->p_instance ); free(p_log); } else @@ -87,23 +123,28 @@ void libvlc_log_close( libvlc_log_t *p_log, libvlc_exception_t *p_e ) unsigned libvlc_log_count( const libvlc_log_t *p_log, libvlc_exception_t *p_e ) { - if( p_log && p_log->p_messages ) + if( p_log ) { - int i_start = p_log->p_messages->i_start; - int i_stop = *(p_log->p_messages->pi_stop); - - return (i_stop - i_start) % VLC_MSG_QSIZE; + unsigned ret; + + /* We cannot lock due to pointer constraints. + * Even then, this would not be thread safe anyway. */ + /*vlc_spin_lock (&p_log->data.lock);*/ + ret = p_log->data.count; + /*vlc_spin_unlock (&p_log->data.lock);*/ + return ret; } RAISEZERO("Invalid log object!"); } void libvlc_log_clear( libvlc_log_t *p_log, libvlc_exception_t *p_e ) { - if( p_log && p_log->p_messages ) + if( p_log ) { - vlc_mutex_lock(p_log->p_messages->p_lock); - p_log->p_messages->i_start = *(p_log->p_messages->pi_stop); - vlc_mutex_unlock(p_log->p_messages->p_lock); + /*vlc_spin_lock (&p_log->data.lock);*/ + p_log->data.count = 0; + /* FIXME: release items */ + /*vlc_spin_unlock (&p_log->data.lock);*/ } else RAISEVOID("Invalid log object!"); @@ -111,19 +152,18 @@ void libvlc_log_clear( libvlc_log_t *p_log, libvlc_exception_t *p_e ) libvlc_log_iterator_t *libvlc_log_get_iterator( const libvlc_log_t *p_log, libvlc_exception_t *p_e ) { - if( p_log && p_log->p_messages ) + if( p_log ) { struct libvlc_log_iterator_t *p_iter = (struct libvlc_log_iterator_t *)malloc(sizeof(struct libvlc_log_iterator_t)); if( !p_iter ) RAISENULL( "Out of memory" ); - vlc_mutex_lock(p_log->p_messages->p_lock); - p_iter->p_messages = p_log->p_messages; - p_iter->i_start = p_log->p_messages->i_start; - p_iter->i_pos = p_log->p_messages->i_start; - p_iter->i_end = *(p_log->p_messages->pi_stop); - vlc_mutex_unlock(p_log->p_messages->p_lock); + /*vlc_spin_lock (&p_log->data.lock);*/ + p_iter->p_data = &p_log->data; + p_iter->i_pos = 0; + p_iter->i_end = p_log->data.count; + /*vlc_spin_unlock (&p_log->data.lock);*/ return p_iter; } @@ -150,33 +190,31 @@ int libvlc_log_iterator_has_next( const libvlc_log_iterator_t *p_iter, libvlc_ex } libvlc_log_message_t *libvlc_log_iterator_next( libvlc_log_iterator_t *p_iter, - struct libvlc_log_message_t *buffer, + libvlc_log_message_t *buffer, libvlc_exception_t *p_e ) { - if( p_iter ) - { - if( buffer && (sizeof(struct libvlc_log_message_t) == buffer->sizeof_msg) ) - { - int i_pos = p_iter->i_pos; - if( i_pos != p_iter->i_end ) - { - msg_item_t *msg; - vlc_mutex_lock(p_iter->p_messages->p_lock); - msg = p_iter->p_messages->p_msg+i_pos; - buffer->i_severity = msg->i_type; - buffer->psz_type = msg_GetObjectTypeName(msg->i_object_type); - buffer->psz_name = msg->psz_module; - buffer->psz_header = msg->psz_header; - buffer->psz_message = msg->psz_msg; - p_iter->i_pos = ++i_pos % VLC_MSG_QSIZE; - vlc_mutex_unlock(p_iter->p_messages->p_lock); - - return buffer; - } - RAISENULL("No more messages"); - } + unsigned i_pos; + + if( !p_iter ) + RAISENULL("Invalid log iterator!"); + if( !buffer ) RAISENULL("Invalid message buffer!"); + + i_pos = p_iter->i_pos; + if( i_pos != p_iter->i_end ) + { + msg_item_t *msg; + /*vlc_spin_lock (&p_iter->p_data->lock);*/ + msg = p_iter->p_data->items[i_pos]; + buffer->i_severity = msg->i_type; + buffer->psz_type = msg->psz_object_type; + buffer->psz_name = msg->psz_module; + buffer->psz_header = msg->psz_header; + buffer->psz_message = msg->psz_msg; + /*vlc_spin_unlock (&p_iter->p_data->lock);*/ + p_iter->i_pos++; + + return buffer; } - RAISENULL("Invalid log iterator!"); + RAISENULL("No more messages"); } -