[libgda] Correctly handle the case where a database provider can only be used by a unique thread



commit baa6d9de398b40d3e08d342b1aef9c42d5e6e3f5
Author: Vivien Malerba <malerba gnome-db org>
Date:   Mon Jul 12 19:21:16 2010 +0200

    Correctly handle the case where a database provider can only be used by a unique thread

 doc/C/prov-writing.xml                     |   15 ++++++++++-----
 libgda/gda-connection.c                    |   10 ++++++++--
 libgda/gda-server-provider.c               |    2 +-
 libgda/gda-server-provider.h               |    1 +
 libgda/sqlite/gda-sqlite-provider.c        |    2 +-
 providers/mysql/gda-mysql-provider.c       |    2 +-
 providers/postgres/gda-postgres-provider.c |    2 +-
 7 files changed, 23 insertions(+), 11 deletions(-)
---
diff --git a/doc/C/prov-writing.xml b/doc/C/prov-writing.xml
index 568f246..227a2e0 100644
--- a/doc/C/prov-writing.xml
+++ b/doc/C/prov-writing.xml
@@ -55,10 +55,11 @@
       is:
       <itemizedlist>
 	<listitem><para>if multi threading cannot be supported at all (for example if the client library internally
-	    used by the provider does not support it), then the provider should make sure it refuses to work
-	    if used from any thread different than the thread which created it, the provider's class implementation
-	    should set the class's <structfield>limiting_thread</structfield> attribute to the thread which created it
-	    using <link linkend="g-thread-self">g_thread_self()</link></para>
+	    used by the provider does not support it), then  the provider's
+	    class implementation should set the class's <structfield>limiting_thread</structfield> attribute to:
+	    the GDA_SERVER_PROVIDER_UNDEFINED_LIMITING_THREAD constant.
+	    This constant will be resolved at run time as the thread which creates the 1st connection using that
+	    provider.</para>
 	</listitem>
 	<listitem><para>if multi threading is supported but any connection (or related object) can only be 
 	    used by the thread in which it was created, then for each opened connection, the 
@@ -66,10 +67,14 @@
 	    must be set to the current thread (and other related objects must be locked in a similar way)</para>
 	</listitem>
 	<listitem><para>if no locking is done, then the provider is assumed to support full multi threading access,
-	  in this case make sure to set class's <structfield>limiting_thread</structfield> attribute to NULL.</para>
+	  in this case make sure to set class's <structfield>limiting_thread</structfield> attribute to the NULL constant.</para>
 	</listitem>
       </itemizedlist>
     </para>
+    <para>
+      Note that the default provider's class value for the <structfield>limiting_thread</structfield> is safely set to the
+      GDA_SERVER_PROVIDER_UNDEFINED_LIMITING_THREAD constant.
+    </para>
   </sect1>
 
   <sect1>
