dataqueue: add gst_data_queue_peek

This function works just like gst_data_queue_pop, but it doesn't
remove the object from the queue.

Useful when inspecting multiple GstDataQueues to decide from which
to pop the element from.

Add: gst_data_queue_peek
This commit is contained in:
Thiago Santos 2013-01-15 16:57:20 -03:00
parent c7a8318452
commit 1681a1b1e0
3 changed files with 74 additions and 7 deletions

View file

@ -484,6 +484,21 @@ flushing:
}
}
static gboolean
_gst_data_queue_wait_non_empty (GstDataQueue * queue)
{
GstDataQueuePrivate *priv = queue->priv;
while (gst_data_queue_locked_is_empty (queue)) {
priv->waiting_add = TRUE;
g_cond_wait (&priv->item_add, &priv->qlock);
priv->waiting_add = FALSE;
if (priv->flushing)
return FALSE;
}
return TRUE;
}
/**
* gst_data_queue_pop:
* @queue: a #GstDataQueue.
@ -518,13 +533,8 @@ gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item)
g_signal_emit (queue, gst_data_queue_signals[SIGNAL_EMPTY], 0);
GST_DATA_QUEUE_MUTEX_LOCK_CHECK (queue, flushing);
while (gst_data_queue_locked_is_empty (queue)) {
priv->waiting_add = TRUE;
g_cond_wait (&priv->item_add, &priv->qlock);
priv->waiting_add = FALSE;
if (priv->flushing)
goto flushing;
}
if (!_gst_data_queue_wait_non_empty (queue))
goto flushing;
}
/* Get the item from the GQueue */
@ -559,6 +569,61 @@ is_of_type (gconstpointer a, gconstpointer b)
return !G_TYPE_CHECK_INSTANCE_TYPE (a, GPOINTER_TO_SIZE (b));
}
/**
* gst_data_queue_peek:
* @queue: a #GstDataQueue.
* @item: pointer to store the returned #GstDataQueueItem.
*
* Retrieves the first @item available on the @queue without removing it.
* If the queue is currently empty, the call will block until at least
* one item is available, OR the @queue is set to the flushing state.
* MT safe.
*
* Returns: #TRUE if an @item was successfully retrieved from the @queue.
*
* Since: 1.2.0
*/
gboolean
gst_data_queue_peek (GstDataQueue * queue, GstDataQueueItem ** item)
{
GstDataQueuePrivate *priv = queue->priv;
g_return_val_if_fail (GST_IS_DATA_QUEUE (queue), FALSE);
g_return_val_if_fail (item != NULL, FALSE);
GST_DATA_QUEUE_MUTEX_LOCK_CHECK (queue, flushing);
STATUS (queue, "before peeking");
if (gst_data_queue_locked_is_empty (queue)) {
GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
if (G_LIKELY (priv->emptycallback))
priv->emptycallback (queue, priv->checkdata);
else
g_signal_emit (queue, gst_data_queue_signals[SIGNAL_EMPTY], 0);
GST_DATA_QUEUE_MUTEX_LOCK_CHECK (queue, flushing);
if (!_gst_data_queue_wait_non_empty (queue))
goto flushing;
}
/* Get the item from the GQueue */
*item = gst_queue_array_peek_head (priv->queue);
STATUS (queue, "after peeking");
GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
return TRUE;
/* ERRORS */
flushing:
{
GST_DEBUG ("queue:%p, we are flushing", queue);
GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
return FALSE;
}
}
/**
* gst_data_queue_drop_head:
* @queue: The #GstDataQueue to drop an item from.

View file

@ -141,6 +141,7 @@ GstDataQueue * gst_data_queue_new (GstDataQueueCheckFullFunction chec
gboolean gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item);
gboolean gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item);
gboolean gst_data_queue_peek (GstDataQueue * queue, GstDataQueueItem ** item);
void gst_data_queue_flush (GstDataQueue * queue);

View file

@ -252,6 +252,7 @@ EXPORTS
gst_data_queue_is_full
gst_data_queue_limits_changed
gst_data_queue_new
gst_data_queue_peek
gst_data_queue_pop
gst_data_queue_push
gst_data_queue_set_flushing