diff -r 000000000000 -r d0f3a028347a loudmouth/src/lm-message-queue.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/loudmouth/src/lm-message-queue.c Tue Feb 02 01:10:06 2010 +0200 @@ -0,0 +1,234 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2006 Imendio AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include "lm-message-queue.h" +#include "lm-debug.h" + +struct _LmMessageQueue { + GQueue *messages; + + GMainContext *context; + GSource *source; + + LmMessageQueueCallback callback; + gpointer user_data; + + gint ref_count; +}; + +typedef struct { + GSource source; + LmMessageQueue *queue; +} MessageQueueSource; + +static void message_queue_free (LmMessageQueue *queue); +static gboolean message_queue_prepare_func (GSource *source, + gint *timeout); +static gboolean message_queue_check_func (GSource *source); +static gboolean message_queue_dispatch_func (GSource *source, + GSourceFunc callback, + gpointer user_data); + +static GSourceFuncs source_funcs = { + message_queue_prepare_func, + message_queue_check_func, + message_queue_dispatch_func, + NULL +}; + +static void +foreach_free_message (LmMessage *m, gpointer user_data) +{ + lm_message_unref (m); + UNUSED_FORMAL_PARAM(user_data); +} + +static void +message_queue_free (LmMessageQueue *queue) +{ + lm_message_queue_detach (queue); + + g_queue_foreach (queue->messages, (GFunc) foreach_free_message, NULL); + g_queue_free (queue->messages); + + g_free (queue); +} + +//Prepare has to return true for check method to be called. +static gboolean +message_queue_prepare_func (GSource *source, gint *timeout) +{ + LmMessageQueue *queue; + + queue = ((MessageQueueSource *)source)->queue; + UNUSED_FORMAL_PARAM(timeout); + return !g_queue_is_empty (queue->messages); +} + +//check has to return true for Dispatch method to be called. +static gboolean +message_queue_check_func (GSource *source) +{ +// return FALSE; +UNUSED_FORMAL_PARAM(source); +return TRUE; +} + +static gboolean +message_queue_dispatch_func (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + LmMessageQueue *queue; + + queue = ((MessageQueueSource *)source)->queue; + + if (queue->callback) { + (queue->callback) (queue, queue->user_data); + } + UNUSED_FORMAL_PARAM(source); + UNUSED_FORMAL_PARAM(callback); + return TRUE; +} + +LmMessageQueue * +lm_message_queue_new (LmMessageQueueCallback callback, + gpointer user_data) +{ + LmMessageQueue *queue; + + queue = g_new0 (LmMessageQueue, 1); + + queue->messages = g_queue_new (); + queue->context = NULL; + queue->source = NULL; + queue->ref_count = 1; + + queue->callback = callback; + queue->user_data = user_data; + + return queue; +} + +void +lm_message_queue_attach (LmMessageQueue *queue, GMainContext *context) +{ + GSource *source; + + if (queue->source) { + if (queue->context == context) { + /* Already attached */ + return; + } + lm_message_queue_detach (queue); + } + + if (context) { + queue->context = g_main_context_ref (context); + } + + source = g_source_new (&source_funcs, sizeof (MessageQueueSource)); + ((MessageQueueSource *)source)->queue = queue; + queue->source = source; + + g_source_attach (source, queue->context); +} + +void +lm_message_queue_detach (LmMessageQueue *queue) +{ + if (queue->source) { + g_source_destroy (queue->source); + g_source_unref (queue->source); + } + + if (queue->context) { + g_main_context_unref (queue->context); + } + + queue->source = NULL; + queue->context = NULL; +} + +void +lm_message_queue_push_tail (LmMessageQueue *queue, LmMessage *m) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (m != NULL); + + g_queue_push_tail (queue->messages, m); +} + +LmMessage * +lm_message_queue_peek_nth (LmMessageQueue *queue, guint n) +{ + g_return_val_if_fail (queue != NULL, NULL); + + return (LmMessage *) g_queue_peek_nth (queue->messages, n); +} + +LmMessage * +lm_message_queue_pop_nth (LmMessageQueue *queue, guint n) +{ + g_return_val_if_fail (queue != NULL, NULL); + + return (LmMessage *) g_queue_pop_nth (queue->messages, n); +} + +guint +lm_message_queue_get_length (LmMessageQueue *queue) +{ + g_return_val_if_fail (queue != NULL, 0); + + return g_queue_get_length (queue->messages); +} + +gboolean +lm_message_queue_is_empty (LmMessageQueue *queue) +{ + g_return_val_if_fail (queue != NULL, TRUE); + + return g_queue_is_empty (queue->messages); +} + +LmMessageQueue * +lm_message_queue_ref (LmMessageQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + queue->ref_count++; + + return queue; +} + +void +lm_message_queue_unref (LmMessageQueue *queue) +{ + g_return_if_fail (queue != NULL); + + queue->ref_count--; + + if (queue->ref_count <= 0) { + message_queue_free (queue); + } +} +