diff --git a/libgda/gda-connection.c b/libgda/gda-connection.c
index 6eed925..50f88a6 100644
--- a/libgda/gda-connection.c
+++ b/libgda/gda-connection.c
@@ -1102,8 +1102,8 @@ gda_connection_open_from_string (const gchar *provider_name, const gchar *cnc_st
 
 	g_return_val_if_fail (cnc_string && *cnc_string, NULL);
 
-	if (((options & GDA_CONNECTION_OPTIONS_THREAD_SAFE) || (options & GDA_CONNECTION_OPTIONS_THREAD_SAFE)) &&
-		!g_thread_supported ()) {
+	if (options & GDA_CONNECTION_OPTIONS_THREAD_SAFE &&
+	    !g_thread_supported ()) {
 		g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_UNSUPPORTED_THREADS_ERROR,
 			      "%s", _("Multi threading is not supported or enabled"));
 		return NULL;
@@ -1381,6 +1381,12 @@ gda_connection_open (GdaConnection *cnc, GError **error)
 		return FALSE;
 	}
 
+	/* if there is a limiting thread but it's not yet set, then initialize it to the current
+	 * thread */
+	if (PROV_CLASS (cnc->priv->provider_obj)->limiting_thread ==
+	    GDA_SERVER_PROVIDER_UNDEFINED_LIMITING_THREAD)
+		PROV_CLASS (cnc->priv->provider_obj)->limiting_thread = g_thread_self ();
+
 	if (PROV_CLASS (cnc->priv->provider_obj)->limiting_thread &&
 	    (PROV_CLASS (cnc->priv->provider_obj)->limiting_thread != g_thread_self ())) {
 		ThreadLookupData data;
diff --git a/libgda/gda-server-provider.c b/libgda/gda-server-provider.c
index dc01ce9..8255e51 100644
--- a/libgda/gda-server-provider.c
+++ b/libgda/gda-server-provider.c
@@ -118,7 +118,7 @@ gda_server_provider_class_init (GdaServerProviderClass *klass)
 	memset (&(klass->meta_funcs), 0, sizeof (GdaServerProviderMeta));
 	klass->xa_funcs = NULL;
 
-	klass->limiting_thread = g_thread_self (); /* default safe behaviour */
+	klass->limiting_thread = GDA_SERVER_PROVIDER_UNDEFINED_LIMITING_THREAD;
 
 	 /* Properties */
         object_class->set_property = gda_server_provider_set_property;
diff --git a/libgda/gda-server-provider.h b/libgda/gda-server-provider.h
index 9490752..de16cfe 100644
--- a/libgda/gda-server-provider.h
+++ b/libgda/gda-server-provider.h
@@ -222,6 +222,7 @@ typedef void (*GdaServerProviderAsyncCallback) (GdaServerProvider *provider, Gda
 typedef void (*GdaServerProviderExecCallback) (GdaServerProvider *provider, GdaConnection *cnc, guint task_id, 
 					       GObject *result_obj, const GError *error, gpointer data);
 
+#define GDA_SERVER_PROVIDER_UNDEFINED_LIMITING_THREAD ((gpointer)0x1)
 struct _GdaServerProviderClass {
 	GObjectClass parent_class;
 
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index e7c373d..27b7d5d 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -439,7 +439,7 @@ gda_sqlite_provider_class_init (GdaSqliteProviderClass *klass)
 	if (! SQLITE3_CALL (sqlite3_threadsafe) ()) {
 		gda_log_message ("SQLite was not compiled with the SQLITE_THREADSAFE flag, "
 				 "only one thread can access the provider");
-		provider_class->limiting_thread = g_thread_self ();
+		provider_class->limiting_thread = GDA_SERVER_PROVIDER_UNDEFINED_LIMITING_THREAD;
 	}
 	else
 		provider_class->limiting_thread = NULL;
diff --git a/providers/mysql/gda-mysql-provider.c b/providers/mysql/gda-mysql-provider.c
index 099aa4d..9899a42 100644
--- a/providers/mysql/gda-mysql-provider.c
+++ b/providers/mysql/gda-mysql-provider.c
@@ -348,7 +348,7 @@ gda_mysql_provider_class_init (GdaMysqlProviderClass  *klass)
 	if (!mysql_thread_safe ()) {
 		gda_log_message ("MySQL was not compiled with the --enable-thread-safe-client flag, "
 				 "only one thread can access the provider");
-		provider_class->limiting_thread = g_thread_self ();
+		provider_class->limiting_thread = GDA_SERVER_PROVIDER_UNDEFINED_LIMITING_THREAD;
 	}
 	else
 		provider_class->limiting_thread = NULL;
diff --git a/providers/postgres/gda-postgres-provider.c b/providers/postgres/gda-postgres-provider.c
index abadb87..909aa94 100644
--- a/providers/postgres/gda-postgres-provider.c
+++ b/providers/postgres/gda-postgres-provider.c
@@ -278,7 +278,7 @@ gda_postgres_provider_class_init (GdaPostgresProviderClass *klass)
 	if (! PQisthreadsafe ()) {
 		gda_log_message ("PostgreSQL was not compiled with the --enable-thread-safety flag, "
 				 "only one thread can access the provider");
-		provider_class->limiting_thread = g_thread_self ();
+		provider_class->limiting_thread = GDA_SERVER_PROVIDER_UNDEFINED_LIMITING_THREAD;
 	}
 	else
 		provider_class->limiting_thread = NULL;



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