[libgda] Modified gda_thread_wrapper_connect_raw()



commit 6401e75f1570cc3aaaa591077805900708e75480
Author: Vivien Malerba <malerba gnome-db org>
Date:   Wed Jul 7 16:52:33 2010 +0200

    Modified gda_thread_wrapper_connect_raw()
    
    it is now possible to specify if a signal can be caught if emitted in any thread

 doc/C/tmpl/gda-thread-wrapper.sgml          |    3 +-
 libgda/thread-wrapper/gda-thread-provider.c |   14 +++---
 libgda/thread-wrapper/gda-thread-wrapper.c  |   71 ++++++++++++++++++++++-----
 libgda/thread-wrapper/gda-thread-wrapper.h  |    3 +-
 tests/multi-threading/check_wrapper.c       |    6 +-
 5 files changed, 73 insertions(+), 24 deletions(-)
---
diff --git a/doc/C/tmpl/gda-thread-wrapper.sgml b/doc/C/tmpl/gda-thread-wrapper.sgml
index 119b8e3..7687d38 100644
--- a/doc/C/tmpl/gda-thread-wrapper.sgml
+++ b/doc/C/tmpl/gda-thread-wrapper.sgml
@@ -185,7 +185,8 @@ Execute functions in a sub thread
 @wrapper: 
 @instance: 
 @sig_name: 
- private: 
+ private_thread: 
+ private_job: 
 @callback: 
 @data: 
 @Returns: 
diff --git a/libgda/thread-wrapper/gda-thread-provider.c b/libgda/thread-wrapper/gda-thread-provider.c
index e09c3ea..aba0de6 100644
--- a/libgda/thread-wrapper/gda-thread-provider.c
+++ b/libgda/thread-wrapper/gda-thread-provider.c
@@ -1,5 +1,5 @@
 /* GDA Thread provider
- * Copyright (C) 2009 The GNOME Foundation.
+ * Copyright (C) 2009 - 2010 The GNOME Foundation.
  *
  * AUTHORS:
  *      Vivien Malerba <malerba gnome-db org>
@@ -564,17 +564,17 @@ setup_signals (GdaConnection *cnc, ThreadConnectionData *cdata)
 {
 	gulong hid;
 	hid = gda_thread_wrapper_connect_raw (cdata->wrapper, cdata->sub_connection,
-					      "conn-closed", FALSE,
+					      "conn-closed", TRUE, FALSE,
 					      (GdaThreadWrapperCallback) sub_cnc_closed_cb, cnc);
 	g_array_prepend_val (cdata->handlers_ids, hid);
 
 	hid = gda_thread_wrapper_connect_raw (cdata->wrapper, cdata->sub_connection,
-					      "error", FALSE,
+					      "error", TRUE, FALSE,
 					      (GdaThreadWrapperCallback) sub_cnc_error_cb, cnc);
 	g_array_prepend_val (cdata->handlers_ids, hid);
 
 	hid = gda_thread_wrapper_connect_raw (cdata->wrapper, cdata->sub_connection,
-					      "transaction-status-changed", FALSE,
+					      "transaction-status-changed", TRUE, FALSE,
 					      (GdaThreadWrapperCallback) sub_cnc_transaction_status_changed_cb,
 					      cnc);
 	g_array_prepend_val (cdata->handlers_ids, hid);
@@ -2088,9 +2088,9 @@ gda_thread_free_cnc_data (ThreadConnectionData *cdata)
 
 	/* unref cdata->sub_connection in sub thread */
 	guint jid;
-	jid = gda_thread_wrapper_execute (cdata->wrapper, 
-					  (GdaThreadWrapperVoidFunc) sub_thread_unref_connection,
-					  cdata->sub_connection, NULL, NULL);
+	jid = gda_thread_wrapper_execute_void (cdata->wrapper, 
+					       (GdaThreadWrapperVoidFunc) sub_thread_unref_connection,
+					       cdata->sub_connection, NULL, NULL);
 	gda_thread_wrapper_fetch_result (cdata->wrapper, TRUE, jid, NULL);
 	g_object_unref (cdata->wrapper);
 
