gstdataqueue: Only emit g_cond_signal when needed

Keep track of which cond we're waiting for and only emit when needed.

https://bugzilla.gnome.org/show_bug.cgi?id=632779
This commit is contained in:
Edward Hervey 2010-10-13 13:50:22 +02:00
parent 8412c2a656
commit 7cc08390b9
2 changed files with 22 additions and 8 deletions

View 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);
}

View 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