[vlc-commits] lib: simplify and speed up event delivery
Rémi Denis-Courmont
git at videolan.org
Wed Aug 5 20:31:27 CEST 2015
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Aug 5 21:12:00 2015 +0300| [175ce396f3d6094a908b0dd7892d222bc5f80710] | committer: Rémi Denis-Courmont
lib: simplify and speed up event delivery
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=175ce396f3d6094a908b0dd7892d222bc5f80710
---
lib/event.c | 106 +++++++----------------------------------------------------
1 file changed, 11 insertions(+), 95 deletions(-)
diff --git a/lib/event.c b/lib/event.c
index 158ab30..6475e2f 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -87,42 +87,13 @@ typedef struct libvlc_event_manager_t
vlc_mutex_t lock;
} libvlc_event_sender_t;
-
-static inline bool
-listeners_are_equal( libvlc_event_listener_t * listener1,
- libvlc_event_listener_t * listener2 )
-{
- return listener1->event_type == listener2->event_type &&
- listener1->pf_callback == listener2->pf_callback &&
- listener1->p_user_data == listener2->p_user_data;
-}
-
-
typedef struct libvlc_event_listeners_group_t
{
libvlc_event_type_t event_type;
vlc_array_t listeners;
- bool b_sublistener_removed;
} libvlc_event_listeners_group_t;
/*
- * Private functions
- */
-
-static bool
-group_contains_listener( libvlc_event_listeners_group_t * group,
- libvlc_event_listener_t * searched_listener )
-{
- int i;
- for( i = 0; i < vlc_array_count(&group->listeners); i++ )
- {
- if( listeners_are_equal(searched_listener, vlc_array_item_at_index(&group->listeners, i)) )
- return true;
- }
- return false;
-}
-
-/*
* Internal libvlc functions
*/
@@ -203,11 +174,7 @@ void libvlc_event_manager_register_event_type(
void libvlc_event_send( libvlc_event_manager_t * p_em,
libvlc_event_t * p_event )
{
- libvlc_event_listeners_group_t * listeners_group = NULL;
- libvlc_event_listener_t * listener_cached;
- libvlc_event_listener_t * listener;
- libvlc_event_listener_t * array_listeners_cached = NULL;
- int i, i_cached_listeners = 0;
+ int i;
/* Fill event with the sending object now */
p_event->p_obj = p_em->p_obj;
@@ -215,68 +182,22 @@ void libvlc_event_send( libvlc_event_manager_t * p_em,
vlc_mutex_lock(&p_em->lock);
for( i = 0; i < vlc_array_count(&p_em->listeners_groups); i++)
{
- listeners_group = vlc_array_item_at_index(&p_em->listeners_groups, i);
- if( listeners_group->event_type == p_event->type )
- {
- if( vlc_array_count( &listeners_group->listeners ) <= 0 )
- break;
-
- /* Cache a copy of the listener to avoid locking issues,
- * and allow that edition of listeners during callbacks will garantee immediate effect. */
- i_cached_listeners = vlc_array_count(&listeners_group->listeners);
- array_listeners_cached = malloc(sizeof(libvlc_event_listener_t)*(i_cached_listeners));
- if( !array_listeners_cached )
- {
- vlc_mutex_unlock(&p_em->lock);
- fprintf(stderr, "Can't alloc memory in libvlc_event_send" );
- return;
- }
-
- listener_cached = array_listeners_cached;
- for( i = 0; i < vlc_array_count(&listeners_group->listeners); i++)
- {
- listener = vlc_array_item_at_index(&listeners_group->listeners, i);
- memcpy( listener_cached, listener, sizeof(libvlc_event_listener_t) );
- listener_cached++;
- }
- break;
- }
- }
-
- if( !listeners_group )
- {
- vlc_mutex_unlock(&p_em->lock);
- free( array_listeners_cached );
- return;
- }
+ libvlc_event_listeners_group_t *listeners_group;
- /* 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;
-
- listener_cached = array_listeners_cached;
- for( i = 0; i < i_cached_listeners; i++ )
- {
- /* The listener wants to block the emitter during event callback */
- listener_cached->pf_callback( p_event, listener_cached->p_user_data );
- listener_cached++;
+ listeners_group = vlc_array_item_at_index(&p_em->listeners_groups, i);
+ if (listeners_group->event_type != p_event->type)
+ continue;
- if( listeners_group->b_sublistener_removed )
+ for (int j = 0; j < vlc_array_count(&listeners_group->listeners); j++)
{
- /* If a callback was removed, this gets called */
- bool valid_listener;
- valid_listener = group_contains_listener( listeners_group, listener_cached );
- if( !valid_listener )
- {
- listener_cached++;
- continue;
- }
+ libvlc_event_listener_t *listener;
+
+ listener = vlc_array_item_at_index(&listeners_group->listeners, j);
+ listener->pf_callback(p_event, listener->p_user_data);
}
+ break;
}
vlc_mutex_unlock(&p_em->lock);
-
- free( array_listeners_cached );
}
/*
@@ -462,11 +383,6 @@ void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
listener->p_user_data == p_user_data )
{
/* that's our listener */
-
- /* Mark this group as edited so that libvlc_event_send
- * will recheck what listener to call */
- listeners_group->b_sublistener_removed = true;
-
free( listener );
vlc_array_remove( &listeners_group->listeners, j );
found = true;
More information about the vlc-commits
mailing list