diff options
-rw-r--r-- | camel/ChangeLog | 5 | ||||
-rw-r--r-- | camel/camel-op-queue.c | 166 | ||||
-rw-r--r-- | camel/camel-op-queue.h | 64 | ||||
-rw-r--r-- | camel/camel-thread-proxy.c | 514 | ||||
-rw-r--r-- | camel/camel-thread-proxy.h | 90 |
5 files changed, 5 insertions, 834 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 337a8be5c7..3af6acd80d 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,8 @@ +2000-10-23 Dan Winship <danw@helixcode.com> + + * camel-op-queue.[ch], camel-thread-proxy.[ch]: These should have + gone away a long time ago. + 2000-10-20 Chris Toshok <toshok@helixcode.com> * providers/Makefile.am (SUBDIRS): re-enable the nntp provider. diff --git a/camel/camel-op-queue.c b/camel/camel-op-queue.c deleted file mode 100644 index 3e17222f0a..0000000000 --- a/camel/camel-op-queue.c +++ /dev/null @@ -1,166 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU 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 - */ - - -/* MT safe */ - - -#include <config.h> -#include "camel-op-queue.h" - -static GStaticMutex op_queue_mutex = G_STATIC_MUTEX_INIT; - - - -/** - * camel_op_queue_new: create a new operation queue - * - * Create a new operation queue. - * - * Return value: the newly allcated object - **/ -CamelOpQueue * -camel_op_queue_new () -{ - CamelOpQueue *op_queue; - - op_queue = g_new (CamelOpQueue, 1); - op_queue->ops_tail = NULL; - op_queue->ops_head = NULL; - op_queue->service_available = TRUE; - - return op_queue; -} - - -void -camel_op_queue_free (CamelOpQueue *op_queue) -{ - g_list_free (op_queue->ops_head); - g_free (op_queue); -} - -/** - * camel_op_queue_push_op: Add an operation to the queue - * @queue: queue object - * @op: operation to add - * - * Add an operation to an operation queue. - * The queue is a FIFO queue. - **/ -void -camel_op_queue_push_op (CamelOpQueue *queue, CamelOp *op) -{ - g_assert (queue); - g_static_mutex_lock (&op_queue_mutex); - if (!queue->ops_tail) { - queue->ops_head = g_list_prepend (NULL, op); - queue->ops_tail = queue->ops_head; - } else - queue->ops_head = g_list_prepend (queue->ops_head, op); - g_static_mutex_unlock (&op_queue_mutex); -} - - -/** - * camel_op_queue_pop_op: Pop the next operation pending in the queue - * @queue: queue object - * - * Pop the next operation pending in the queue. - * - * Return value: - **/ -CamelOp * -camel_op_queue_pop_op (CamelOpQueue *queue) -{ - GList *op_list; - CamelOp *op; - - g_assert (queue); - - g_static_mutex_lock (&op_queue_mutex); - op_list = queue->ops_tail; - if (!op_list) return NULL; - - queue->ops_tail = queue->ops_tail->prev; - op = (CamelOp *)op_list->data; - g_static_mutex_unlock (&op_queue_mutex); - - return op; -} - - -/** - * camel_op_queue_run_next_op: run the next pending operation - * @queue: queue object - * - * Run the next pending operation in the queue. - * - * Return value: TRUE if an operation was launched FALSE if there was no operation pending in the queue. - **/ -gboolean -camel_op_queue_run_next_op (CamelOpQueue *queue) -{ - CamelOp *op; - - op = camel_op_queue_pop_op (queue); - if (!op) return FALSE; - - return FALSE; -} - -/** - * camel_op_queue_set_service_availability: set the service availability for an operation queue - * @queue: queue object - * @available: availability flag - * - * set the service availability - **/ -void -camel_op_queue_set_service_availability (CamelOpQueue *queue, gboolean available) -{ - g_static_mutex_lock (&op_queue_mutex); - queue->service_available = available; - g_static_mutex_unlock (&op_queue_mutex); -} - -/** - * camel_op_queue_get_service_availability: determine if an operation queue service is available - * @queue: queue object - * - * Determine if the service associated to an operation queue is available. - * - * Return value: service availability. - **/ -gboolean -camel_op_queue_get_service_availability (CamelOpQueue *queue) -{ - gboolean available; - - g_static_mutex_lock (&op_queue_mutex); - available = queue->service_available; - g_static_mutex_unlock (&op_queue_mutex); - return available; -} - diff --git a/camel/camel-op-queue.h b/camel/camel-op-queue.h deleted file mode 100644 index 49fdc152d3..0000000000 --- a/camel/camel-op-queue.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU 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 - */ - - -#ifndef CAMEL_OP_QUEUE_H -#define CAMEL_OP_QUEUE_H 1 - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <glib.h> -#include <camel/camel-marshal-utils.h> - - - -typedef struct -{ - GList *ops_head; - GList *ops_tail; - gboolean service_available; - -} CamelOpQueue; - - -/* public methods */ -CamelOpQueue *camel_op_queue_new (); -void camel_op_queue_free (CamelOpQueue *op_queue); -void camel_op_queue_push_op (CamelOpQueue *queue, CamelOp *op); -CamelOp *camel_op_queue_pop_op (CamelOpQueue *queue); -gboolean camel_op_queue_run_next_op (CamelOpQueue *queue); -gboolean camel_op_queue_get_service_availability (CamelOpQueue *queue); -void camel_op_queue_set_service_availability (CamelOpQueue *queue, gboolean available); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_OP_QUEUE_H */ - diff --git a/camel/camel-thread-proxy.c b/camel/camel-thread-proxy.c deleted file mode 100644 index 9553499e8f..0000000000 --- a/camel/camel-thread-proxy.c +++ /dev/null @@ -1,514 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-folder-pt-proxy.c : proxy folder using posix threads */ - -/* - * - * Author : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU 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 <config.h> -#include "camel-marshal-utils.h" -#include "camel-thread-proxy.h" -#include <pthread.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - - - -/* vocabulary: - * operation: commanded by the main thread, executed by the child thread - * callback: commanded by the child thread, generally when an operation is - * completed. Executed in the main thread, - */ - -/* needed for proper casts of async funcs when - * calling pthreads_create - */ -typedef void * (*thread_call_func) (void *); - -/* forward declarations */ -static gboolean -_thread_notification_catch (GIOChannel *source, - GIOCondition condition, - gpointer data); - -static void -_notify_availability (CamelThreadProxy *proxy, gchar op_name); - -static int -_init_notify_system (CamelThreadProxy *proxy); - - - -/** - * camel_thread_proxy_new: create a new proxy object - * - * Create a new proxy object. This proxy object can be used - * to run async operations and this operations can trigger - * callbacks. It can also be used to proxy signals. - * - * Return value: The newly created proxy object - **/ -CamelThreadProxy * -camel_thread_proxy_new (void) -{ - CamelThreadProxy *proxy; - - proxy = g_new (CamelThreadProxy, 1); - if (!proxy) - return NULL; - - proxy->server_op_queue = camel_op_queue_new (); - proxy->client_op_queue = camel_op_queue_new (); - proxy->signal_data_cond = g_cond_new(); - proxy->signal_data_mutex = g_mutex_new(); - if (_init_notify_system (proxy) < 0) { - g_free (proxy); - return NULL; - } - return proxy; -} - - -/** - * camel_thread_proxy_free: free a proxy object - * @proxy: proxy object to free - * - * free a proxy object - **/ -void -camel_thread_proxy_free (CamelThreadProxy *proxy) -{ - g_cond_free (proxy->signal_data_cond); - g_mutex_free (proxy->signal_data_mutex); - camel_op_queue_free (proxy->server_op_queue); - camel_op_queue_free (proxy->client_op_queue); -} - - - - - -/* Operations handling */ - - -/** - * _op_run_free_notify: - * @folder: folder to notify when the operation is completed. - * @op: operation to run. - * - * run an operation, free the operation field - * and then notify the main thread of the op - * completion. - * - * this routine is intended to be called - * in a new thread (in _run_next_op_in_thread) - * - **/ -void -_op_run_free_and_notify (CamelOp *op) -{ - CamelThreadProxy *th_proxy; - - camel_op_run (op); - camel_op_free (op); - th_proxy = camel_op_get_user_data (op); - _notify_availability (th_proxy, 'a'); -} - - -/** - * _run_next_op_in_thread: - * @proxy_object: - * - * run the next operation pending in the proxy - * operation queue - **/ -static void -_run_next_op_in_thread (CamelThreadProxy *proxy) -{ - CamelOp *op; - CamelOpQueue *server_op_queue; - pthread_t thread; - - server_op_queue = proxy->server_op_queue; - /* get the next pending operation */ - op = camel_op_queue_pop_op (server_op_queue); - if (!op) { - camel_op_queue_set_service_availability (server_op_queue, TRUE); - return; - } - - /* run the operation in a child thread */ - pthread_create (&thread, NULL, (thread_call_func) _op_run_free_and_notify, op); -} - - - -/** - * camel_thread_proxy_push_op: push an operation in the proxy operation queue - * @proxy: proxy object - * @op: operation to push in the execution queue - * - * if no thread is currently running, executes the - * operation directly, otherwise push the operation - * in the proxy operation queue. - **/ -void -camel_thread_proxy_push_op (CamelThreadProxy *proxy, CamelOp *op) -{ - CamelOpQueue *server_op_queue; - - g_assert (proxy); - server_op_queue = proxy->server_op_queue; - - /* put the proxy object in the user data - so that it can be notified when the - operation is completed */ - camel_op_set_user_data (op, (gpointer)proxy); - - /* get next operation */ - camel_op_queue_push_op (server_op_queue, op); - - if (camel_op_queue_get_service_availability (server_op_queue)) { - /* no thread is currently running, run - * the next operation. */ - camel_op_queue_set_service_availability (server_op_queue, FALSE); - /* when the operation is completed in the - child thread the main thread gets - notified and executes next operation - (see _thread_notification_catch, case 'a') - so there is no need to set the service - availability to FALSE except here - */ - _run_next_op_in_thread (proxy); - } -} -/** - * _op_run_and_free: Run an operation and free it - * @op: Operation object - * - * Run an operation object in the current thread - * and free it. - **/ -static void -_op_run_and_free (CamelOp *op) -{ - camel_op_run (op); - camel_op_free (op); -} - - - - - - -/* Callbacks handling */ - -/** - * _run_next_cb: Run next callback pending in a proxy object - * @proxy: Proxy object - * - * Run next callback in the callback queue of a proxy object - **/ -static void -_run_next_cb (CamelThreadProxy *proxy) -{ - CamelOp *op; - CamelOpQueue *client_op_queue; - - client_op_queue = proxy->client_op_queue; - - /* get the next pending operation */ - op = camel_op_queue_pop_op (client_op_queue); - if (!op) return; - - /* run the operation in the main thread */ - _op_run_and_free (op); -} - - -/** - * camel_thread_proxy_push_cb: push a callback in the client queue - * @proxy: proxy object concerned by the callback - * @cb: callback to push - * - * Push an operation in the client queue, ie the queue - * containing the operations (callbacks) intended to be - * executed in the main thread. - **/ -void -camel_thread_proxy_push_cb (CamelThreadProxy *proxy, CamelOp *cb) -{ - CamelOpQueue *client_op_queue; - - client_op_queue = proxy->client_op_queue; - - /* put the proxy object in the user data - so that it can be notified when the - operation is completed */ - camel_op_set_user_data (cb, (gpointer)proxy); - - /* push the callback in the client queue */ - camel_op_queue_push_op (client_op_queue, cb); - - /* tell the main thread a new callback is there */ - _notify_availability (proxy, 'c'); -} - - - -/** - * _init_notify_system: set the notify channel up - * @proxy: proxy object - * - * called once to set the notification channel up - **/ -static int -_init_notify_system (CamelThreadProxy *proxy) -{ - int filedes[2]; - - /* set up the notification channel */ - if (pipe (filedes) < 0) { - g_warning ("could not create pipe in " - "CamelThreadProxy::_init_notify_system\n"); - return -1; - } - - - proxy->pipe_client_fd = filedes [0]; - proxy->pipe_server_fd = filedes [1]; - proxy->notify_source = g_io_channel_unix_new (filedes [0]); - proxy->notify_channel = g_io_channel_unix_new (filedes [1]); - - /* the _thread_notification_catch function - * will be called in the main thread when the - * child thread writes some data in the channel */ - g_io_add_watch (proxy->notify_source, G_IO_IN, - _thread_notification_catch, - proxy); - - return 1; -} - -/** - * _notify_availability: notify the main thread from an event - * @proxy: proxy object - * @op_name: operation name - * - * called by child thread to notify the main - * thread something is available for him. - * What this thing is depends on @op_name: - * - * 'a' : thread available. That means the thread is ready - * to process an operation. - * 's' : a signal is available. Used by the signal proxy. - * - */ -static void -_notify_availability (CamelThreadProxy *proxy, gchar op_name) -{ - GIOChannel *notification_channel; - guint bytes_written; - - notification_channel = proxy->notify_channel; - - do { - /* the write operation will trigger the - * watch on the main thread side */ - g_io_channel_write (notification_channel, - &op_name, - 1, - &bytes_written); - } while (bytes_written < 1); -} - - - -/* signal proxying */ - - - -/** - * _signal_marshaller_server_side: called in the child thread to proxy a signal - * @object: - * @data: - * @n_args: - * @args: - * - * - **/ -static void -_signal_marshaller_server_side (GtkObject *object, - gpointer data, - guint n_args, - GtkArg *args) -{ - CamelThreadProxy *proxy; - guint signal_id; - - proxy = CAMEL_THREAD_PROXY (gtk_object_get_data (object, "__proxy__")); - signal_id = (guint)data; - g_assert (proxy); - - g_mutex_lock (proxy->signal_data_mutex); - - /* we are going to wait for the main client thread - * to have emitted the last signal we asked him - * to proxy. - */ - while (proxy->signal_data.args) - g_cond_wait (proxy->signal_data_cond, - proxy->signal_data_mutex); - - proxy->signal_data.signal_id = signal_id; - proxy->signal_data.args = args; - - - g_mutex_unlock (proxy->signal_data_mutex); - - /* tell the main thread there is a signal pending */ - _notify_availability (proxy, 's'); -} - - -static void -_signal_marshaller_client_side (CamelThreadProxy *proxy) -{ - g_mutex_lock (proxy->signal_data_mutex); - g_assert (proxy->signal_data.args); - - /* emit the pending signal */ - gtk_signal_emitv (GTK_OBJECT (proxy), - proxy->signal_data.signal_id, - proxy->signal_data.args); - - proxy->signal_data.args = NULL; - - /* if waiting for the signal to be treated, - * awake the client thread up - */ - g_cond_signal (proxy->signal_data_cond); - g_mutex_unlock (proxy->signal_data_mutex); -} - - -/** - * camel_thread_proxy_add_signals: init the signal proxy - * @proxy: proxy - * @proxy_object: Proxy Gtk Object - * @real_object: Real Gtk Object - * @signal_to_proxy: NULL terminated array of signal name - * - * Add some signals to the list of signals to be - * proxied by the proxy object. - * The signals emitted by the real object in the child - * thread are reemited by the proxy object in the - * main thread. - **/ -void -camel_thread_proxy_add_signals (CamelThreadProxy *proxy, - GtkObject *proxy_object, - GtkObject *real_object, - char *signal_to_proxy[]) -{ - guint i; - - for (i=0; signal_to_proxy[i]; i++) { - /* connect the signal to the signal marshaller - * user_data is the signal id */ - gtk_signal_connect_full (GTK_OBJECT (real_object), - signal_to_proxy[i], - NULL, - _signal_marshaller_server_side, - (gpointer)gtk_signal_lookup (signal_to_proxy[i], - GTK_OBJECT_CLASS (real_object)->type), - NULL, - TRUE, - FALSE); - } -} - -/**** catch notification from child thread ****/ -/** - * _thread_notification_catch: call by glib loop when data is available on the thread io channel - * @source: - * @condition: - * @data: - * - * called by watch set on the IO channel - * - * Return value: TRUE because we don't want the watch to be removed - **/ -static gboolean -_thread_notification_catch (GIOChannel *source, - GIOCondition condition, - gpointer data) -{ - CamelThreadProxy *proxy = CAMEL_THREAD_PROXY (data); - gchar op_name; - guint bytes_read; - GIOError error; - - error = g_io_channel_read (source, - &op_name, - 1, - &bytes_read); - - while ((!error) && (bytes_read == 1)) { - - switch (op_name) { - case 'a': /* the thread is OK for a new operation */ - _run_next_op_in_thread (proxy); - break; - case 's': /* there is a pending signal to proxy */ - _signal_marshaller_client_side (proxy); - break; - case 'c': /* there is a cb pending in the main thread */ - _run_next_cb (proxy); - break; - } - - error = g_io_channel_read (source, - &op_name, - 1, - &bytes_read); - - } - - /* do not remove the io watch */ - return TRUE; -} - - - - - - - - - - - diff --git a/camel/camel-thread-proxy.h b/camel/camel-thread-proxy.h deleted file mode 100644 index 050d8ed598..0000000000 --- a/camel/camel-thread-proxy.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-folder-pt-proxy.h : proxy folder using posix threads */ - -/* - * - * Author : - * Bertrand Guiheneuf <bertrand@helixcode.com> - * - * Copyright 1999, 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU 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 - */ - - - - - -#ifndef CAMEL_THREAD_PROXY_H -#define CAMEL_THREAD_PROXY_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <camel/camel-op-queue.h> - -#define CAMEL_THREAD_PROXY(o) (CamelThreadProxy *)(o) - - -typedef struct { - guint signal_id; - GtkArg *args; -} CamelThreadProxySignalData; - - -typedef struct { - - GtkObject *real_object; - GtkObject *proxy_object; - - CamelOpQueue *server_op_queue; - CamelOpQueue *client_op_queue; - - - gint pipe_client_fd; - gint pipe_server_fd; - GIOChannel *notify_source; - GIOChannel *notify_channel; - - /* signal proxy */ - GMutex *signal_data_mutex; - GCond *signal_data_cond; - CamelThreadProxySignalData signal_data; - -} CamelThreadProxy; - - -CamelThreadProxy *camel_thread_proxy_new (void); -void camel_thread_proxy_free (CamelThreadProxy *proxy); - -void camel_thread_proxy_push_op (CamelThreadProxy *proxy, CamelOp *op); -void camel_thread_proxy_push_cb (CamelThreadProxy *proxy, CamelOp *cb); - -void camel_thread_proxy_add_signals (CamelThreadProxy *proxy, - GtkObject *proxy_object, - GtkObject *real_object, - char *signal_to_proxy[]); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_THREAD_PROXY_H */ - - |