X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fevents.c;h=6e056f7ff777880b57095e83b48164b23b8c948d;hb=6ee1e193fd896ab9a4729fde14f009d9ce629815;hp=9db64c28422a5dfb84f66aa829d3782207e7ddb7;hpb=b778f3486ef8c8f21be3712ac15f387d1d02d5d9;p=vlc diff --git a/src/misc/events.c b/src/misc/events.c index 9db64c2842..6e056f7ff7 100644 --- a/src/misc/events.c +++ b/src/misc/events.c @@ -39,6 +39,8 @@ * Documentation : Read vlc_events.h *****************************************************************************/ +//#define DEBUG_EVENT + /***************************************************************************** * Private types. *****************************************************************************/ @@ -47,6 +49,9 @@ 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 @@ -55,8 +60,18 @@ typedef struct vlc_event_listeners_group_t DECL_ARRAY(struct vlc_event_listener_t *) listeners; } vlc_event_listeners_group_t; +#ifdef DEBUG_EVENT +static const char * ppsz_event_type_to_name[] = +{ + [vlc_InputItemMetaChanged] = "vlc_InputItemMetaChanged", + [vlc_InputItemSubItemAdded] = "vlc_InputItemSubItemAdded", + [vlc_ServicesDiscoveryItemAdded] = "vlc_ServicesDiscoveryItemAdded", + [vlc_ServicesDiscoveryItemRemoved] = "vlc_ServicesDiscoveryItemRemoved" +}; +#endif + /***************************************************************************** - * + * *****************************************************************************/ /** @@ -70,6 +85,7 @@ int vlc_event_manager_init( vlc_event_manager_t * p_em, void * p_obj, vlc_object_t * p_parent_obj ) { p_em->p_obj = p_obj; + p_em->p_parent_object = p_parent_obj; vlc_mutex_init( p_parent_obj, &p_em->object_lock ); ARRAY_INIT( p_em->listeners_groups ); return VLC_SUCCESS; @@ -89,8 +105,10 @@ void vlc_event_manager_fini( vlc_event_manager_t * p_em ) FOREACH_ARRAY( listener, listeners_group->listeners ) free( listener ); FOREACH_END() + ARRAY_RESET( listeners_group->listeners ); free( listeners_group ); FOREACH_END() + ARRAY_RESET( p_em->listeners_groups ); } /** @@ -108,7 +126,7 @@ int vlc_event_manager_register_event_type( listeners_group->event_type = event_type; ARRAY_INIT( listeners_group->listeners ); - + vlc_mutex_lock( &p_em->object_lock ); ARRAY_APPEND( p_em->listeners_groups, listeners_group ); vlc_mutex_unlock( &p_em->object_lock ); @@ -124,8 +142,9 @@ void vlc_event_send( vlc_event_manager_t * p_em, { vlc_event_listeners_group_t * listeners_group; vlc_event_listener_t * listener; - vlc_event_callback_t func = NULL; - void * user_data = NULL; + vlc_event_listener_t * array_of_cached_listeners = NULL; + vlc_event_listener_t * cached_listener; + int i, i_cached_listeners = 0; /* Fill event with the sending object now */ p_event->p_obj = p_em->p_obj; @@ -134,51 +153,96 @@ void vlc_event_send( vlc_event_manager_t * p_em, FOREACH_ARRAY( listeners_group, p_em->listeners_groups ) if( listeners_group->event_type == p_event->type ) { - /* We found the group, now send every one the event */ - FOREACH_ARRAY( listener, listeners_group->listeners ) - func = listener->pf_callback; - user_data = listener->p_user_data; - /* This is safe to do that because we are sure - * that there will be no object owned references - * used after the lock. */ + if( listeners_group->listeners.i_size <= 0 ) + break; + + /* Save the function to call */ + i_cached_listeners = listeners_group->listeners.i_size; + array_of_cached_listeners = malloc( + 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 ); - func( p_event, user_data ); - vlc_mutex_lock( &p_em->object_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() vlc_mutex_unlock( &p_em->object_lock ); + + /* Call the function attached */ + cached_listener = array_of_cached_listeners; + 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 + + cached_listener->pf_callback( p_event, cached_listener->p_user_data ); + cached_listener++; + } + free( array_of_cached_listeners ); + } /** * 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 ) +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 ) { vlc_event_listeners_group_t * listeners_group; vlc_event_listener_t * listener; listener = malloc(sizeof(vlc_event_listener_t)); if( !listener ) return VLC_ENOMEM; - + 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; } @@ -206,6 +270,15 @@ 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->object_lock ); return VLC_SUCCESS; @@ -215,7 +288,7 @@ int vlc_event_detach( vlc_event_manager_t *p_em, FOREACH_END() 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; } - -