A lot of changes. The thread proxy mechanism
authorbertrand <Bertrand.Guiheneuf@aful.org>
Wed, 13 Oct 1999 21:16:54 +0000 (21:16 +0000)
committerBertrand Guiheneuf <bertrand@src.gnome.org>
Wed, 13 Oct 1999 21:16:54 +0000 (21:16 +0000)
is now functional. The signal proxy needs to be tested
though. The thread proxy folder is being implemented.
A rough summary :

1999-10-13  bertrand <Bertrand.Guiheneuf@aful.org>

* camel/camel-folder.c (camel_folder_close): the
folder->close method is now asynchronous.

* camel/camel-folder-pt-proxy.c (_folder_open_cb):
(_open):
(_folder_open_cb):
(_open):
open/close method implemented in the thread proxy
folder. More to come.

* camel/camel-exception.c (camel_exception_xfer):
new utility func.

* camel/camel-marshal-utils.c: some new marshallers

* camel/camel-folder-pt-proxy.c: Some explanations
on the thread proxy system.

1999-10-11  bertrand <Bertrand.Guiheneuf@aful.org>

* camel/camel-marshal-utils.c:
camel/camel-marshal-utils.h:
Handles operation marshalling.

* camel/camel-thread-proxy.c:
camel/camel-thread-proxy.h:
new files. Generic proxy system.

* camel/camel-folder-pt-proxy.c
moved all proxy related code in dedicated files.

(camel_folder_pt_proxy_init):
removed proxy initialisation code
(_finalize):
removed proxy finalization code

* camel/camel-exception.c
(camel_exception_new):
(camel_exception_set):
(camel_exception_free):
New funcs.

13 files changed:
camel/Makefile.am
camel/camel-exception.c
camel/camel-exception.h
camel/camel-folder-pt-proxy.c
camel/camel-folder-pt-proxy.h
camel/camel-folder.c
camel/camel-folder.h
camel/camel-marshal-utils.c
camel/camel-marshal-utils.h
camel/camel-op-queue.c
camel/camel-op-queue.h
camel/camel.c
camel/camel.h

index 474718d..b9316d1 100644 (file)
@@ -15,10 +15,12 @@ INCLUDES = -I.. -I$(srcdir)/.. -I$(includedir)      \
 if HAVE_PTHREAD
 
 pthread_SRC =  \
-       camel-folder-pt-proxy.c         
+       camel-folder-pt-proxy.c         \
+       camel-thread-proxy.c
 
 pthread_HDR =  \
-       camel-folder-pt-proxy.h         
+       camel-folder-pt-proxy.h                 \
+       camel-thread-proxy.h    
 
 else
 
index 4726194..8b8c70f 100644 (file)
 #include <config.h>
 #include "camel-exception.h"
 