diff --git a/libgda/thread-wrapper/gda-thread-wrapper.c b/libgda/thread-wrapper/gda-thread-wrapper.c
index 864dada..beaa767 100644
--- a/libgda/thread-wrapper/gda-thread-wrapper.c
+++ b/libgda/thread-wrapper/gda-thread-wrapper.c
@@ -1,5 +1,5 @@
 /* GDA library
- * Copyright (C) 2009 The GNOME Foundation.
+ * Copyright (C) 2009 - 2010 The GNOME Foundation.
  *
  * AUTHORS:
  *      Vivien Malerba <malerba gnome-db org>
@@ -924,8 +924,7 @@ worker_thread_closure_marshal (GClosure *closure,
 	if (g_thread_self () !=  sigspec->worker_thread)
 		return;
 
-	/* check that the worker thread is working on a job for which job->reply_queue == sigspec->reply_queue */
-	if (sigspec->private &&
+	/* check that the worker thread is working on a job for which job->reply_queue == sigspec->reply_queue */	if (sigspec->private &&
 	    g_static_private_get (&worker_thread_current_queue) != sigspec->reply_queue)
 		return;
 
@@ -957,14 +956,62 @@ worker_thread_closure_marshal (GClosure *closure,
 	signal_spec_unlock (sigspec);
 }
 
+/* 
+ * Executed in sub thread (or potentially in other threads, in which case will be ignored)
+ * pushes data into the queue 
+ */
+static void
+worker_thread_closure_marshal_anythread (GClosure *closure,
+					 GValue *return_value,
+					 guint n_param_values,
+					 const GValue *param_values,
+					 gpointer invocation_hint,
+					 gpointer marshal_data)
+{
+	SignalSpec *sigspec = (SignalSpec *) closure->data;
+
+	gint i;
+	/*
+	  for (i = 1; i < n_param_values; i++) {
+		g_print ("\t%d => %s\n", i, gda_value_stringify (param_values + i));
+	}
+	*/
+	Job *job= g_new0 (Job, 1);
+	job->type = JOB_TYPE_SIGNAL;
+	job->u.signal.spec = signal_spec_ref (sigspec);
+	job->u.signal.n_param_values = n_param_values - 1;
+	job->u.signal.param_values = g_new0 (GValue, job->u.signal.n_param_values);
+	for (i = 1; i < n_param_values; i++) {
+		const GValue *src;
+		GValue *dest;
+
+		src = param_values + i;
+		dest = job->u.signal.param_values + i - 1;
+
+		if (G_VALUE_TYPE (src) != GDA_TYPE_NULL) {
+			g_value_init (dest, G_VALUE_TYPE (src));
+			g_value_copy (src, dest);
+		}
+	}
+
+	g_async_queue_push (sigspec->reply_queue, job);
+	signal_spec_unlock (sigspec);
+}
+
 /**
  * gda_thread_wrapper_connect_raw
  * @wrapper: a #GdaThreadWrapper object
  * @instance: the instance to connect to
  * @sig_name: a string of the form "signal-name::detail"
- * @private: set to %TRUE if @callback is to be invoked only if the signal has
+ * @private_thread:  set to %TRUE if @callback is to be invoked only if the signal has
+ *    been emitted while in @wrapper's private sub thread (ie. used when @wrapper is executing some functions
+ *    specified by gda_thread_wrapper_execute() or gda_thread_wrapper_execute_void()), and to %FALSE if the
+ *    callback is to be invoked whenever the signal is emitted, independently of th thread in which the
+ *    signal is emitted.
+ * @private_job: set to %TRUE if @callback is to be invoked only if the signal has
  *    been emitted when a job created for the calling thread is being executed, and to %FALSE
- *    if @callback has to be called whenever the @sig_name signa is emitted by @instance.
+ *    if @callback has to be called whenever the @sig_name signal is emitted by @instance. Note that
+ *    this argument is not taken into account if @private_thread is set to %FALSE.
  * @callback: a #GdaThreadWrapperCallback function
  * @data: data to pass to @callback's calls
  *
@@ -976,10 +1023,6 @@ worker_thread_closure_marshal (GClosure *closure,
  *  <listitem><para>the signal handler must not have to return any value</para></listitem>
  *  <listitem><para>the @callback function will be called asynchronously, the caller may need to use 
  *    gda_thread_wrapper_iterate() to get the notification</para></listitem>
- *  <listitem><para>the @callback function will be called only if the signal has been emitted by @instance 
- *    while being used in @wrapper's private sub thread (ie. used when @wrapper is executing some functions
- *    specified by
- *    gda_thread_wrapper_execute() or gda_thread_wrapper_execute_void())</para></listitem>
  *  <listitem><para>if @private is set to %TRUE, then the @callback function will be called only
  *    if the signal has been emitted by @instance while doing a job on behalf of the current
  *    calling thread. If @private is set to %FALSE, then @callback will be called whenever @instance
@@ -1001,7 +1044,8 @@ worker_thread_closure_marshal (GClosure *closure,
 gulong
 gda_thread_wrapper_connect_raw (GdaThreadWrapper *wrapper,
 				gpointer instance,
-				const gchar *sig_name, gboolean private,
+				const gchar *sig_name,
+				gboolean private_thread, gboolean private_job,
 				GdaThreadWrapperCallback callback,
 				gpointer data)
 {
@@ -1024,7 +1068,7 @@ gda_thread_wrapper_connect_raw (GdaThreadWrapper *wrapper,
         }
 
         sigspec = g_new0 (SignalSpec, 1);
-	sigspec->private = private;
+	sigspec->private = private_job;
         g_signal_query (sigid, (GSignalQuery*) sigspec);
 
 	if (((GSignalQuery*) sigspec)->return_type != G_TYPE_NONE) {
@@ -1042,7 +1086,10 @@ gda_thread_wrapper_connect_raw (GdaThreadWrapper *wrapper,
 
 	GClosure *cl;
 	cl = g_closure_new_simple (sizeof (GClosure), sigspec);
-	g_closure_set_marshal (cl, (GClosureMarshal) worker_thread_closure_marshal);
+	if (private_thread)
+		g_closure_set_marshal (cl, (GClosureMarshal) worker_thread_closure_marshal);
+	else
+		g_closure_set_marshal (cl, (GClosureMarshal) worker_thread_closure_marshal_anythread);
 	sigspec->signal_id = g_signal_connect_closure (instance, sig_name, cl, FALSE);
 
 	td->signals_list = g_slist_append (td->signals_list, sigspec);
diff --git a/libgda/thread-wrapper/gda-thread-wrapper.h b/libgda/thread-wrapper/gda-thread-wrapper.h
index 534fb8c..dd32a82 100644
--- a/libgda/thread-wrapper/gda-thread-wrapper.h
+++ b/libgda/thread-wrapper/gda-thread-wrapper.h
@@ -83,7 +83,8 @@ gint                   gda_thread_wrapper_get_waiting_size (GdaThreadWrapper *wr
 
 gulong                 gda_thread_wrapper_connect_raw       (GdaThreadWrapper *wrapper,
 							     gpointer instance,
-							     const gchar *sig_name, gboolean private,
+							     const gchar *sig_name,
+							     gboolean private_thread, gboolean private_job,
 							     GdaThreadWrapperCallback callback,
 							     gpointer data);
 void                   gda_thread_wrapper_disconnect       (GdaThreadWrapper *wrapper, gulong id);
diff --git a/tests/multi-threading/check_wrapper.c b/tests/multi-threading/check_wrapper.c
index d638289..0658266 100644
--- a/tests/multi-threading/check_wrapper.c
+++ b/tests/multi-threading/check_wrapper.c
@@ -526,13 +526,13 @@ t2_main_thread_func (DummyObject *dummy)
 	GSList *received_list = NULL;
 
 	/*g_print ("NEW test thread: %p\n", g_thread_self());*/
-	sigid[0] = gda_thread_wrapper_connect_raw (wrapper, dummy, "sig0", TRUE,
+	sigid[0] = gda_thread_wrapper_connect_raw (wrapper, dummy, "sig0", TRUE, TRUE,
 						   (GdaThreadWrapperCallback) wrapper_callback,
 						   &received_list);
-	sigid[1] = gda_thread_wrapper_connect_raw (wrapper, dummy, "sig1", TRUE,
+	sigid[1] = gda_thread_wrapper_connect_raw (wrapper, dummy, "sig1", TRUE, TRUE,
 						   (GdaThreadWrapperCallback) wrapper_callback,
 						   &received_list);
-	sigid[2] = gda_thread_wrapper_connect_raw (wrapper, dummy, "sig2", TRUE,
+	sigid[2] = gda_thread_wrapper_connect_raw (wrapper, dummy, "sig2", TRUE, TRUE,
 						   (GdaThreadWrapperCallback) wrapper_callback,
 						   &received_list);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]