]> git.sesse.net Git - vlc/blobdiff - src/control/event_async.c
Use var_Inherit* instead of var_CreateGet*.
[vlc] / src / control / event_async.c
index ecb6fa8890e8259c0b9fa94dcc3c1f71efd9b322..5dce2a3231b203376c18a9be88ea7ecedb3bb953 100644 (file)
@@ -17,9 +17,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU 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 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.
  *****************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -40,13 +40,16 @@ struct queue_elmt {
 };
 
 struct libvlc_event_async_queue {
-    struct queue_elmt * elements;
+    struct queue_elmt *first_elmt, *last_elmt;
     vlc_mutex_t lock;
     vlc_cond_t signal;
     vlc_thread_t thread;
     bool is_idle;
     vlc_cond_t signal_idle;
     vlc_threadvar_t is_asynch_dispatch_thread_var;
+#ifndef NDEBUG
+    long count;
+#endif
 };
 
 /*
@@ -67,41 +70,34 @@ static inline bool is_queue_initialized(libvlc_event_manager_t * p_em)
 
 static inline bool current_thread_is_asynch_thread(libvlc_event_manager_t * p_em)
 {
-    return vlc_threadvar_get(queue(p_em)->is_asynch_dispatch_thread_var);
+    return vlc_threadvar_get(queue(p_em)->is_asynch_dispatch_thread_var)
+            != NULL;
 }
 
 /* Lock must be held */
-static void push(libvlc_event_manager_t * p_em, libvlc_event_listener_t * listener, libvlc_event_t * event)
+static void push(libvlc_event_manager_t * p_em,
+                 libvlc_event_listener_t * listener, libvlc_event_t * event)
 {
-#ifndef NDEBUG
-    static const long MaxQueuedItem = 300000;
-    long count = 0;
-#endif
-
     struct queue_elmt * elmt = malloc(sizeof(struct queue_elmt));
     elmt->listener = *listener;
     elmt->event = *event;
     elmt->next = NULL;
 
     /* Append to the end of the queue */
-    struct queue_elmt * iter = queue(p_em)->elements;
-    if(!iter)
-    {
-        queue(p_em)->elements = elmt;
-        return;
-    }
+    if(!queue(p_em)->first_elmt)
+        queue(p_em)->first_elmt = elmt;
+    else
+        queue(p_em)->last_elmt->next = elmt;
+    queue(p_em)->last_elmt = elmt;
 
-    while (iter->next) {
-        iter = iter->next;
 #ifndef NDEBUG
-        if(count++ > MaxQueuedItem)
-        {
-            fprintf(stderr, "Warning: libvlc event overflow.\n");
-            abort();
-        }
-#endif
+    enum { MaxQueueSize = 300000 };
+    if(queue(p_em)->count++ > MaxQueueSize)
+    {
+        fprintf(stderr, "Warning: libvlc event overflow.\n");
+        abort();
     }
-    iter->next = elmt;
+#endif
 }
 
 static inline void queue_lock(libvlc_event_manager_t * p_em)
@@ -115,16 +111,23 @@ static inline void queue_unlock(libvlc_event_manager_t * p_em)
 }
 
 /* Lock must be held */
-static bool pop(libvlc_event_manager_t * p_em, libvlc_event_listener_t * listener, libvlc_event_t * event)
+static bool pop(libvlc_event_manager_t * p_em,
+                libvlc_event_listener_t * listener, libvlc_event_t * event)
 {
-    if(!queue(p_em)->elements)
-        return false; /* No elements */
+    if(!queue(p_em)->first_elmt)
+        return false; /* No first_elmt */
+
+    struct queue_elmt * elmt = queue(p_em)->first_elmt;
+    *listener = elmt->listener;
+    *event = elmt->event;
 
-    *listener = queue(p_em)->elements->listener;
-    *event = queue(p_em)->elements->event;
+    queue(p_em)->first_elmt = elmt->next;
+    if( !elmt->next ) queue(p_em)->last_elmt=NULL;
+
+#ifndef NDEBUG
+    queue(p_em)->count--;
+#endif
 
-    struct queue_elmt * elmt = queue(p_em)->elements;
-    queue(p_em)->elements = elmt->next;
     free(elmt);
     return true;
 }
@@ -132,24 +135,28 @@ static bool pop(libvlc_event_manager_t * p_em, libvlc_event_listener_t * listene
 /* Lock must be held */
 static void pop_listener(libvlc_event_manager_t * p_em, libvlc_event_listener_t * listener)
 {
-    struct queue_elmt * iter = queue(p_em)->elements;
+    struct queue_elmt * iter = queue(p_em)->first_elmt;
     struct queue_elmt * prev = NULL;
     while (iter) {
         if(listeners_are_equal(&iter->listener, listener))
         {
             struct queue_elmt * to_delete = iter;
             if(!prev)
-                queue(p_em)->elements = to_delete->next;
+                queue(p_em)->first_elmt = to_delete->next;
             else
                 prev->next = to_delete->next;
             iter = to_delete->next;
             free(to_delete);
+#ifndef NDEBUG
+            queue(p_em)->count--;
+#endif
         }
         else {
             prev = iter;
             iter = iter->next;
         }
     }
+    queue(p_em)->last_elmt=prev;
 }
 
 /**************************************************************************
@@ -180,7 +187,7 @@ libvlc_event_async_fini(libvlc_event_manager_t * p_em)
     vlc_cond_destroy(&queue(p_em)->signal_idle);
     vlc_threadvar_delete(&queue(p_em)->is_asynch_dispatch_thread_var);
 
-    struct queue_elmt * iter = queue(p_em)->elements;
+    struct queue_elmt * iter = queue(p_em)->first_elmt;
     while (iter) {
         struct queue_elmt * elemt_to_delete = iter;
         iter = iter->next;