hythmbox-2.98/lib/rb-async-queue-watch.c

No issues found

  1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  2  *
  3  *  Copyright (C) 2007  Jonathan Matthew
  4  *
  5  *  This program is free software; you can redistribute it and/or modify
  6  *  it under the terms of the GNU General Public License as published by
  7  *  the Free Software Foundation; either version 2, or (at your option)
  8  *  any later version.
  9  *
 10  *  The Rhythmbox authors hereby grant permission for non-GPL compatible
 11  *  GStreamer plugins to be used and distributed together with GStreamer
 12  *  and Rhythmbox. This permission is above and beyond the permissions granted
 13  *  by the GPL license by which Rhythmbox is covered. If you modify this code
 14  *  you may extend this exception to your version of the code, but you are not
 15  *  obligated to do so. If you do not wish to do so, delete this exception
 16  *  statement from your version.
 17  *
 18  *  This program is distributed in the hope that it will be useful,
 19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 21  *  GNU General Public License for more details.
 22  *
 23  *  You should have received a copy of the GNU General Public License
 24  *  along with this program; if not, write to the Free Software
 25  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 26  *
 27  */
 28 
 29 #include "config.h"
 30 
 31 #include <rb-async-queue-watch.h>
 32 
 33 /**
 34  * SECTION:rb-async-queue-watch
 35  * @short_description: GSource for watching a GAsyncQueue in the main loop
 36  *
 37  * This provides a way to feed work items to the main loop using a #GAsyncQueue
 38  * without polling it.
 39  */
 40 
 41 /**
 42  * RBAsyncQueueWatchFunc:
 43  * @item: the item found in the queue
 44  * @data: user data specified when creating the watch
 45  *
 46  * Callback to call when an item is found in the queue.
 47  */
 48 
 49 typedef struct {
 50 	GSource source;
 51 	GAsyncQueue *queue;
 52 } RBAsyncQueueWatch;
 53 
 54 static gboolean
 55 rb_async_queue_watch_prepare (GSource *source, gint *timeout)
 56 {
 57 	RBAsyncQueueWatch *watch = (RBAsyncQueueWatch *)source;
 58 	*timeout = -1;
 59 	return (g_async_queue_length (watch->queue) > 0);
 60 }
 61 
 62 static gboolean
 63 rb_async_queue_watch_check (GSource *source)
 64 {
 65 	RBAsyncQueueWatch *watch = (RBAsyncQueueWatch *)source;
 66 	return (g_async_queue_length (watch->queue) > 0);
 67 }
 68 
 69 static gboolean
 70 rb_async_queue_watch_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
 71 {
 72 	RBAsyncQueueWatch *watch = (RBAsyncQueueWatch *)source;
 73 	RBAsyncQueueWatchFunc cb = (RBAsyncQueueWatchFunc)callback;
 74 	gpointer item;
 75 
 76 	item = g_async_queue_try_pop (watch->queue);
 77 	if (item == NULL) {
 78 		return TRUE;
 79 	}
 80 
 81 	if (cb == NULL) {
 82 		return FALSE;
 83 	}
 84 
 85 	cb (item, user_data);
 86 	return TRUE;
 87 }
 88 
 89 static void
 90 rb_async_queue_watch_finalize (GSource *source)
 91 {
 92 	RBAsyncQueueWatch *watch = (RBAsyncQueueWatch *)source;
 93 
 94 	if (watch->queue != NULL) {
 95 		g_async_queue_unref (watch->queue);
 96 		watch->queue = NULL;
 97 	}
 98 }
 99 
100 static GSourceFuncs rb_async_queue_watch_funcs = {
101 	rb_async_queue_watch_prepare,
102 	rb_async_queue_watch_check,
103 	rb_async_queue_watch_dispatch,
104 	rb_async_queue_watch_finalize
105 };
106 
107 /**
108  * rb_async_queue_watch_new:
109  * @queue:	the #GAsyncQueue to watch
110  * @priority:	priority value for the #GSource
111  * @callback:	callback to invoke when the queue is non-empty
112  * @user_data:	user data to pass to the callback
113  * @notify:	function to call to clean up the user data for the callback
114  * @context:	the #GMainContext to attach the source to
115  *
116  * Creates a new #GSource that triggers when the #GAsyncQueue is
117  * non-empty.  This is used in rhythmbox to process queues within
118  * #RhythmDB in the main thread without polling.
119  *
120  * Return value: the ID of the new #GSource
121  */
122 guint rb_async_queue_watch_new (GAsyncQueue *queue,
123 				gint priority,
124 				RBAsyncQueueWatchFunc callback,
125 				gpointer user_data,
126 				GDestroyNotify notify,
127 				GMainContext *context)
128 {
129 	GSource *source;
130 	RBAsyncQueueWatch *watch;
131 	guint id;
132 
133 	source = (GSource *) g_source_new (&rb_async_queue_watch_funcs,
134 					   sizeof (RBAsyncQueueWatch));
135 
136 	watch = (RBAsyncQueueWatch *)source;
137 	watch->queue = g_async_queue_ref (queue);
138 
139 	if (priority != G_PRIORITY_DEFAULT)
140 		g_source_set_priority (source, priority);
141 
142 	g_source_set_callback (source, (GSourceFunc) callback, user_data, notify);
143 
144 	id = g_source_attach (source, context);
145 	g_source_unref (source);
146 	return id;
147 }