aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/Makefile.am2
-rw-r--r--camel/camel-folder-pt-proxy.c160
-rw-r--r--camel/camel-folder-pt-proxy.h2
-rw-r--r--camel/camel-marshal-utils.c195
-rw-r--r--camel/camel-marshal-utils.h38
-rw-r--r--camel/camel-op-queue.c65
-rw-r--r--camel/camel-op-queue.h11
-rw-r--r--camel/camel.h3
8 files changed, 313 insertions, 163 deletions
diff --git a/camel/Makefile.am b/camel/Makefile.am
index 8bc72c829e..474718ddf5 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -98,6 +98,8 @@ libcamelinclude_HEADERS = \
url-util.h \
$(pthread_HDR)
+libcamel_extra_sources = \
+ camel-arg-collector.c
libcamel_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
diff --git a/camel/camel-folder-pt-proxy.c b/camel/camel-folder-pt-proxy.c
index bfc5900573..9c52615971 100644
--- a/camel/camel-folder-pt-proxy.c
+++ b/camel/camel-folder-pt-proxy.c
@@ -94,13 +94,18 @@ static void _finalize (GtkObject *object);
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)
{
GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_folder_pt_proxy_class);
CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_folder_pt_proxy_class);
-
+ CamelFolderPtProxyClass *proxy_class = camel_folder_pt_proxy_class;
+
parent_class = gtk_type_class (camel_folder_get_type ());
/* virtual method definition */
@@ -133,6 +138,12 @@ camel_folder_pt_proxy_class_init (CamelFolderPtProxyClass *camel_folder_pt_proxy
/* virtual method overload */
gtk_object_class->finalize = _finalize;
+
+ /* function definition for proxying */
+ proxy_class->open_func_def =
+ camel_func_def_new (camel_marshal_NONE__POINTER_INT_POINTER_POINTER,
+ 1,
+ GTK_TYPE_INT);
}
@@ -144,10 +155,13 @@ 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);
}
+
GtkType
camel_folder_pt_proxy_get_type (void)
{
@@ -188,26 +202,54 @@ _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_notify (CamelOp *op)
+_op_run_free_and_notify (CamelOp *op)
{
gboolean error;
-
- error = camel_op_run (op);
+ CamelFolder *folder;
+
+ camel_op_run (op);
camel_op_free (op);
-
+ folder = camel_op_get_user_data (op);
+ _notify_availability (folder, 'a');
}
+
+
+
/**
- * _maybe_run_next_op: run next operation in queue, if any
+ * _run_next_op_in_thread:
* @proxy_folder:
*
- *
+ * run the next operation pending in the proxy
+ * operation queue
**/
static void
-_maybe_run_next_op (CamelFolderPtProxy *proxy_folder)
+_run_next_op_in_thread (CamelFolderPtProxy *proxy_folder)
{
CamelOp *op;
CamelOpQueue *op_queue;
@@ -222,17 +264,12 @@ _maybe_run_next_op (CamelFolderPtProxy *proxy_folder)
}
/* run the operation in a child thread */
- pthread_create (&thread, NULL, (thread_call_func) camel_op_run_and_free, op);
-
-}
+ pthread_create (&thread, NULL, (thread_call_func) _op_run_free_and_notify, op);
-static void
-_maybe_run_next_op_in_thread (CamelFolderPtProxy *proxy_folder)
-{
-
}
+
/**
* _op_exec_or_plan_for_exec:
* @proxy_folder:
@@ -249,12 +286,27 @@ _op_exec_or_plan_for_exec (CamelFolderPtProxy *proxy_folder, CamelOp *op)
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 operation next op.*/
+ * the next operation. */
camel_op_queue_set_service_availability (op_queue, FALSE);
- _maybe_run_next_op (proxy_folder);
+ /* 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);
}
}
@@ -298,7 +350,7 @@ _init_notify_system (CamelFolderPtProxy *proxy_folder)
/**
* notify_availability: notify thread completion
- * @folder: server folder (in the child thread)
+ * @folder: real folder (in the child thread)
* @op_name: operation name
*
* called by child thread (real folder) to notify the main
@@ -330,6 +382,9 @@ _notify_availability (CamelFolder *folder, gchar op_name)
} while (bytes_written == 1);
}
+
+
+
/* signal proxying */
static void
@@ -389,7 +444,7 @@ _signal_marshaller_client_side (CamelFolderPtProxy *proxy_folder)
}
-
+static void
_init_signals_proxy (CamelFolderPtProxy *proxy_folder)
{
CamelFolder *real_folder;
@@ -403,7 +458,7 @@ _init_signals_proxy (CamelFolderPtProxy *proxy_folder)
real_folder = proxy_folder->real_folder;
for (i=0; signal_to_proxy[i]; i++) {
- /* conect the signal to the signal marshaller
+ /* 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],
@@ -420,7 +475,7 @@ _init_signals_proxy (CamelFolderPtProxy *proxy_folder)
}
-/**** catch notification from the child thread ****/
+/**** catch notification from child thread ****/
/**
* _thread_notification_catch: call by glib loop when data is available on the thread io channel
* @source:
@@ -449,7 +504,7 @@ _thread_notification_catch (GIOChannel *source,
switch (op_name) {
case 'a': /* the thread is OK for a new operation */
- _maybe_run_next_op (proxy_folder);
+ _run_next_op_in_thread (proxy_folder);
break;
case 's': /* there is a pending signal to proxy */
_signal_marshaller_client_side (proxy_folder);
@@ -492,7 +547,7 @@ _init_with_store (CamelFolder *folder, CamelStore *parent_store, CamelException
"proxy_folder",
proxy_folder);
- camel_folder_init_with_store (proxy_folder->real_folder,
+ CF_CLASS (proxy_folder)->init_with_store (proxy_folder->real_folder,
parent_store,
ex);
}
@@ -529,11 +584,11 @@ _folder_open_cb (CamelFolder *folder,
g_assert (proxy_folder);
g_assert (callback);
- op = camel_op_new ();
+ //op = camel_op_new ();
- param = g_new (_OpenFolderParam, 1);
- param->folder = proxy_folder;
- param->user_data = user_data;
+ //param = g_new (_OpenFolderParam, 1);
+ //param->folder = proxy_folder;
+ //param->user_data = user_data;
}
@@ -572,19 +627,19 @@ _open (CamelFolder *folder,
_OpenFolderParam *param;
CamelOp *op;
- op = camel_op_new ();
+ //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;
+ //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->func = _async_open;
+ //op->param = param;
- _op_exec_or_plan_for_exec (proxy_folder, op);
+ //_op_exec_or_plan_for_exec (proxy_folder, op);
}
@@ -624,16 +679,16 @@ _close (CamelFolder *folder, gboolean expunge, CamelException *ex)
_CloseFolderParam *param;
CamelOp *op;
- op = camel_op_new ();
+ //op = camel_op_new ();
- param = g_new (_CloseFolderParam, 1);
- param->folder = proxy_folder->real_folder;
- param->expunge = expunge;
+ //param = g_new (_CloseFolderParam, 1);
+ //param->folder = proxy_folder->real_folder;
+ //param->expunge = expunge;
- op->func = _async_close;
- op->param = param;
+ //op->func = _async_close;
+ //op->param = param;
- _op_exec_or_plan_for_exec (proxy_folder, op);
+ //_op_exec_or_plan_for_exec (proxy_folder, op);
}
@@ -672,16 +727,16 @@ _set_name (CamelFolder *folder, const gchar *name, CamelException *ex)
_SetNameFolderParam *param;
CamelOp *op;
- op = camel_op_new ();
+ //op = camel_op_new ();
- param = g_new (_SetNameFolderParam, 1);
- param->folder = proxy_folder->real_folder;
- param->name = name;
+ //param = g_new (_SetNameFolderParam, 1);
+ //param->folder = proxy_folder->real_folder;
+ //param->name = name;
- op->func = _async_set_name;
- op->param = param;
+ //op->func = _async_set_name;
+ //op->param = param;
- _op_exec_or_plan_for_exec (proxy_folder, op);
+ //_op_exec_or_plan_for_exec (proxy_folder, op);
}
@@ -922,3 +977,8 @@ _get_uid_list (CamelFolder *folder, CamelException *ex)
/* **** */
+
+
+
+
+
diff --git a/camel/camel-folder-pt-proxy.h b/camel/camel-folder-pt-proxy.h
index 39f6ee3d16..e540c78d4b 100644
--- a/camel/camel-folder-pt-proxy.h
+++ b/camel/camel-folder-pt-proxy.h
@@ -65,6 +65,8 @@ typedef struct {
typedef struct {
CamelFolderClass parent_class;
+
+ CamelFuncDef *open_func_def;
} CamelFolderPtProxyClass;
diff --git a/camel/camel-marshal-utils.c b/camel/camel-marshal-utils.c
index 95cf1577bb..bb12318837 100644
--- a/camel/camel-marshal-utils.c
+++ b/camel/camel-marshal-utils.c
@@ -27,8 +27,13 @@
#include "config.h"
#include "camel-log.h"
#include "camel-marshal-utils.h"
+#include "camel-arg-collector.c"
+#define NB_OP_CHUNKS 20
+static GMemChunk *op_chunk=NULL;
+static GStaticMutex op_chunk_mutex = G_STATIC_MUTEX_INIT;
+
CamelFuncDef *
camel_func_def_new (CamelMarshal marshal, guint n_params, ...)
{
@@ -60,20 +65,22 @@ _collect_params (GtkArg *params,
CamelFuncDef *func_def,
va_list var_args)
{
- register GtkArg *last_param;
- register gboolean failed = FALSE;
-
- for (last_param = params + func_def->n_params;
- params < last_param;
- params++)
+ GtkArg *last_param;
+ int i;
+ gboolean failed = FALSE;
+
+
+ for (i=0;
+ i<func_def->n_params;
+ i++, params++)
{
- register gchar *error;
+ gchar *error;
params->name = NULL;
- params->type = *(func_def->params_type++);
- GTK_ARG_COLLECT_VALUE (params,
- var_args,
- error);
+ params->type = (func_def->params_type) [i];
+ CAMEL_ARG_COLLECT_VALUE (params,
+ var_args,
+ error);
if (error)
{
failed = TRUE;
@@ -85,30 +92,20 @@ _collect_params (GtkArg *params,
}
-gboolean
-camel_marshal_exec_func (CamelFuncDef *func_def, ...)
-{
- GtkArg *params;
- gboolean error;
- va_list args;
-
- g_assert (func_def);
-
- params = g_new (GtkArg, func_def->n_params);
-
- va_start (args, func_def);
- error = _collect_params (params, func_def, args);
- va_end (args);
- if (!error)
- error = func_def->marshal (func_def->func, params);
-
- g_free (params);
- return (!error);
-}
-
+/**
+ * camel_marshal_create_op: create an operation
+ * @func_def: function definition object
+ * @func: function to call
+ *
+ * create a function ready to be executed. The
+ * vari
+ *
+ *
+ * Return value: operation ready to be executed
+ **/
CamelOp *
-camel_marshal_create_op (CamelFuncDef *func_def, ...)
+camel_marshal_create_op (CamelFuncDef *func_def, CamelFunc func, ...)
{
GtkArg *params;
gboolean error;
@@ -118,8 +115,9 @@ camel_marshal_create_op (CamelFuncDef *func_def, ...)
g_assert (func_def);
op = camel_op_new (func_def);
-
- va_start (args, func_def);
+ op->func = func;
+
+ va_start (args, func);
error = _collect_params (op->params, func_def, args);
va_end (args);
@@ -133,6 +131,102 @@ camel_marshal_create_op (CamelFuncDef *func_def, ...)
+/**
+ * camel_op_new: return a new CamelOp object
+ *
+ * The obtained object must be destroyed with
+ * camel_op_free ()
+ *
+ * Return value: the newly allocated CamelOp object
+ **/
+CamelOp *
+camel_op_new (CamelFuncDef *func_def)
+{
+ CamelOp *op;
+
+ g_static_mutex_lock (&op_chunk_mutex);
+ if (!op_chunk)
+ op_chunk = g_mem_chunk_create (CamelOp,
+ NB_OP_CHUNKS,
+ G_ALLOC_AND_FREE);
+ g_static_mutex_unlock (&op_chunk_mutex);
+
+ op = g_chunk_new (CamelOp, op_chunk);
+ op->func_def = func_def;
+ op->params = g_new (GtkArg, func_def->n_params);
+
+ return op;
+}
+
+/**
+ * camel_op_free: free a CamelOp object allocated with camel_op_new
+ * @op: CamelOp object to free
+ *
+ * Free a CamelOp object allocated with camel_op_new ()
+ * this routine won't work with CamelOp objects allocated
+ * with other allocators.
+ **/
+void
+camel_op_free (CamelOp *op)
+{
+ g_free (op->params);
+ g_chunk_free (op, op_chunk);
+}
+
+
+/**
+ * camel_op_run: run an operation
+ * @op: the operation object
+ *
+ * run an operation
+ *
+ **/
+void
+camel_op_run (CamelOp *op)
+{
+ GtkArg *params;
+ gboolean error;
+
+ g_assert (op);
+ g_assert (op->func_def);
+ g_assert (op->params);
+
+ op->func_def->marshal (op->func, op->params);
+}
+
+
+
+
+/**
+ * camel_op_set_user_data: set the private field
+ * @op: operation
+ * @user_data: private field
+ *
+ * associate a field to an operation object
+ **/
+void
+camel_op_set_user_data (CamelOp *op, gpointer user_data)
+{
+ g_assert (op);
+ op->user_data = user_data;
+}
+
+
+/**
+ * camel_op_get_user_data: return the private field
+ * @op: operation object
+ *
+ * return the private field associated to
+ * an operation object.
+ *
+ * Return value:
+ **/
+gpointer
+camel_op_get_user_data (CamelOp *op)
+{
+ g_assert (op);
+ return op->user_data;
+}
@@ -166,3 +260,34 @@ void camel_marshal_NONE__POINTER_INT_POINTER (CamelFunc func,
GTK_VALUE_INT(args[1]),
GTK_VALUE_POINTER(args[2]));
}
+
+typedef void (*CamelMarshal_NONE__POINTER_INT_POINTER_POINTER) (gpointer arg1,
+ gint arg2,
+ gpointer arg3,
+ gpointer arg4);
+void camel_marshal_NONE__POINTER_INT_POINTER_POINTER (CamelFunc func,
+ GtkArg *args)
+{
+ CamelMarshal_NONE__POINTER_INT_POINTER_POINTER rfunc;
+ 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]));
+}
+
+
+typedef void (*CamelMarshal_NONE__INT) (gint arg1);
+void camel_marshal_NONE__INT (CamelFunc func,
+ GtkArg *args)
+{
+ CamelMarshal_NONE__INT rfunc;
+ rfunc = (CamelMarshal_NONE__INT) func;
+ (* rfunc) (GTK_VALUE_INT (args[0]));
+}
+
+
+
+
+
+
diff --git a/camel/camel-marshal-utils.h b/camel/camel-marshal-utils.h
index 158b72b1be..324f32e644 100644
--- a/camel/camel-marshal-utils.h
+++ b/camel/camel-marshal-utils.h
@@ -34,14 +34,19 @@ extern "C" {
#include <gtk/gtk.h>
+
typedef void (*CamelFunc) ();
-typedef gboolean ( *CamelMarshal) (CamelFunc func,
+typedef void ( *CamelMarshal) (CamelFunc func,
GtkArg *args);
+
+
+
+
typedef struct {
+
CamelMarshal marshal;
- CamelFunc func;
guint n_params;
GtkType *params_type;
@@ -49,7 +54,36 @@ typedef struct {
+typedef struct {
+ CamelFuncDef *func_def;
+ CamelFunc func;
+ GtkArg *params;
+ gpointer user_data;
+} CamelOp;
+
+
+CamelFuncDef *
+camel_func_def_new (CamelMarshal marshal,
+ guint n_params,
+ ...);
+
+
+CamelOp *camel_op_new (CamelFuncDef *func_def);
+void camel_op_free (CamelOp *op);
+void camel_op_run (CamelOp *op);
+void camel_op_run_and_free (CamelOp *op);
+void camel_op_set_user_data (CamelOp *op, gpointer user_data);
+gpointer camel_op_get_user_data (CamelOp *op);
+
+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_INT_POINTER_POINTER (CamelFunc func,
+ GtkArg *args);
+void camel_marshal_NONE__INT (CamelFunc func,
+ GtkArg *args);
#ifdef __cplusplus
}
diff --git a/camel/camel-op-queue.c b/camel/camel-op-queue.c
index 100a3df89e..a722c16f80 100644
--- a/camel/camel-op-queue.c
+++ b/camel/camel-op-queue.c
@@ -25,9 +25,6 @@
#include "camel-op-queue.h"
-#define NB_OP_CHUNKS 20
-static GMemChunk *op_chunk=NULL;
-
static GStaticMutex op_queue_mutex = G_STATIC_MUTEX_INIT;
@@ -44,12 +41,6 @@ camel_op_queue_new ()
{
CamelOpQueue *op_queue;
- g_static_mutex_lock (&op_queue_mutex);
- if (!op_chunk)
- op_chunk = g_mem_chunk_create (CamelOp,
- NB_OP_CHUNKS,
- G_ALLOC_AND_FREE);
- g_static_mutex_unlock (&op_queue_mutex);
op_queue = g_new (CamelOpQueue, 1);
op_queue->ops_tail = NULL;
@@ -162,59 +153,3 @@ camel_op_queue_get_service_availability (CamelOpQueue *queue)
return available;
}
-/**
- * camel_op_new: return a new CamelOp object
- *
- * The obtained object must be destroyed with
- * camel_op_free ()
- *
- * Return value: the newly allocated CamelOp object
- **/
-CamelOp *
-camel_op_new (CamelFuncDef *func_def)
-{
- CamelOp *op;
-
- op = g_chunk_new (CamelOp, op_chunk);
- op->func_def = func_def;
- op->params = g_new (GtkArg, func_def->n_params);
-
- return op;
-}
-
-/**
- * camel_op_free: free a CamelOp object allocated with camel_op_new
- * @op: CamelOp object to free
- *
- * Free a CamelOp object allocated with camel_op_new ()
- * this routine won't work with CamelOp objects allocated
- * with other allocators.
- **/
-void
-camel_op_free (CamelOp *op)
-{
- g_free (op->params);
- g_chunk_free (op, op_chunk);
-}
-
-
-/**
- * camel_op_run: run an operation
- * @op: the opertaion object
- *
- * run an operation
- *
- * Return value:
- **/
-gboolean
-camel_op_run (CamelOp *op)
-{
- GtkArg *params;
- gboolean error;
-
- g_assert (op);
- g_assert (op->func_def);
- g_assert (op->params);
-
- return (op->func_def->marshal (op->func_def->func, op->params));
-}
diff --git a/camel/camel-op-queue.h b/camel/camel-op-queue.h
index 9c91ca9297..f649532426 100644
--- a/camel/camel-op-queue.h
+++ b/camel/camel-op-queue.h
@@ -34,12 +34,6 @@ extern "C" {
-typedef struct {
- CamelFuncDef *func_def;
- GtkArg *params;
-} CamelOp;
-
-
typedef struct
{
GList *ops_head;
@@ -57,11 +51,6 @@ 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);
-CamelOp *camel_op_new (CamelFuncDef *func_def);
-void camel_op_free (CamelOp *op);
-gboolean camel_op_run (CamelOp *op);
-gboolean camel_op_run_and_free (CamelOp *op);
-
#ifdef __cplusplus
}
diff --git a/camel/camel.h b/camel/camel.h
index 33bd0bdd92..9950014f8b 100644
--- a/camel/camel.h
+++ b/camel/camel.h
@@ -38,10 +38,13 @@ extern "C" {
#include <camel/camel-data-wrapper.h>
#include <camel-simple-data-wrapper.h>
#include <camel-folder.h>
+#include <camel-folder-pt-proxy.h>
+#include <camel-marshal-utils.h>
#include <camel-mime-body-part.h>
#include <camel-mime-message.h>
#include <camel-mime-part.h>
#include <camel-multipart.h>
+#include <camel-op-queue.h>
#include <camel-provider.h>
#include <camel-service.h>
#include <camel-session.h>