+void 
+camel_exception_free (CamelException *exception)
+{
+       if (!exception) return;
+
+       if (exception->desc)
+               g_free (exception->desc);
+
+       g_free (exception);
+}
+
+
+CamelException *
+camel_exception_new ()
+{
+       CamelException *ex;
+
+       ex = g_new (CamelException, 1);
+       return ex;
+}
+
+
+void
+camel_exception_set (CamelException *ex,
+                    ExceptionId id,
+                    const char *desc)
+{
+       ex->id = id;
+       if (ex->desc)
+               g_free (ex->desc);
+       ex->desc = g_strdup (desc);
+}
+
+void 
+camel_exception_xfer (CamelException *ex_dst,
+                     CamelException *ex_src)
+{
+       if (ex_dst->desc)
+               g_free (ex_dst->desc);
+
+       ex_dst->id = ex_src->id;
+       ex_dst->desc = ex_src->desc;
+
+       ex_src->desc = NULL;
+       ex_src->id = CAMEL_EXCEPTION_NONE;
+}
index 217d6ca..1213511 100644 (file)
@@ -32,6 +32,8 @@ extern "C" {
 #pragma }
 #endif /* __cplusplus }*/
 
+#include <glib.h>
+
 
 typedef enum {
 #include "camel-exception-list.def"
@@ -45,7 +47,13 @@ typedef struct {
 
 } CamelException;
 
-
+void camel_exception_free (CamelException *exception);
+CamelException *camel_exception_new ();
+void camel_exception_set (CamelException *ex,
+                         ExceptionId id,
+                         const char *desc);
+void camel_exception_xfer (CamelException *ex_dst,
+                          CamelException *ex_src);
 
 
 
index 9c52615..8b89bbe 100644 (file)
 #include "camel-folder-pt-proxy.h"
 #include "camel-log.h"
 #include "camel-marshal-utils.h"
+#include "camel-exception.h"
 #include <pthread.h>
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
 
-/* needed for proper casts of async funcs when 
- * calling pthreads_create
- */
-typedef void * (*thread_call_func) (void *);
 
 static CamelFolderClass *parent_class=NULL;
 
@@ -53,14 +50,19 @@ enum CamelFolderFunc {
 static CamelFuncDef _camel_func_def [CAMEL_FOLDER__LAST_FUNC];
 
 
-
-static void _init_with_store (CamelFolder *folder, CamelStore *parent_store, CamelException *ex);
+static void _init_with_store (CamelFolder *folder, 
+                             CamelStore *parent_store, 
+                             CamelException *ex);
 static void _open (CamelFolder *folder, 
                   CamelFolderOpenMode mode, 
                   CamelFolderAsyncCallback callback, 
                   gpointer user_data, 
                   CamelException *ex);
-static void _close (CamelFolder *folder, gboolean expunge, CamelException *ex);
+static void _close (CamelFolder *folder, 
+                   gboolean expunge, 
+                   CamelFolderAsyncCallback callback, 
+                   gpointer user_data, 
+                   CamelException *ex);
 static void _set_name (CamelFolder *folder, const gchar *name, CamelException *ex);
 static const gchar *_get_name (CamelFolder *folder, CamelException *ex);
 static const gchar *_get_full_name (CamelFolder *folder, CamelException *ex);
@@ -87,17 +89,8 @@ static const gchar *_get_message_uid (CamelFolder *folder, CamelMimeMessage *mes
 static CamelMimeMessage *_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex);
 static GList *_get_uid_list  (CamelFolder *folder, CamelException *ex);
 
-
 static void _finalize (GtkObject *object);
 
-/* for the proxy watch */
-static gboolean _thread_notification_catch (GIOChannel *source,
-                                           GIOCondition condition,
-                                           gpointer data);
-static void _notify_availability (CamelFolder *folder, gchar op_name);
-static void _init_notify_system (CamelFolderPtProxy *proxy_folder);
-static void _init_signals_proxy (CamelFolderPtProxy *proxy_folder);
-
 
 static void
 camel_folder_pt_proxy_class_init (CamelFolderPtProxyClass *camel_folder_pt_proxy_class)
@@ -115,7 +108,7 @@ camel_folder_pt_proxy_class_init (CamelFolderPtProxyClass *camel_folder_pt_proxy
        camel_folder_class->set_name = _set_name;
        camel_folder_class->get_name = _get_name;
        camel_folder_class->can_hold_folders = _can_hold_folders;
-       camel_folder_class->can_hold_messages = _can_hold_messages;
+       camel_folder_class->can_hold_messages = _can_hold_messages;
        camel_folder_class->exists = _exists;
        camel_folder_class->is_open = _is_open;
        camel_folder_class->get_folder = _get_folder;
@@ -142,8 +135,32 @@ camel_folder_pt_proxy_class_init (CamelFolderPtProxyClass *camel_folder_pt_proxy
        /* function definition for proxying */
        proxy_class->open_func_def = 
                camel_func_def_new (camel_marshal_NONE__POINTER_INT_POINTER_POINTER, 
-                                   1, 
-                                   GTK_TYPE_INT);
+                                   4, 
+                                   GTK_TYPE_POINTER,
+                                   GTK_TYPE_INT,
+                                   GTK_TYPE_POINTER,
+                                   GTK_TYPE_POINTER);
+       proxy_class->open_cb_def = 
+               camel_func_def_new (camel_marshal_NONE__POINTER_POINTER_POINTER, 
+                                   3, 
+                                   GTK_TYPE_POINTER,
+                                   GTK_TYPE_POINTER,
+                                   GTK_TYPE_POINTER);
+
+       proxy_class->close_func_def = 
+               camel_func_def_new (camel_marshal_NONE__POINTER_BOOL_POINTER_POINTER, 
+                                   4, 
+                                   GTK_TYPE_POINTER,
+                                   GTK_TYPE_BOOL,
+                                   GTK_TYPE_POINTER,
+                                   GTK_TYPE_POINTER);
+       proxy_class->close_cb_def = 
+               camel_func_def_new (camel_marshal_NONE__POINTER_POINTER_POINTER, 
+                                   3, 
+                                   GTK_TYPE_POINTER,
+                                   GTK_TYPE_POINTER,
+                                   GTK_TYPE_POINTER);
+
 }
 
 
@@ -152,11 +169,8 @@ camel_folder_pt_proxy_class_init (CamelFolderPtProxyClass *camel_folder_pt_proxy
 static void
 camel_folder_pt_proxy_init (CamelFolderPtProxy *folder_pt_proxy)
 {
-       folder_pt_proxy->op_queue = camel_op_queue_new ();
-       folder_pt_proxy->signal_data_cond = g_cond_new();
-       folder_pt_proxy->signal_data_mutex = g_mutex_new();
-       _init_signals_proxy (folder_pt_proxy);
-       _init_notify_system (folder_pt_proxy);
+       folder_pt_proxy->thread_ex = camel_exception_new ();    
+       folder_pt_proxy->pud = g_new (_ProxyCbUserData, 1);     
 }
 
 
@@ -195,8 +209,9 @@ _finalize (GtkObject *object)
        GList *message_node;
 
        CAMEL_LOG_FULL_DEBUG ("Entering CamelFolderPtProxy::finalize\n");
-       g_cond_free (camel_folder_pt_proxy->signal_data_cond);
-       g_mutex_free (camel_folder_pt_proxy->signal_data_mutex);
+
+       camel_exception_free (camel_folder_pt_proxy->thread_ex);
+       g_free (camel_folder_pt_proxy->pud);
        GTK_OBJECT_CLASS (parent_class)->finalize (object);
        CAMEL_LOG_FULL_DEBUG ("Leaving CamelFolderPtProxy::finalize\n");
 }
@@ -205,417 +220,100 @@ _finalize (GtkObject *object)
 
 
 
-/* function proxies definitions */
-
-
-/* generic operation 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.
- * 
- * these routine is entended to be called 
- * in a thread 
- * 
- * Return value: 
- **/
-void
-_op_run_free_and_notify (CamelOp *op)
-{
-       gboolean error;
-       CamelFolder *folder;
-
-       camel_op_run (op);
-       camel_op_free (op);
-       folder = camel_op_get_user_data (op);
-       _notify_availability (folder, 'a');
-}
-
-
-
-
-/**
- * _run_next_op_in_thread:  
- * @proxy_folder: 
- * 
- * run the next operation pending in the proxy 
- * operation queue
- **/
-static void 
-_run_next_op_in_thread (CamelFolderPtProxy *proxy_folder)
-{
-       CamelOp *op;
-       CamelOpQueue *op_queue;
-       pthread_t thread;
-
-       op_queue = proxy_folder->op_queue;
-       /* get the next pending operation */
-       op = camel_op_queue_pop_op (op_queue);
-       if (!op) {
-               camel_op_queue_set_service_availability (op_queue, TRUE);
-               return;
-       }
-       
-       /* run the operation in a child thread */
-       pthread_create (&thread, NULL, (thread_call_func) _op_run_free_and_notify, op);
-
-}
+/**** Operations implementation ****/
 
 
 
-/**
- * _op_exec_or_plan_for_exec:
- * @proxy_folder: 
- * @op: 
- * 
- * if no thread is currently running, executes
- * op, otherwise push the operation in the operation 
- * queue.
- **/
-static void 
-_op_exec_or_plan_for_exec (CamelFolderPtProxy *proxy_folder, CamelOp *op)
+static gpointer
+_proxy_cb_user_data (_ProxyCbUserData *pud,
+                    CamelFolderAsyncCallback real_callback, 
+                    CamelFolderPtProxy *proxy_folder, 
+                    CamelException *ex,
+                    gpointer real_user_data)
 {
-       CamelOpQueue *op_queue;
-       pthread_t thread;
-       
-       op_queue = proxy_folder->op_queue;
-
-       /* put the real folder in the user data
-          so that it can be notified when the 
-          operation is completed */
-       camel_op_set_user_data (op, proxy_folder->real_folder);
-       
-       /* get next operation */
-       camel_op_queue_push_op (op_queue, op);
-       
-       if (camel_op_queue_get_service_availability (op_queue)) {
-               /* no thread is currently running, run 
-                * the next operation. */
-               camel_op_queue_set_service_availability (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_folder);          
-       }
+       pud->real_callback = real_callback;
+       pud->proxy_folder = proxy_folder;
+       pud->ex = ex;
+       pud->real_user_data = real_user_data;
+       return (gpointer)pud;
 }
 
 
+/* ******** */
 
-
-
-
-
-/**
- * _init_notify_system: set the notify channel up
- * @proxy_folder: 
- * 
- * called once to set the notification channel
- **/
+/* thread->init_with_store implementation */
 static void 
-_init_notify_system (CamelFolderPtProxy *proxy_folder)
+_init_with_store (CamelFolder *folder, 
+                 CamelStore *parent_store, 
+                 CamelException *ex)
 {
-       int filedes[2];
 
-       /* set up the notification channel */
-       if (!pipe (filedes)) {
-               CAMEL_LOG_WARNING ("could not create pipe in for camel_folder_proxy_init");
-               CAMEL_LOG_FULL_DEBUG ("Full error message : %s\n", strerror(errno));
+       parent_class->init_with_store (folder, parent_store, ex);
+       if (ex->id != CAMEL_EXCEPTION_NONE)
                return;
-       }
-       
-       
-       proxy_folder->pipe_client_fd = filedes [0];
-       proxy_folder->pipe_server_fd = filedes [1];
-       proxy_folder->notify_source =  g_io_channel_unix_new (filedes [0]);
-       
-       /* 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_folder->notify_source, G_IO_IN,
-                       _thread_notification_catch, 
-                       proxy_folder);
-       
-}
-
-/**
- * notify_availability: notify thread completion
- * @folder: real folder (in the child thread)
- * @op_name: operation name
- *
- * called by child thread (real folder) to notify the main 
- * thread (folder proxy) 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 (CamelFolder *folder, gchar op_name)
-{
-       GIOChannel *notification_channel;
-       CamelFolderPtProxy *proxy_folder;
-       guint bytes_written;
-
-       proxy_folder = (CamelFolderPtProxy *)gtk_object_get_data (GTK_OBJECT (folder),
-                                                                 "proxy_folder");
-       notification_channel = proxy_folder->notify_source;     
-       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 */
-
-static void
-_signal_marshaller_server_side (GtkObject *object,
-                               gpointer data,
-                               guint n_args,
-                               GtkArg *args)
-{
-       CamelFolder *folder;
-       CamelFolderPtProxy *proxy_folder;
-       guint signal_id;
-       
-       folder = CAMEL_FOLDER (object);
-       proxy_folder = CAMEL_FOLDER_PT_PROXY (gtk_object_get_data (object, "proxy_folder"));
-       signal_id = (guint)data;
-       g_assert (proxy_folder);
-
-       g_mutex_lock (proxy_folder->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_folder->signal_data.args)
-               g_cond_wait (proxy_folder->signal_data_cond,
-                            proxy_folder->signal_data_mutex);
-
-       proxy_folder->signal_data.signal_id = signal_id;
-       proxy_folder->signal_data.args = args;
-
-       
-       g_mutex_unlock (proxy_folder->signal_data_mutex);
-
-       /* tell the main thread there is a signal pending */
-       _notify_availability (folder, 's');
+#warning use proxy store here  
+       CF_CLASS (folder)->init_with_store (CAMEL_FOLDER_PT_PROXY (folder)->real_folder, 
+                                           parent_store, 
+                                           ex);
 }
 
 
-static void
-_signal_marshaller_client_side (CamelFolderPtProxy *proxy_folder)
-{
-       g_mutex_lock (proxy_folder->signal_data_mutex);
-       g_assert (proxy_folder->signal_data.args);
-       
-       /* emit the pending signal */
-       gtk_signal_emitv (GTK_OBJECT (proxy_folder), 
-                         proxy_folder->signal_data.signal_id,
-                         proxy_folder->signal_data.args);
-
-       proxy_folder->signal_data.args = NULL;
-
-       /* if waiting for the signal to be treated,
-        * awake the client thread up 
-        */ 
-       g_cond_signal (proxy_folder->signal_data_cond);
-       g_mutex_unlock (proxy_folder->signal_data_mutex);       
-}
-
 
-static void 
-_init_signals_proxy (CamelFolderPtProxy *proxy_folder)
-{
-       CamelFolder *real_folder;
-       GtkType camel_folder_type;
-       guint i;
-       char *signal_to_proxy[] = { 
-               NULL
-       };
-       camel_folder_type = CAMEL_FOLDER_TYPE;
-       real_folder = proxy_folder->real_folder;        
-
-       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_folder),
-                                        signal_to_proxy[i],
-                                        NULL,
-                                        _signal_marshaller_server_side,
-                                        (gpointer)gtk_signal_lookup (signal_to_proxy[i], camel_folder_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
+/* a little bit of explanation for the folder_class->open 
+ * method implementation : 
  * 
- * Return value: TRUE because we don't want the watch to be removed
- **/
-static gboolean  
-_thread_notification_catch (GIOChannel *source,
-                           GIOCondition condition,
-                           gpointer data)
-{
-       CamelFolderPtProxy *proxy_folder = (CamelFolderPtProxy *)data;  
-       gchar op_name;
-       guint bytes_read;
-       GIOError error;
-
-       
-       error = g_io_channel_read (source,
-                                  &op_name,
-                                  1,
-                                  &bytes_read);
-       
-       switch (op_name) {              
-       case 'a': /* the thread is OK for a new operation */
-               _run_next_op_in_thread (proxy_folder);          
-               break;
-       case 's': /* there is a pending signal to proxy */
-               _signal_marshaller_client_side (proxy_folder);
-               break;
-       }
-
-       /* do not remove the io watch */
-       return TRUE;
-}
-
-
-
-
-
-/*********/
+ * the proxy object "open" method is called by the client 
+ * program in the main thread. This method creates a 
+ * CamelOp object containing all the necessary informations 
+ * to call the corresponding "open" method on the real 
+ * folder object in the child folder. This CamelOp object 
+ * is pushed in a queue in the main thread (see the 
+ * CamelThreadProxy structure for more details). 
+ * The operations in this queue are executed one by one
+ * in a child thread. 
+ * Once the "open" method of the real object is finished, 
+ * it calls a callback. This callback is not the one supplied
+ * by the client object. Instead, the _folder_open_cb()
+ * function is called (in the child thread) which pushes
+ * the real callback function in another operation queue.
+ * The real callback is then called in the main thread. 
+ */
 
-/**** Operations implementation ****/
+/* folder->open implementation */
 
 /* 
- * the _async prefixed operations are
- * executed in a child thread.
- * When completed, they must call 
- * notify_availability () in order to
- * tell the main thread it can process
- * a new operation.
- *
+ * proxy callback. Called in the child thread by the 
+ * real folder "open" method when it is completed 
  */
-
-/* folder->init_with_store implementation */
 static void 
-_init_with_store (CamelFolder *folder, CamelStore *parent_store, CamelException *ex)
-{
-       CamelFolderPtProxy *proxy_folder = CAMEL_FOLDER_PT_PROXY (folder);
-
-#warning Notify io_channel initialization should be elsewhere
-       /* it can not be in camel_folder_proxy_init 
-        * because of the pipe error handling */ 
-       _init_notify_system (proxy_folder);
-       gtk_object_set_data (GTK_OBJECT (proxy_folder->real_folder),
-                            "proxy_folder",
-                            proxy_folder);
-
-       CF_CLASS (proxy_folder)->init_with_store (proxy_folder->real_folder,
-                                     parent_store,
-                                     ex);
-}
-
-
-
-/* folder->open implementation */
-
-typedef struct {
-       CamelFolder *folder;
-       CamelFolderOpenMode mode;
-       CamelFolderAsyncCallback callback;
-       gpointer user_data;
-       CamelException *ex;
-} _OpenFolderParam;
-
-
-void 
 _folder_open_cb (CamelFolder *folder,
                 gpointer user_data,
                 CamelException *ex)
 {
-       CamelFolderPtProxy *proxy_folder;
-       CamelFolderAsyncCallback callback;
-       _OpenFolderParam *param;
-       CamelOp *op;
-
-
-
+       CamelOp *cb;
+       _ProxyCbUserData *pud;
+       CamelFuncDef *cb_def;
 
-       proxy_folder = gtk_object_get_data (GTK_OBJECT (folder),
-                                           "proxy_folder");
-       callback = (CamelFolderAsyncCallback)user_data;
-
-       g_assert (proxy_folder);
-       g_assert (callback);
-       //op = camel_op_new ();
-       
-       //param = g_new (_OpenFolderParam, 1);
-       //param->folder = proxy_folder;
-       //param->user_data = user_data;
-       
-       
-}
+       /* transfer the exception information from "ex" to the 
+        * client supplied exception (kept in pud->ex) */        
+       camel_exception_xfer (pud->ex, ex);
 
-static void  
-_async_open (gpointer param)
-{
-       _OpenFolderParam *open_folder_param;
-       CamelFolder *folder;
-       CamelException *ex;
-       
-       open_folder_param = (_OpenFolderParam *)param;
-       
-       folder = open_folder_param->folder;
-       
-       CF_CLASS (folder)->open (folder, 
-                                open_folder_param->mode,
-                                open_folder_param->callback,
-                                open_folder_param->user_data,
-                                NULL);
-       g_free (param);
-       _notify_availability (folder, 'a');
+       /* create an operation which will call the real client
+        * supplied callback in the main thread */
+       cb_def = CAMEL_FOLDER_PT_PROXY_CLASS(pud->proxy_folder)->open_cb_def;
+       cb = camel_marshal_create_op (cb_def,
+                                     pud->real_callback, 
+                                     pud->proxy_folder, 
+                                     pud->real_user_data,
+                                     pud->ex);
+       camel_thread_proxy_push_cb (pud->proxy_folder->proxy_object, cb);
 
 }
 
 
-
 static void
 _open (CamelFolder *folder, 
        CamelFolderOpenMode mode, 
@@ -623,23 +321,39 @@ _open (CamelFolder *folder,
        gpointer user_data, 
        CamelException *ex)
 {
-       CamelFolderPtProxy *proxy_folder = CAMEL_FOLDER_PT_PROXY (folder);
-       _OpenFolderParam *param;
+       CamelFolderPtProxy *proxy_folder;
        CamelOp *op;
-
-       //op = camel_op_new ();
-       
-       //param = g_new (_OpenFolderParam, 1);
-       //param->folder = proxy_folder->real_folder;
-       //param->mode = mode;
-       //param->callback = callback;
-       //param->user_data = user_data;
-       
-
-       //op->func = _async_open;
-       //op->param =  param;
-       
-       //_op_exec_or_plan_for_exec (proxy_folder, op);
+       CamelFuncDef *func_def;
+
+       proxy_folder = CAMEL_FOLDER_PT_PROXY (folder);
+       
+       /* create an operation corresponding to the "open"
+        * method of the real object. The operation definition
+        * is common to all instances of the CamelFolderPtProxy 
+        * class so it is contained in the CamelFolderPtProxyClass
+        * structure. */
+       func_def = CAMEL_FOLDER_PT_PROXY_CLASS(proxy_folder)->open_func_def;
+       if (callback)           
+               op = camel_marshal_create_op (func_def, 
+                                             CAMEL_FOLDER_CLASS (proxy_folder->real_folder)->open,
+                                             proxy_folder->real_folder,
+                                             mode,
+                                             _folder_open_cb,
+                                             _proxy_cb_user_data (proxy_folder->pud, callback, proxy_folder, ex, user_data),
+                                             proxy_folder->thread_ex);
+       else 
+               op = camel_marshal_create_op (func_def, 
+                                             CAMEL_FOLDER_CLASS (proxy_folder->real_folder)->open,
+                                             proxy_folder->real_folder,
+                                             mode,
+                                             NULL,
+                                             NULL,
+                                             NULL);
+       /* push the operation in the operation queue. This operation 
+        * will be executed in a child thread but only one operation 
+        * will be executed at a time, so that folder implementations
+        * don't have to be MultiThread safe. */
+       camel_thread_proxy_push_op (proxy_folder->proxy_object, op);                                    
 }
 
 
@@ -647,84 +361,82 @@ _open (CamelFolder *folder,
 
 
 /* folder->close implementation */
-typedef struct {
-       CamelFolder *folder;
-       gboolean expunge;
-       CamelException *ex;
-} _CloseFolderParam;
 
-static void  
-_async_close (gpointer param)
+static void 
+_folder_close_cb (CamelFolder *folder,
+                 gpointer user_data,
+                 CamelException *ex)
 {
-       _CloseFolderParam *close_folder_param;
-       CamelFolder *folder;
-       CamelException *ex;
+       CamelOp *cb;
+       _ProxyCbUserData *pud;
+       CamelFuncDef *cb_def;
 
-       close_folder_param = (_CloseFolderParam *)param;
-       
-       folder = close_folder_param->folder;
-       
-       CF_CLASS (folder)->close (folder, 
-                                 close_folder_param->expunge, 
-                                 NULL);
-       g_free (param);
-       _notify_availability (folder, 'a');
+       camel_exception_xfer (pud->ex, ex);
+       cb_def = CAMEL_FOLDER_PT_PROXY_CLASS(pud->proxy_folder)->close_cb_def;
+       cb = camel_marshal_create_op (cb_def,
+                                     pud->real_callback, 
+                                     pud->proxy_folder, 
+                                     pud->real_user_data,
+                                     pud->ex);
+       camel_thread_proxy_push_cb (pud->proxy_folder->proxy_object, cb);
 
 }
 
 static void
-_close (CamelFolder *folder, gboolean expunge, CamelException *ex)
+_close (CamelFolder *folder, 
+       gboolean expunge, 
+       CamelFolderAsyncCallback callback, 
+       gpointer user_data, 
+       CamelException *ex)
 {
-       CamelFolderPtProxy *proxy_folder = CAMEL_FOLDER_PT_PROXY (folder);
-       _CloseFolderParam *param;
+       CamelFolderPtProxy *proxy_folder;
        CamelOp *op;
+       CamelFuncDef *func_def;
 
-       //op = camel_op_new ();
-       
-       //param = g_new (_CloseFolderParam, 1);
-       //param->folder = proxy_folder->real_folder;
-       //param->expunge = expunge;
+       proxy_folder = CAMEL_FOLDER_PT_PROXY (folder);
        
-       //op->func = _async_close;
-       //op->param =  param;
-       
-       //_op_exec_or_plan_for_exec (proxy_folder, op);
+       func_def = CAMEL_FOLDER_PT_PROXY_CLASS(proxy_folder)->close_func_def;
+       if (callback)           
+               op = camel_marshal_create_op (func_def, 
+                                             CAMEL_FOLDER_CLASS (proxy_folder->real_folder)->open,
+                                             proxy_folder->real_folder,
+                                             expunge,
+                                             _folder_close_cb,
+                                             _proxy_cb_user_data (proxy_folder->pud, callback, proxy_folder, ex, user_data),
+                                             proxy_folder->thread_ex);
+       else 
+               op = camel_marshal_create_op (func_def, 
+                                             CAMEL_FOLDER_CLASS (proxy_folder->real_folder)->open,
+                                             proxy_folder->real_folder,
+                                             expunge,
+                                             NULL,
+                                             NULL,
+                                             NULL);
+       camel_thread_proxy_push_op (proxy_folder->proxy_object, op);
+
 }
 
 
 
-/* folder->set_name implementation */
-
-typedef struct {
-       CamelFolder *folder;
-       const gchar *name;
-       CamelException *ex;
-} _SetNameFolderParam;
 
+/* folder->set_name implementation */
 static void  
 _async_set_name (gpointer param)
 {
-       _SetNameFolderParam *set_name_folder_param;
        CamelFolder *folder;
        CamelException *ex;
        
-       set_name_folder_param = (_SetNameFolderParam *)param;
        
-       folder = set_name_folder_param->folder;
+       //CF_CLASS (folder)->set_name (folder, 
+       //                           set_name_folder_param->name, 
+       //                   NULL);
        
-       CF_CLASS (folder)->set_name (folder, 
-                                    set_name_folder_param->name, 
-                                    NULL);
-       g_free (param);
-       _notify_availability (folder, 'a');
-
 }
 
 static void
 _set_name (CamelFolder *folder, const gchar *name, CamelException *ex)
 {
        CamelFolderPtProxy *proxy_folder = CAMEL_FOLDER_PT_PROXY (folder);
-       _SetNameFolderParam *param;
        CamelOp *op;
 
        //op = camel_op_new ();
@@ -747,8 +459,8 @@ _get_name (CamelFolder *folder, CamelException *ex)
 {
        CamelFolderPtProxy *proxy_folder = CAMEL_FOLDER_PT_PROXY (folder);
        
-       return CF_CLASS (proxy_folder->real_folder)->
-               get_name (proxy_folder->real_folder, ex);
+       //return CF_CLASS (proxy_folder->real_folder)->
+       //get_name (proxy_folder->real_folder, ex);
 }
 
 
index e540c78..285306a 100644 (file)
 #ifndef CAMEL_FOLDER_PT_PROXY_H
 #define CAMEL_FOLDER_PT_PROXY_H 1
 
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus }*/
+
 #include "camel-folder.h"
 #include "camel-op-queue.h"
+#include "camel-thread-proxy.h"
 
 
 #define CAMEL_FOLDER_PT_PROXY_TYPE     (camel_folder_pt_proxy_get_type ())
 #define CAMEL_FOLDER_PT_PROXY_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_FOLDER_PT_PROXY_TYPE, CamelFolderPtProxyClass))
 #define IS_CAMEL_FOLDER_PT_PROXY(o)    (GTK_CHECK_TYPE((o), CAMEL_FOLDER_PT_PROXY_TYPE))
 
-typedef struct {
-       guint signal_id;
-       GtkArg *args;
-} PtProxySignaData;
-
-
+typedef struct _CamelFolderPtProxy CamelFolderPtProxy;
 
 typedef struct {
+       CamelFolderAsyncCallback real_callback;
+       CamelFolderPtProxy *proxy_folder;
+       CamelException *ex;
+       gpointer real_user_data;
+} _ProxyCbUserData;
+
+struct _CamelFolderPtProxy {
        CamelFolder parent;
        
-       gchar *real_url;
+       /* private fields */ 
        CamelFolder *real_folder;
-
-       CamelOpQueue *op_queue;
-       gint pipe_client_fd;
-       gint pipe_server_fd;
-       GIOChannel *notify_source;
-
-       /* used for signal proxy */
-       GMutex *signal_data_mutex;
-       GCond *signal_data_cond;
-       PtProxySignaData signal_data;
-} CamelFolderPtProxy;
+       CamelThreadProxy *proxy_object;
+       CamelException *thread_ex;
+       _ProxyCbUserData *pud;
+       
+};
 
 
 
 typedef struct {
        CamelFolderClass parent_class;
        
+       /* functions and callbacks definition (for marshalling) */
        CamelFuncDef *open_func_def;
+       CamelFuncDef *open_cb_def;
+       CamelFuncDef *close_func_def;
+       CamelFuncDef *close_cb_def;
 
 } CamelFolderPtProxyClass;
 
-/* some marshallers */
-void camel_marshal_NONE__POINTER_INT (CamelFunc func, 
-                                     GtkArg *args);
-
-void camel_marshal_NONE__POINTER_INT_POINTER (CamelFunc func, 
-                                             GtkArg *args);
-
-
 
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
 
 #endif /* CAMEL_FOLDER_PT_PROXY_H */
index f887d83..ef37bb8 100644 (file)
@@ -36,7 +36,11 @@ static void _open (CamelFolder *folder,
                   CamelFolderAsyncCallback callback, 
                   gpointer user_data, 
                   CamelException *ex);
-static void _close (CamelFolder *folder, gboolean expunge, CamelException *ex);
+static void _close (CamelFolder *folder, 
+                   gboolean expunge, 
+                   CamelFolderAsyncCallback callback, 
+                   gpointer user_data, 
+                   CamelException *ex);
 static void _set_name (CamelFolder *folder, const gchar *name, CamelException *ex);
 /*  static void _set_full_name (CamelFolder *folder, const gchar *name); */
 static const gchar *_get_name (CamelFolder *folder, CamelException *ex);
@@ -189,13 +193,7 @@ _init_with_store (CamelFolder *folder, CamelStore *parent_store, CamelException
 
 
 
-/**
- * _open: Open a folder
- * @folder: The folder object
- * @mode: open mode (R/W/RW ?)
- * 
- * 
- **/
+
 static void
 _open (CamelFolder *folder, 
        CamelFolderOpenMode mode, 
@@ -207,7 +205,19 @@ _open (CamelFolder *folder,
 /*     folder->open_mode = mode; */
 }
 
-
+/**
+ * camel_folder_open: Open a folder
+ * @folder: The folder object
+ * @mode: open mode (R/W/RW ?)
+ * @callback: function to call when the operation is over
+ * @user_data: data to pass to the callback 
+ * @ex: exception object
+ *
+ * Open a folder in a given mode. When the opration is over
+ * the callback is called and the client program can determine
+ * if the operation suceeded by examining the exception. 
+ * 
+ **/
 void 
 camel_folder_open (CamelFolder *folder, 
                   CamelFolderOpenMode mode, 
@@ -220,25 +230,39 @@ camel_folder_open (CamelFolder *folder,
 
 
 
-/**
- * _close:Close a folder.
- * @folder: 
- * @expunge: if TRUE, the flagged message are deleted.
- * 
- * Put a folder in its closed state, and possibly 
- * expunge the flagged messages.
- **/
+
 static void
-_close (CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
-       if (expunge) camel_folder_expunge (folder, FALSE, ex);
+_close (CamelFolder *folder, 
+       gboolean expunge, 
+       CamelFolderAsyncCallback callback, 
+       gpointer user_data, 
+       CamelException *ex)
+{      
        folder->open_state = FOLDER_CLOSE;
 }
 
+/**
+ * camel_folder_close: Close a folder.
+ * @folder: The folder object
+ * @expunge: if TRUE, the flagged message are deleted.
+ * @callback: function to call when the operation is over
+ * @user_data: data to pass to the callback 
+ * @ex: exception object
+ *
+ * Put a folder in its closed state, and possibly 
+ * expunge the flagged messages. The callback is called 
+ * when the operation is over and the client program can determine
+ * if the operation suceeded by examining the exception. 
+ * 
+ **/
 void 
-camel_folder_close (CamelFolder *folder, gboolean expunge, CamelException *ex)
+camel_folder_close (CamelFolder *folder, 
+                   gboolean expunge, 
+                   CamelFolderAsyncCallback callback, 
+                   gpointer user_data, 
+                   CamelException *ex)
 {
-       CF_CLASS(folder)->close (folder, expunge, ex);
+       CF_CLASS(folder)->close (folder, expunge, callback, user_data, ex);
 }
 
 
index 7f454d9..5ab39f8 100644 (file)
@@ -88,13 +88,19 @@ typedef struct {
        GtkObjectClass parent_class;
        
        /* Virtual methods */   
-       void   (*init_with_store) (CamelFolder *folder, CamelStore *parent_store, CamelException *ex);
+       void   (*init_with_store) (CamelFolder *folder, 
+                                  CamelStore *parent_store, 
+                                  CamelException *ex);
        void   (*open) (CamelFolder *folder, 
                        CamelFolderOpenMode mode, 
                        CamelFolderAsyncCallback callback, 
                        gpointer user_data, 
                        CamelException *ex);
-       void   (*close) (CamelFolder *folder, gboolean expunge, CamelException *ex);
+       void   (*close) (CamelFolder *folder, 
+                        gboolean expunge, 
+                        CamelFolderAsyncCallback callback, 
+                        gpointer user_data, 
+                        CamelException *ex);
        void   (*set_name) (CamelFolder *folder, const gchar *name, CamelException *ex);
        /*      void   (*set_full_name) (CamelFolder *folder, const gchar *name); */
        const gchar *  (*get_name) (CamelFolder *folder, CamelException *ex);
@@ -139,7 +145,12 @@ void camel_folder_open (CamelFolder *folder,
                        gpointer user_data, 
                        CamelException *ex);
 
-void camel_folder_close (CamelFolder *folder, gboolean expunge, CamelException *ex);
+void camel_folder_close (CamelFolder *folder, 
+                        gboolean expunge, 
+                        CamelFolderAsyncCallback callback, 
+                        gpointer user_data, 
+                        CamelException *ex);
+
 gboolean camel_folder_create (CamelFolder *folder, CamelException *ex);
 gboolean camel_folder_delete (CamelFolder *folder, gboolean recurse, CamelException *ex);
 gboolean camel_folder_delete_messages (CamelFolder *folder, CamelException *ex);
index bb12318..7ea5402 100644 (file)
@@ -144,6 +144,7 @@ camel_op_new (CamelFuncDef *func_def)
 {
        CamelOp *op;
 
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOp::new\n");
        g_static_mutex_lock (&op_chunk_mutex);
        if (!op_chunk)
                op_chunk = g_mem_chunk_create (CamelOp, 
@@ -155,6 +156,7 @@ camel_op_new (CamelFuncDef *func_def)
        op->func_def = func_def;
        op->params = g_new (GtkArg, func_def->n_params);
        
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOp::new\n");
        return op;      
 }
 
@@ -169,8 +171,10 @@ camel_op_new (CamelFuncDef *func_def)
 void 
 camel_op_free (CamelOp *op)
 {
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOp::free\n");
        g_free (op->params);
        g_chunk_free (op, op_chunk);
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOp::free\n");
 }
 
 
@@ -187,11 +191,13 @@ camel_op_run (CamelOp *op)
        GtkArg  *params;
        gboolean error;
        
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOp::run\n");
        g_assert (op);
        g_assert (op->func_def);
        g_assert (op->params);
 
        op->func_def->marshal (op->func, op->params);
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOp::run\n");
 }
 
 
@@ -207,8 +213,10 @@ camel_op_run (CamelOp *op)
 void 
 camel_op_set_user_data (CamelOp *op, gpointer user_data)
 {
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOp::set_user_data\n");
        g_assert (op);
        op->user_data = user_data;
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOp::set_user_data\n");
 }
 
 
@@ -224,7 +232,9 @@ camel_op_set_user_data (CamelOp *op, gpointer user_data)
 gpointer 
 camel_op_get_user_data (CamelOp *op)
 {
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOp::get_user_data\n");
        g_assert (op);
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOp::get_user_data\n");
        return op->user_data;
 }
 
@@ -239,9 +249,12 @@ void camel_marshal_NONE__POINTER_INT (CamelFunc func,
                                      GtkArg *args)
 {
        CamelMarshal_NONE__POINTER_INT rfunc;
+
+       CAMEL_LOG_FULL_DEBUG ("Entering camel_marshal_NONE__POINTER_INT\n");
        rfunc = (CamelMarshal_NONE__POINTER_INT) func;
        (* rfunc) (GTK_VALUE_POINTER(args[0]),
                   GTK_VALUE_INT(args[1]));
+       CAMEL_LOG_FULL_DEBUG ("Leaving camel_marshal_NONE__POINTER_INT\n");
 }
 
 
@@ -255,12 +268,33 @@ void camel_marshal_NONE__POINTER_INT_POINTER (CamelFunc func,
                                              GtkArg *args)
 {
        CamelMarshal_NONE__POINTER_INT_POINTER rfunc;
+
+       CAMEL_LOG_FULL_DEBUG ("Entering camel_marshal_NONE__POINTER_INT_POINTER\n");
        rfunc = (CamelMarshal_NONE__POINTER_INT_POINTER) func;
        (* rfunc) (GTK_VALUE_POINTER(args[0]),
                   GTK_VALUE_INT(args[1]),
                   GTK_VALUE_POINTER(args[2]));
+       CAMEL_LOG_FULL_DEBUG ("Leaving camel_marshal_NONE__POINTER_INT_POINTER\n");
 }
 
+
+typedef void (*CamelMarshal_NONE__POINTER_BOOL_POINTER) (gpointer arg1,
+                                                        gboolean arg2,
+                                                        gpointer arg3);
+void camel_marshal_NONE__POINTER_BOOL_POINTER (CamelFunc func, 
+                                             GtkArg *args)
+{
+       CamelMarshal_NONE__POINTER_BOOL_POINTER rfunc;
+
+       CAMEL_LOG_FULL_DEBUG ("Entering camel_marshal_NONE__POINTER_BOOL_POINTER\n");
+       rfunc = (CamelMarshal_NONE__POINTER_BOOL_POINTER) func;
+       (* rfunc) (GTK_VALUE_POINTER(args[0]),
+                  GTK_VALUE_BOOL(args[1]),
+                  GTK_VALUE_POINTER(args[2]));
+       CAMEL_LOG_FULL_DEBUG ("Leaving camel_marshal_NONE__POINTER_BOOL_POINTER\n");
+}
+
+
 typedef void (*CamelMarshal_NONE__POINTER_INT_POINTER_POINTER) (gpointer arg1,
                                                                gint arg2,
                                                                gpointer arg3,
@@ -269,11 +303,52 @@ void camel_marshal_NONE__POINTER_INT_POINTER_POINTER (CamelFunc func,
                                                      GtkArg *args)
 {
        CamelMarshal_NONE__POINTER_INT_POINTER_POINTER rfunc;
+
+       CAMEL_LOG_FULL_DEBUG ("Entering camel_marshal_NONE__POINTER_INT_POINTER_POINTER\n");
        rfunc = (CamelMarshal_NONE__POINTER_INT_POINTER_POINTER) func;
        (* rfunc) (GTK_VALUE_POINTER(args[0]),
                   GTK_VALUE_INT(args[1]),
                   GTK_VALUE_POINTER(args[2]),
                   GTK_VALUE_POINTER(args[3]));
+       CAMEL_LOG_FULL_DEBUG ("Leaving camel_marshal_NONE__POINTER_INT_POINTER_POINTER\n");
+}
+
+
+
+typedef void (*CamelMarshal_NONE__POINTER_BOOL_POINTER_POINTER) (gpointer arg1,
+                                                                gboolean arg2,
+                                                                gpointer arg3,
+                                                                gpointer arg4);
+void camel_marshal_NONE__POINTER_BOOL_POINTER_POINTER (CamelFunc func, 
+                                                      GtkArg *args)
+{
+       CamelMarshal_NONE__POINTER_BOOL_POINTER_POINTER rfunc;
+
+       CAMEL_LOG_FULL_DEBUG ("Entering camel_marshal_NONE__POINTER_BOOL_POINTER_POINTER\n");
+       rfunc = (CamelMarshal_NONE__POINTER_BOOL_POINTER_POINTER) func;
+       (* rfunc) (GTK_VALUE_POINTER(args[0]),
+                  GTK_VALUE_BOOL(args[1]),
+                  GTK_VALUE_POINTER(args[2]),
+                  GTK_VALUE_POINTER(args[3]));
+       CAMEL_LOG_FULL_DEBUG ("Leaving camel_marshal_NONE__POINTER_BOOL_POINTER_POINTER\n");
+}
+
+
+
+typedef void (*CamelMarshal_NONE__POINTER_POINTER_POINTER) (gpointer arg1,
+                                                           gpointer arg2,
+                                                           gpointer arg3);
+void camel_marshal_NONE__POINTER_POINTER_POINTER (CamelFunc func, 
+                                                 GtkArg *args)
+{
+       CamelMarshal_NONE__POINTER_POINTER_POINTER rfunc;
+
+       CAMEL_LOG_FULL_DEBUG ("Entering camel_marshal_NONE__POINTER_POINTER_POINTER\n");
+       rfunc = (CamelMarshal_NONE__POINTER_POINTER_POINTER) func;
+       (* rfunc) (GTK_VALUE_POINTER(args[0]),
+                  GTK_VALUE_POINTER(args[1]),
+                  GTK_VALUE_POINTER(args[2]));
+       CAMEL_LOG_FULL_DEBUG ("Leaving camel_marshal_NONE__POINTER_POINTER_POINTER\n");
 }
 
 
@@ -282,8 +357,11 @@ void camel_marshal_NONE__INT (CamelFunc func,
                              GtkArg *args)
 {
        CamelMarshal_NONE__INT rfunc;
+
+       CAMEL_LOG_FULL_DEBUG ("Entering camel_marshal_NONE__INT\n");
        rfunc = (CamelMarshal_NONE__INT) func;
        (* rfunc) (GTK_VALUE_INT (args[0]));
+       CAMEL_LOG_FULL_DEBUG ("Leaving camel_marshal_NONE__INT\n");
 }
 
 
index 324f32e..da62309 100644 (file)
@@ -80,8 +80,14 @@ CamelOp *camel_marshal_create_op (CamelFuncDef *func_def, CamelFunc func, ...);
 /* marshallers */
 void camel_marshal_NONE__POINTER_INT_POINTER (CamelFunc func, 
                                              GtkArg *args);
+void camel_marshal_NONE__POINTER_BOOL_POINTER (CamelFunc func, 
+                                             GtkArg *args);
 void camel_marshal_NONE__POINTER_INT_POINTER_POINTER (CamelFunc func, 
                                                      GtkArg *args);
+void camel_marshal_NONE__POINTER_BOOL_POINTER_POINTER (CamelFunc func, 
+                                                      GtkArg *args);
+void camel_marshal_NONE__POINTER_POINTER_POINTER (CamelFunc func, 
+                                                 GtkArg *args);
 void camel_marshal_NONE__INT (CamelFunc func, 
                              GtkArg *args);
 
index a722c16..415c607 100644 (file)
@@ -22,7 +22,9 @@
 
 /* MT safe */
 
-
+#include <config.h>
+#include "camel-log.h"
 #include "camel-op-queue.h"
 
 static GStaticMutex op_queue_mutex = G_STATIC_MUTEX_INIT;
@@ -41,14 +43,27 @@ camel_op_queue_new ()
 {
        CamelOpQueue *op_queue;
 
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOpQueue::new\n");
 
        op_queue = g_new (CamelOpQueue, 1);
        op_queue->ops_tail = NULL;
        op_queue->ops_head = NULL;
-       
+       op_queue->service_available = TRUE;
+
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOpQueue::new\n");
+       return op_queue;
 }
 
 
+void 
+camel_op_queue_free (CamelOpQueue *op_queue)
+{
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOpQueue::free\n");
+       g_list_free (op_queue->ops_head);       
+       g_free (op_queue);
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOpQueue::free\n");
+}
+
 /**
  * camel_op_queue_push_op: Add an operation to the queue
  * @queue: queue object
@@ -62,14 +77,18 @@ camel_op_queue_push_op (CamelOpQueue *queue, CamelOp *op)
 {
        GList *new_op;
 
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOpQueue::push_op\n");
        g_assert (queue);
        g_static_mutex_lock (&op_queue_mutex);
        if (!queue->ops_tail) {
+               CAMEL_LOG_FULL_DEBUG ("CamelOpQueue::push_op queue does not exists yet. "
+                                     "Creating it\n");
                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_LOG_FULL_DEBUG ("Leaving CamelOpQueue::push_op\n");
 }
 
 
@@ -87,14 +106,18 @@ camel_op_queue_pop_op (CamelOpQueue *queue)
        GList *op_list;
        CamelOp *op;
 
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOpQueue::pop_op\n");
        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);
 
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOpQueue::pop_op\n");
        return op;
 }
 
@@ -112,11 +135,12 @@ camel_op_queue_run_next_op (CamelOpQueue *queue)
 {
        CamelOp *op;
 
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOpQueue::run_next_op\n");
        op = camel_op_queue_pop_op (queue);
        if (!op) return FALSE;
 
        
-
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOpQueue::run_next_op\n");
        return FALSE;
 }
 
@@ -130,9 +154,11 @@ camel_op_queue_run_next_op (CamelOpQueue *queue)
 void
 camel_op_queue_set_service_availability (CamelOpQueue *queue, gboolean available)
 {
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOpQueue::set_service_availability\n");
        g_static_mutex_lock (&op_queue_mutex);
        queue->service_available = available;
        g_static_mutex_unlock (&op_queue_mutex);
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOpQueue::set_service_availability\n");
 }
 
 /**
@@ -147,9 +173,12 @@ gboolean
 camel_op_queue_get_service_availability (CamelOpQueue *queue)
 {
        gboolean available;
+
+       CAMEL_LOG_FULL_DEBUG ("Entering CamelOpQueue::get_service_availability\n");
        g_static_mutex_lock (&op_queue_mutex);
        available = queue->service_available;
        g_static_mutex_unlock (&op_queue_mutex);
+       CAMEL_LOG_FULL_DEBUG ("Leaving CamelOpQueue::get_service_availability\n");
        return available;
 }
 
index f649532..5231a20 100644 (file)
@@ -45,6 +45,7 @@ typedef struct
 
 /* 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);
index 7060418..06e0b34 100644 (file)
  * USA
  */
 
+#include <config.h>
 #include "camel.h"
 
 gint
 camel_init()
 {
-       return data_wrapper_repository_init ();
+#ifdef G_THREADS_ENABLED       
+       g_thread_init (NULL);
+#else  /* G_THREADS_ENABLED */
+       printf ("Threads are not supported by glib\n");
+#endif /* G_THREADS_ENABLED */
+
+       //return data_wrapper_repository_init ();
        
 }
index 9950014..085f53f 100644 (file)
@@ -52,6 +52,7 @@ extern "C" {
 #include <camel-stream.h>
 #include <camel-stream-fs.h>
 #include <camel-stream-mem.h>
+#include <camel-thread-proxy.h>
 #include <data-wrapper-repository.h>
 #include <gmime-content-field.h>
 #include <gmime-utils.h>