[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