gstdataqueue: Only emit g_cond_signal when needed
authorEdward Hervey <bilboed@bilboed.com>
Wed, 13 Oct 2010 11:50:22 +0000 (13:50 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Thu, 2 Dec 2010 18:04:55 +0000 (19:04 +0100)
Keep track of which cond we're waiting for and only emit when needed.

https://bugzilla.gnome.org/show_bug.cgi?id=632779

libs/gst/base/gstdataqueue.c
libs/gst/base/gstdataqueue.h

index 3741291..69dadb4 100644 (file)
@@ -277,7 +277,8 @@ gst_data_queue_locked_flush (GstDataQueue * queue)
   gst_data_queue_cleanup (queue);
   STATUS (queue, "after flushing");
   /* we deleted something... */
-  g_cond_signal (queue->item_del);
+  if (queue->waiting_del)
+    g_cond_signal (queue->item_del);
 }
 
 static inline gboolean
@@ -383,8 +384,10 @@ gst_data_queue_set_flushing (GstDataQueue * queue, gboolean flushing)
   queue->flushing = flushing;
   if (flushing) {
     /* release push/pop functions */
-    g_cond_signal (queue->item_add);
-    g_cond_signal (queue->item_del);
+    if (queue->waiting_add)
+      g_cond_signal (queue->item_add);
+    if (queue->waiting_del)
+      g_cond_signal (queue->item_del);
   }
   GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
 }
@@ -429,7 +432,9 @@ gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item)
 
     /* signal might have removed some items */
     while (gst_data_queue_locked_is_full (queue)) {
+      queue->waiting_del = TRUE;
       g_cond_wait (queue->item_del, queue->qlock);
+      queue->waiting_del = FALSE;
       if (queue->flushing)
         goto flushing;
     }
@@ -443,7 +448,8 @@ gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item)
   queue->cur_level.time += item->duration;
 
   STATUS (queue, "after pushing");
-  g_cond_signal (queue->item_add);
+  if (queue->waiting_add)
+    g_cond_signal (queue->item_add);
 
   GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
 
@@ -491,7 +497,9 @@ gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item)
     GST_DATA_QUEUE_MUTEX_LOCK_CHECK (queue, flushing);
 
     while (gst_data_queue_locked_is_empty (queue)) {
+      queue->waiting_add = TRUE;
       g_cond_wait (queue->item_add, queue->qlock);
+      queue->waiting_add = FALSE;
       if (queue->flushing)
         goto flushing;
     }
@@ -507,7 +515,8 @@ gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item)
   queue->cur_level.time -= (*item)->duration;
 
   STATUS (queue, "after popping");
-  g_cond_signal (queue->item_del);
+  if (queue->waiting_del)
+    g_cond_signal (queue->item_del);
 
   GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
 
@@ -591,8 +600,10 @@ gst_data_queue_limits_changed (GstDataQueue * queue)
   g_return_if_fail (GST_IS_DATA_QUEUE (queue));
 
   GST_DATA_QUEUE_MUTEX_LOCK (queue);
-  GST_DEBUG ("signal del");
-  g_cond_signal (queue->item_del);
+  if (queue->waiting_del) {
+    GST_DEBUG ("signal del");
+    g_cond_signal (queue->item_del);
+  }
   GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
 }
 
index d07dfa8..d6cde4b 100644 (file)
@@ -128,13 +128,16 @@ struct _GstDataQueue
   gpointer *checkdata;
 
   GMutex *qlock;                /* lock for queue (vs object lock) */
+  gboolean waiting_add;
   GCond *item_add;              /* signals buffers now available for reading */
+  gboolean waiting_del;
   GCond *item_del;              /* signals space now available for writing */
   gboolean flushing;            /* indicates whether conditions where signalled because
                                  * of external flushing */
   GstDataQueueFullCallback fullcallback;
   GstDataQueueEmptyCallback emptycallback;
-  gpointer _gst_reserved[GST_PADDING - 2];
+
+  gpointer _gst_reserved[GST_PADDING - 4];
 };
 
 struct _GstDataQueueClass