X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fevents.c;h=fb2a04df3accfd0cdac885211dce36c37aa5fdb3;hb=c7a51a6b62670ce29d3ae8244f7fd9ca3467601a;hp=19893353536b5f5ffb93417e19364e1165353cc3;hpb=e9fba763dfcb5f7ba12211bddf75bba55c35896c;p=vlc diff --git a/src/misc/events.c b/src/misc/events.c index 1989335353..fb2a04df3a 100644 --- a/src/misc/events.c +++ b/src/misc/events.c @@ -3,24 +3,24 @@ * This library provides an interface to the send and receive events. * It is more lightweight than variable based callback. ***************************************************************************** - * Copyright (C) 1998-2005 the VideoLAN team + * Copyright (C) 1998-2005 VLC authors and VideoLAN * $Id$ * * Authors: Pierre d'Herbemont * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -42,8 +42,6 @@ * Documentation : Read vlc_events.h *****************************************************************************/ -//#define DEBUG_EVENT - /***************************************************************************** * Private types. *****************************************************************************/ @@ -52,9 +50,6 @@ typedef struct vlc_event_listener_t { void * p_user_data; vlc_event_callback_t pf_callback; -#ifdef DEBUG_EVENT - char * psz_debug_name; -#endif } vlc_event_listener_t; typedef struct vlc_event_listeners_group_t @@ -69,26 +64,6 @@ typedef struct vlc_event_listeners_group_t } vlc_event_listeners_group_t; -#ifdef DEBUG_EVENT -static const char ppsz_event_type_to_name[][33] = -{ - [vlc_InputStateChanged] = "vlc_InputStateChanged", - [vlc_InputSelectedStreamChanged] = "vlc_InputSelectedStreamChanged", - - [vlc_InputItemMetaChanged] = "vlc_InputItemMetaChanged", - [vlc_InputItemSubItemAdded] = "vlc_InputItemSubItemAdded", - [vlc_InputItemDurationChanged] = "vlc_InputItemDurationChanged", - [vlc_InputItemPreparsedChanged] = "vlc_InputItemPreparsedChanged", - [vlc_InputItemNameChanged] = "vlc_InputItemNameChanged", - [vlc_InputItemInfoChanged] = "vlc_InputItemInfoChanged", - - [vlc_ServicesDiscoveryItemAdded] = "vlc_ServicesDiscoveryItemAdded", - [vlc_ServicesDiscoveryItemRemoved] = "vlc_ServicesDiscoveryItemRemoved" - [vlc_ServicesDiscoveryStarted] = "vlc_ServicesDiscoveryStarted" - [vlc_ServicesDiscoveryEnded] = "vlc_ServicesDiscoveryEnded" -}; -#endif - static bool listeners_are_equal( vlc_event_listener_t * listener1, vlc_event_listener_t * listener2 ) @@ -113,18 +88,16 @@ group_contains_listener( vlc_event_listeners_group_t * group, * *****************************************************************************/ +#undef vlc_event_manager_init /** * Initialize event manager object * p_obj is the object that contains the event manager. But not * necessarily a vlc_object_t (an input_item_t is not a vlc_object_t * for instance). - * p_parent_obj gives a libvlc instance */ -int __vlc_event_manager_init( vlc_event_manager_t * p_em, void * p_obj, - vlc_object_t * p_parent_obj ) +int vlc_event_manager_init( vlc_event_manager_t * p_em, void * p_obj ) { p_em->p_obj = p_obj; - p_em->p_parent_object = p_parent_obj; vlc_mutex_init( &p_em->object_lock ); /* We need a recursive lock here, because we need to be able @@ -160,7 +133,7 @@ void vlc_event_manager_fini( vlc_event_manager_t * p_em ) } /** - * Destroy the event manager + * Register the event manager */ int vlc_event_manager_register_event_type( vlc_event_manager_t * p_em, @@ -197,7 +170,9 @@ void vlc_event_send( vlc_event_manager_t * p_em, /* Fill event with the sending object now */ p_event->p_obj = p_em->p_obj; + vlc_mutex_lock( &p_em->event_sending_lock ) ; vlc_mutex_lock( &p_em->object_lock ); + FOREACH_ARRAY( listeners_group, p_em->listeners_groups ) if( listeners_group->event_type == p_event->type ) { @@ -210,62 +185,51 @@ void vlc_event_send( vlc_event_manager_t * p_em, sizeof(vlc_event_listener_t)*i_cached_listeners ); if( !array_of_cached_listeners ) { - msg_Err( p_em->p_parent_object, "Not enough memory in vlc_event_send" ); vlc_mutex_unlock( &p_em->object_lock ); + vlc_mutex_unlock( &p_em->event_sending_lock ) ; return; } cached_listener = array_of_cached_listeners; FOREACH_ARRAY( listener, listeners_group->listeners ) memcpy( cached_listener, listener, sizeof(vlc_event_listener_t)); -#ifdef DEBUG_EVENT - cached_listener->psz_debug_name = strdup(cached_listener->psz_debug_name); -#endif cached_listener++; FOREACH_END() break; } FOREACH_END() + + /* Track item removed from *this* thread, with a simple flag. Indeed + * event_sending_lock is a recursive lock. This has the advantage of + * allowing to remove an event listener from within a callback */ + listeners_group->b_sublistener_removed = false; + vlc_mutex_unlock( &p_em->object_lock ); - + /* Call the function attached */ cached_listener = array_of_cached_listeners; if( !listeners_group || !array_of_cached_listeners ) { free( array_of_cached_listeners ); + vlc_mutex_unlock( &p_em->event_sending_lock ); return; } - vlc_mutex_lock( &p_em->event_sending_lock ) ; - - /* Track item removed from *this* thread, with a simple flag */ - listeners_group->b_sublistener_removed = false; for( i = 0; i < i_cached_listeners; i++ ) { -#ifdef DEBUG_EVENT - msg_Dbg( p_em->p_parent_object, - "Calling '%s' with a '%s' event (data %p)", - cached_listener->psz_debug_name, - ppsz_event_type_to_name[p_event->type], - cached_listener->p_user_data ); - free(cached_listener->psz_debug_name); -#endif - /* No need to lock on listeners_group, a listener group can't be removed */ if( listeners_group->b_sublistener_removed ) { - /* If a callback was removed, this gets called */ + /* If a callback was removed inside one of our callback, this gets + * called */ bool valid_listener; vlc_mutex_lock( &p_em->object_lock ); valid_listener = group_contains_listener( listeners_group, cached_listener ); vlc_mutex_unlock( &p_em->object_lock ); if( !valid_listener ) { -#ifdef DEBUG_EVENT - msg_Dbg( p_em->p_parent_object, "Callback was removed during execution" ); -#endif cached_listener++; continue; } @@ -278,14 +242,14 @@ void vlc_event_send( vlc_event_manager_t * p_em, free( array_of_cached_listeners ); } +#undef vlc_event_attach /** * Add a callback for an event. */ -int __vlc_event_attach( vlc_event_manager_t * p_em, - vlc_event_type_t event_type, - vlc_event_callback_t pf_callback, - void *p_user_data, - const char * psz_debug_name ) +int vlc_event_attach( vlc_event_manager_t * p_em, + vlc_event_type_t event_type, + vlc_event_callback_t pf_callback, + void *p_user_data ) { vlc_event_listeners_group_t * listeners_group; vlc_event_listener_t * listener; @@ -295,49 +259,34 @@ int __vlc_event_attach( vlc_event_manager_t * p_em, listener->p_user_data = p_user_data; listener->pf_callback = pf_callback; -#ifdef DEBUG_EVENT - listener->psz_debug_name = strdup( psz_debug_name ); -#else - (void)psz_debug_name; -#endif vlc_mutex_lock( &p_em->object_lock ); FOREACH_ARRAY( listeners_group, p_em->listeners_groups ) if( listeners_group->event_type == event_type ) { ARRAY_APPEND( listeners_group->listeners, listener ); -#ifdef DEBUG_EVENT - msg_Dbg( p_em->p_parent_object, - "Listening to '%s' event with '%s' (data %p)", - ppsz_event_type_to_name[event_type], - listener->psz_debug_name, - listener->p_user_data ); -#endif vlc_mutex_unlock( &p_em->object_lock ); return VLC_SUCCESS; } FOREACH_END() - vlc_mutex_unlock( &p_em->object_lock ); - - msg_Err( p_em->p_parent_object, "Can't attach to an object event manager event" ); - free(listener); - return VLC_EGENERIC; + /* Unknown event = BUG */ + assert( 0 ); } /** * Remove a callback for an event. */ -int vlc_event_detach( vlc_event_manager_t *p_em, - vlc_event_type_t event_type, - vlc_event_callback_t pf_callback, - void *p_user_data ) +void vlc_event_detach( vlc_event_manager_t *p_em, + vlc_event_type_t event_type, + vlc_event_callback_t pf_callback, + void *p_user_data ) { vlc_event_listeners_group_t * listeners_group; struct vlc_event_listener_t * listener; - vlc_mutex_lock( &p_em->object_lock ); vlc_mutex_lock( &p_em->event_sending_lock ); + vlc_mutex_lock( &p_em->object_lock ); FOREACH_ARRAY( listeners_group, p_em->listeners_groups ) if( listeners_group->event_type == event_type ) { @@ -353,28 +302,14 @@ int vlc_event_detach( vlc_event_manager_t *p_em, ARRAY_REMOVE( listeners_group->listeners, fe_idx /* This comes from the macro (and that's why I hate macro) */ ); -#ifdef DEBUG_EVENT - msg_Dbg( p_em->p_parent_object, - "Detaching '%s' from '%s' event (data %p)", - listener->psz_debug_name, - ppsz_event_type_to_name[event_type], - listener->p_user_data ); - - free( listener->psz_debug_name ); -#endif free( listener ); vlc_mutex_unlock( &p_em->event_sending_lock ); vlc_mutex_unlock( &p_em->object_lock ); - return VLC_SUCCESS; + return; } FOREACH_END() } FOREACH_END() - vlc_mutex_unlock( &p_em->event_sending_lock ); - vlc_mutex_unlock( &p_em->object_lock ); - msg_Warn( p_em->p_parent_object, "Can't detach to an object event manager event" ); - - return VLC_EGENERIC; + assert( 0 ); } -