From 905fea098fa9e9ac5afe3c5389279a54f0e62c45 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 16 Feb 2011 16:19:46 +0100 Subject: [PATCH] atomicqueue: add refcounting and docs --- docs/gst/gstreamer-docs.sgml | 1 + docs/gst/gstreamer-sections.txt | 16 ++++++ gst/gstatomicqueue.c | 96 +++++++++++++++++++++++++++++++++ gst/gstatomicqueue.h | 15 ++++-- 4 files changed, 125 insertions(+), 3 deletions(-) diff --git a/docs/gst/gstreamer-docs.sgml b/docs/gst/gstreamer-docs.sgml index b961835ccb..ca969a141a 100644 --- a/docs/gst/gstreamer-docs.sgml +++ b/docs/gst/gstreamer-docs.sgml @@ -57,6 +57,7 @@ Windows. It is released under the GNU Library General Public License + diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index d6f9ec375c..4787245f5c 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -38,6 +38,22 @@ GstPluginLoader GstPluginLoaderFuncs +
+gstatomicqueue +GstAtomicQueue +GstAtomicQueue +gst_atomic_queue_new + +gst_atomic_queue_ref +gst_atomic_queue_unref + +gst_atomic_queue_push +gst_atomic_queue_peek +gst_atomic_queue_pop + +gst_atomic_queue_length +
+
gstbin GstBin diff --git a/gst/gstatomicqueue.c b/gst/gstatomicqueue.c index b7fa67dad2..c417b23023 100644 --- a/gst/gstatomicqueue.c +++ b/gst/gstatomicqueue.c @@ -21,9 +21,23 @@ */ #include + +#include "gst_private.h" + #include #include "gstatomicqueue.h" +/** + * SECTION:gstatomicqueue + * @title: GstAtomicQueue + * @short_description: An atomic queue implementation + * + * The #GstAtomicQueue object implements a queue that can be used from multiple + * threads without performing any blocking operations. + * + * Since: 0.10.33 + */ + /* By default the queue uses 2 * sizeof(gpointer) * clp2 (max_items) of * memory. clp2(x) is the next power of two >= than x. * @@ -84,6 +98,7 @@ free_queue_mem (GstAQueueMem * mem) struct _GstAtomicQueue { + volatile gint refcount; #ifdef LOW_MEM gint num_readers; #endif @@ -123,6 +138,17 @@ clear_free_list (GstAtomicQueue * queue) } } +/** + * gst_atomic_queue_new: + * @initial_size: initial queue size + * + * Create a new atomic queue instance. @initial_size will be rounded up to the + * nearest power of 2 and used as the initial size of the queue. + * + * Returns: a new #GstAtomicQueue + * + * Since: 0.10.33 + */ GstAtomicQueue * gst_atomic_queue_new (guint initial_size) { @@ -130,6 +156,7 @@ gst_atomic_queue_new (guint initial_size) queue = g_new (GstAtomicQueue, 1); + queue->refcount = 1; #ifdef LOW_MEM queue->num_readers = 0; #endif @@ -139,7 +166,21 @@ gst_atomic_queue_new (guint initial_size) return queue; } +/** + * gst_atomic_queue_ref: + * @queue: a #GstAtomicQueue + * + * Increase the refcount of @queue. + */ void +gst_atomic_queue_ref (GstAtomicQueue * queue) +{ + g_return_if_fail (queue != NULL); + + g_atomic_int_inc (&queue->refcount); +} + +static void gst_atomic_queue_free (GstAtomicQueue * queue) { free_queue_mem (queue->head_mem); @@ -149,12 +190,37 @@ gst_atomic_queue_free (GstAtomicQueue * queue) g_free (queue); } +/** + * gst_atomic_queue_unref: + * @queue: a #GstAtomicQueue + * + * Unref @queue and free the memory when the refcount reaches 0. + */ +void +gst_atomic_queue_unref (GstAtomicQueue * queue) +{ + g_return_if_fail (queue != NULL); + + if (g_atomic_int_dec_and_test (&queue->refcount)) + gst_atomic_queue_free (queue); +} + +/** + * gst_atomic_queue_peek: + * @queue: a #GstAtomicQueue + * + * Peek the head element of the queue without removing it from the queue. + * + * Returns: the head element of @queue or NULL when the queue is empty. + */ gpointer gst_atomic_queue_peek (GstAtomicQueue * queue) { GstAQueueMem *head_mem; gint head, tail, size; + g_return_val_if_fail (queue != NULL, NULL); + while (TRUE) { GstAQueueMem *next; @@ -188,6 +254,14 @@ gst_atomic_queue_peek (GstAtomicQueue * queue) return head_mem->array[head & size]; } +/** + * gst_atomic_queue_pop: + * @queue: a #GstAtomicQueue + * + * Get the head element of the queue. + * + * Returns: the head element of @queue or NULL when the queue is empty. + */ gpointer gst_atomic_queue_pop (GstAtomicQueue * queue) { @@ -195,6 +269,8 @@ gst_atomic_queue_pop (GstAtomicQueue * queue) GstAQueueMem *head_mem; gint head, tail, size; + g_return_val_if_fail (queue != NULL, NULL); + #ifdef LOW_MEM g_atomic_int_inc (&queue->num_readers); #endif @@ -244,12 +320,21 @@ gst_atomic_queue_pop (GstAtomicQueue * queue) return ret; } +/** + * gst_atomic_queue_push: + * @queue: a #GstAtomicQueue + * @data: the data + * + * Append @data to the tail of the queue. + */ void gst_atomic_queue_push (GstAtomicQueue * queue, gpointer data) { GstAQueueMem *tail_mem; gint head, tail, size; + g_return_if_fail (queue != NULL); + do { while (TRUE) { GstAQueueMem *mem; @@ -286,12 +371,23 @@ gst_atomic_queue_push (GstAtomicQueue * queue, gpointer data) tail_mem->array[tail & size] = data; } +/** + * gst_atomic_queue_length: + * @queue: a #GstAtomicQueue + * @data: the data + * + * Get the amount of items in the queue. + * + * Returns: the number of elements in the queue. + */ guint gst_atomic_queue_length (GstAtomicQueue * queue) { GstAQueueMem *head_mem, *tail_mem; gint head, tail; + g_return_val_if_fail (queue != NULL, 0); + #ifdef LOW_MEM g_atomic_int_inc (&queue->num_readers); #endif diff --git a/gst/gstatomicqueue.h b/gst/gstatomicqueue.h index 98bac83e06..a501ca584b 100644 --- a/gst/gstatomicqueue.h +++ b/gst/gstatomicqueue.h @@ -25,12 +25,21 @@ #ifndef __GST_ATOMIC_QUEUE_H__ #define __GST_ATOMIC_QUEUE_H__ -typedef struct _GstAtomicQueue GstAtomicQueue; - G_BEGIN_DECLS +/** + * GstAtomicQueue: + * Opaque atomic data queue. + * + * Use the acessor functions to get the stored values. + */ +typedef struct _GstAtomicQueue GstAtomicQueue; + + GstAtomicQueue * gst_atomic_queue_new (guint initial_size); -void gst_atomic_queue_free (GstAtomicQueue * queue); + +void gst_atomic_queue_ref (GstAtomicQueue * queue); +void gst_atomic_queue_unref (GstAtomicQueue * queue); void gst_atomic_queue_push (GstAtomicQueue* queue, gpointer data); gpointer gst_atomic_queue_pop (GstAtomicQueue* queue);