[libgda] Thread-wrapped connection corrections



commit d46325b0f926f65b52cc7f9975d0b2bd52319bbf
Author: Vivien Malerba <malerba gnome-db org>
Date:   Sat Nov 19 17:42:18 2011 +0100

    Thread-wrapped connection corrections
    
    to be able to use any thread-wrapped connection even when it's closed,
    like for non thread-wrapped connections

 libgda/gda-connection-internal.h            |    7 +-
 libgda/gda-connection.c                     |   87 ++++++++++++-
 libgda/thread-wrapper/gda-thread-provider.c |  193 ++++++++++++++------------
 3 files changed, 192 insertions(+), 95 deletions(-)
---
diff --git a/libgda/gda-connection-internal.h b/libgda/gda-connection-internal.h
index 15f9194..96ffd45 100644
--- a/libgda/gda-connection-internal.h
+++ b/libgda/gda-connection-internal.h
@@ -71,8 +71,11 @@ typedef struct {
 	/* current async. tasks */
 	GSList *async_tasks; /* list of ThreadConnectionAsyncTask pointers */
 } ThreadConnectionData; /* Per connection private data for */
-void               _gda_connection_force_transaction_status (GdaConnection *cnc, GdaConnection *wrapped_cnc);
-GdaServerProvider *_gda_connection_get_internal_thread_provider (void);
+void                  _gda_thread_connection_set_data (GdaConnection *cnc, ThreadConnectionData *cdata);
+ThreadConnectionData *_gda_thread_connection_get_data (GdaConnection *cnc);
+void                  _gda_thread_connection_data_free (ThreadConnectionData *cdata);
+void                  _gda_connection_force_transaction_status (GdaConnection *cnc, GdaConnection *wrapped_cnc);
+GdaServerProvider    *_gda_connection_get_internal_thread_provider (void);
 
 /*
  * Used by virtual connections to keep meta data up to date when a table
diff --git a/libgda/gda-connection.c b/libgda/gda-connection.c
index 857da47..1a3d001 100644
--- a/libgda/gda-connection.c
+++ b/libgda/gda-connection.c
@@ -117,6 +117,8 @@ struct _GdaConnectionPrivate {
 	GArray               *trans_meta_context; /* Array of GdaMetaContext pointers */
 
 	gboolean              exec_times;
+
+	ThreadConnectionData *th_data; /* used if connection is used by the GdaThreadProvider, NULL otherwise */
 };
 
 /* represents an asynchronous execution task */
@@ -497,6 +499,11 @@ gda_connection_dispose (GObject *object)
 	cnc->priv->unique_possible_thread = NULL;
 	gda_connection_close_no_warning (cnc);
 
+	if (cnc->priv->th_data) {
+		_gda_thread_connection_data_free (cnc->priv->th_data);
+		cnc->priv->th_data = NULL;
+	}
+
 	/* get rid of prepared statements to avoid problems */
 	if (cnc->priv->prepared_stmts) {
 		g_hash_table_foreach (cnc->priv->prepared_stmts, 
@@ -663,6 +670,11 @@ gda_connection_set_property (GObject *object,
 
         cnc = GDA_CONNECTION (object);
         if (cnc->priv) {
+		if (cnc->priv->th_data && ! gda_connection_internal_get_provider_data (cnc)) {
+			_gda_thread_connection_data_free (cnc->priv->th_data);
+			cnc->priv->th_data = NULL;
+		}
+
                 switch (param_id) {
 		case PROP_THREAD_OWNER:
 			g_mutex_lock (cnc->priv->object_mutex);
@@ -685,6 +697,7 @@ gda_connection_set_property (GObject *object,
 			GdaDsnInfo *dsn;
 
 			gda_connection_lock ((GdaLockable*) cnc);
+			_gda_thread_connection_set_data (cnc, NULL);
 			if (cnc->priv->provider_data) {
 				g_warning (_("Could not set the '%s' property when the connection is opened"),
 					   pspec->name);
@@ -713,6 +726,7 @@ gda_connection_set_property (GObject *object,
 		}
                 case PROP_CNC_STRING:
 			gda_connection_lock ((GdaLockable*) cnc);
+			_gda_thread_connection_set_data (cnc, NULL);
 			if (cnc->priv->provider_data) {
 				g_warning (_("Could not set the '%s' property when the connection is opened"),
 					   pspec->name);
@@ -727,6 +741,7 @@ gda_connection_set_property (GObject *object,
                         break;
                 case PROP_PROVIDER_OBJ:
 			gda_connection_lock ((GdaLockable*) cnc);
+			_gda_thread_connection_set_data (cnc, NULL);
 			if (cnc->priv->provider_data) {
 				g_warning (_("Could not set the '%s' property when the connection is opened"),
 					   pspec->name);
@@ -742,6 +757,7 @@ gda_connection_set_property (GObject *object,
                         break;
                 case PROP_AUTH_STRING:
 			gda_connection_lock ((GdaLockable*) cnc);
+			_gda_thread_connection_set_data (cnc, NULL);
 			if (cnc->priv->provider_data) {
 				g_warning (_("Could not set the '%s' property when the connection is opened"),
 					   pspec->name);
@@ -761,12 +777,13 @@ gda_connection_set_property (GObject *object,
 			GdaConnectionOptions flags;
 			flags = g_value_get_flags (value);
 			gda_mutex_lock (cnc->priv->mutex);
+			_gda_thread_connection_set_data (cnc, NULL);
 			if (cnc->priv->provider_data &&
 			    ((flags & (~GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE)) !=
 			     (cnc->priv->options & (~GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE)))) {
 				g_warning (_("Can't set the '%s' property once the connection is opened"),
 					   pspec->name);
-				gda_connection_unlock ((GdaLockable*) cnc);
+				gda_mutex_unlock (cnc->priv->mutex);
 				return;
 			}
 			cnc->priv->options = flags;
@@ -1117,8 +1134,8 @@ gda_connection_new_from_dsn (const gchar *dsn, const gchar *auth_string,
 			}
 			else
 				cnc = g_object_new (GDA_TYPE_CONNECTION, 
-						    "provider", prov, 
-						    "dsn", real_dsn, 
+						    "provider", prov,
+						    "dsn", real_dsn,
 						    "auth-string", auth_string ? auth_string : real_auth_string, 
 						    "options", options, NULL);
 		}
@@ -1747,7 +1764,7 @@ gda_connection_close_no_warning (GdaConnection *cnc)
 	if (cnc->priv->provider_data) {
 		if (cnc->priv->provider_data_destroy_func)
 			cnc->priv->provider_data_destroy_func (cnc->priv->provider_data);
-		else
+		else if (cnc->priv->provider_data != cnc->priv->th_data)
 			g_warning ("Provider did not clean its connection data");
 		cnc->priv->provider_data = NULL;
 	}
@@ -6744,3 +6761,65 @@ _gda_connection_compute_table_virtual_name (GdaConnection *cnc, const gchar *tab
 	g_strfreev (array);
 	return g_string_free (string, FALSE);
 }
+
+/*
+ * Free connection's specific data
+ */
+static gpointer
+sub_thread_unref_connection (GdaConnection *cnc, G_GNUC_UNUSED GError **error)
+{
+	/* WARNING: function executed in sub thread! */
+	g_object_unref (cnc);
+#ifdef GDA_DEBUG_NO
+	g_print ("/%s()\n", __FUNCTION__);
+#endif
+	return NULL;
+}
+
+void
+_gda_thread_connection_data_free (ThreadConnectionData *cdata)
+{
+	if (!cdata)
+		return;
+
+	/* disconnect signals handlers */
+	gsize i;
+	for (i = 0; i < cdata->handlers_ids->len; i++) {
+		gulong hid = g_array_index (cdata->handlers_ids, gulong, i);
+		gda_thread_wrapper_disconnect (cdata->wrapper, hid);
+	}
+
+	/* unref cdata->sub_connection in sub thread */
+	guint jid;
+	jid = gda_thread_wrapper_execute (cdata->wrapper,
+					  (GdaThreadWrapperFunc) sub_thread_unref_connection,
+					  cdata->sub_connection, NULL, NULL);
+	gda_thread_wrapper_fetch_result (cdata->wrapper, TRUE, jid, NULL);
+	g_object_unref (cdata->wrapper);
+
+	/* free async data */
+	if (cdata->async_tasks) {
+		g_slist_foreach (cdata->async_tasks, (GFunc) _ThreadConnectionAsyncTask_free, NULL);
+		g_slist_free (cdata->async_tasks);
+	}
+
+	g_object_unref (cdata->cnc_provider);
+
+	g_free (cdata);
+}
+
+void
+_gda_thread_connection_set_data (GdaConnection *cnc, ThreadConnectionData *cdata)
+{
+	gda_mutex_lock (cnc->priv->mutex);
+	if (cnc->priv->th_data)
+		_gda_thread_connection_data_free (cnc->priv->th_data);
+	cnc->priv->th_data = cdata;
+	gda_mutex_unlock (cnc->priv->mutex);
+}
+
+ThreadConnectionData *
+_gda_thread_connection_get_data (GdaConnection *cnc)
+{
+	return cnc->priv->th_data;
+}
diff --git a/libgda/thread-wrapper/gda-thread-provider.c b/libgda/thread-wrapper/gda-thread-provider.c
index db67f36..a9c3a43 100644
--- a/libgda/thread-wrapper/gda-thread-provider.c
+++ b/libgda/thread-wrapper/gda-thread-provider.c
@@ -148,8 +148,6 @@ static gboolean gda_thread_provider_xa_rollback (GdaServerProvider *provider, Gd
 static GList   *gda_thread_provider_xa_recover  (GdaServerProvider *provider, GdaConnection *cnc, 
 						   GError **error);
 
-static void gda_thread_free_cnc_data (ThreadConnectionData *cdata);
-
 /*
  * GdaThreadProvider class implementation
  */
@@ -350,18 +348,18 @@ typedef struct {
 	GdaConnectionOptions options;
 
 	GdaServerProvider *out_cnc_provider;
-} OpenConnectionData;
+} NewConnectionData;
 
 static GdaConnection *
-sub_thread_open_connection (OpenConnectionData *data, GError **error)
+sub_thread_new_connection (NewConnectionData *data, GError **error)
 {
 	/* WARNING: function executed in sub thread! */
 	GdaConnection *cnc;
 	if (data->dsn)
-		cnc = gda_connection_open_from_dsn (data->dsn, data->auth_string, data->options, error);
+		cnc = gda_connection_new_from_dsn (data->dsn, data->auth_string, data->options, error);
 	else
-		cnc = gda_connection_open_from_string (data->prov_name, data->cnc_string, 
-						       data->auth_string, data->options, error);
+		cnc = gda_connection_new_from_string (data->prov_name, data->cnc_string, 
+						      data->auth_string, data->options, error);
 	if (cnc)
 		data->out_cnc_provider = gda_connection_get_provider (cnc);
 #ifdef GDA_DEBUG_NO
@@ -371,40 +369,26 @@ sub_thread_open_connection (OpenConnectionData *data, GError **error)
 }
 
 static void setup_signals (GdaConnection *cnc, ThreadConnectionData *cdata);
-
-static gboolean
-gda_thread_provider_open_connection (GdaServerProvider *provider, GdaConnection *cnc,
-				     GdaQuarkList *params, G_GNUC_UNUSED GdaQuarkList *auth,
-				     G_GNUC_UNUSED guint *task_id, GdaServerProviderAsyncCallback async_cb,
-				     G_GNUC_UNUSED gpointer cb_data)
+static ThreadConnectionData *
+create_connection_data (GdaServerProvider *provider, GdaConnection *cnc, GdaQuarkList *params)
 {
 	GdaThreadWrapper *wr = NULL;
 	gboolean wr_created = FALSE;
 
-	g_return_val_if_fail (GDA_IS_THREAD_PROVIDER (provider), FALSE);
-	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
-
-	/* If asynchronous connection opening is not supported, then exit now */
-	if (async_cb) {
-		gda_connection_add_event_string (cnc, 
-						 _("Provider does not support asynchronous connection open"));
-                return FALSE;
-	}
-
 	static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
 	g_static_mutex_lock (&mutex);
 
 	/* test if connection has to be opened using a DSN or a connection string */
 	gchar *dsn, *auth_string, *cnc_string;
 	GdaConnectionOptions options;
-	OpenConnectionData *data = NULL;
+	NewConnectionData *data = NULL;
 	g_object_get (cnc, "dsn", &dsn, 
-		      "auth_string", &auth_string,
+		      "auth-string", &auth_string,
 		      "cnc-string", &cnc_string, 
 		      "options", &options,
 		      NULL);
 	if (dsn) {
-		data = g_new0 (OpenConnectionData, 1);
+		data = g_new0 (NewConnectionData, 1);
 		data->dsn = dsn;
 		
 		GdaDsnInfo *dsninfo;
@@ -414,8 +398,15 @@ gda_thread_provider_open_connection (GdaServerProvider *provider, GdaConnection
 						  dsninfo->provider);
 	}
 	else if (cnc_string) {
-		data = g_new0 (OpenConnectionData, 1);
-		data->prov_name = gda_quark_list_find (params, "PROVIDER_NAME");
+		data = g_new0 (NewConnectionData, 1);
+		if (params)
+			data->prov_name = gda_quark_list_find (params, "PROVIDER_NAME");
+		else {
+			params = gda_quark_list_new_from_string (cnc_string);
+			data->prov_name = gda_quark_list_find (params, "PROVIDER_NAME");
+			gda_quark_list_free (params);
+			params = NULL;
+		}
 		data->cnc_string = cnc_string;
 		wr = g_hash_table_lookup (GDA_THREAD_PROVIDER (provider)->priv->prov_wrappers,
 					  data->prov_name);
@@ -429,7 +420,7 @@ gda_thread_provider_open_connection (GdaServerProvider *provider, GdaConnection
 			gda_connection_add_event_string (cnc, "%s", _("Multi threading is not supported or enabled"));
 			g_free (data);
 			g_static_mutex_unlock (&mutex);
-			return FALSE;
+			return NULL;
 		}
 	}
 	else {
@@ -446,7 +437,7 @@ gda_thread_provider_open_connection (GdaServerProvider *provider, GdaConnection
 	data->auth_string = auth_string;
 	data->options = options & (~(GDA_CONNECTION_OPTIONS_THREAD_ISOLATED | GDA_CONNECTION_OPTIONS_THREAD_SAFE));
 
-	jid = gda_thread_wrapper_execute (wr, (GdaThreadWrapperFunc) sub_thread_open_connection, data, NULL, NULL);
+	jid = gda_thread_wrapper_execute (wr, (GdaThreadWrapperFunc) sub_thread_new_connection, data, NULL, NULL);
 	sub_cnc = gda_thread_wrapper_fetch_result (wr, TRUE, jid, &error);
 	g_free (dsn);
 	g_free (cnc_string);
@@ -459,7 +450,7 @@ gda_thread_provider_open_connection (GdaServerProvider *provider, GdaConnection
 		g_free (data);
 		if (wr_created)
 			g_static_mutex_unlock (&mutex);
-		return FALSE;
+		return NULL;
 	}
 	
 	ThreadConnectionData *cdata;
@@ -470,7 +461,8 @@ gda_thread_provider_open_connection (GdaServerProvider *provider, GdaConnection
 	cdata->wrapper = wr;
 	cdata->handlers_ids = g_array_sized_new (FALSE, FALSE, sizeof (gulong), 2);
 	g_free (data);
-	gda_connection_internal_set_provider_data (cnc, cdata, (GDestroyNotify) gda_thread_free_cnc_data);
+	_gda_thread_connection_set_data (cnc, cdata);
+	gda_connection_internal_set_provider_data (cnc, cdata, NULL);
 	setup_signals (cnc, cdata);
 
 	if (wr_created) {
@@ -483,6 +475,59 @@ gda_thread_provider_open_connection (GdaServerProvider *provider, GdaConnection
 		g_static_mutex_unlock (&mutex);
 	}
 
+	return cdata;	
+}
+
+static gpointer
+sub_thread_open_connection (GdaConnection *sub_cnc, GError **error)
+{
+	/* WARNING: function executed in sub thread! */
+	gboolean retval;
+	retval = gda_connection_open (sub_cnc, error);
+
+#ifdef GDA_DEBUG_NO
+	g_print ("/%s() => %d\n", __FUNCTION__, retval);
+#endif
+	return retval ? (gpointer) 0x01 : NULL;
+}
+
+static gboolean
+gda_thread_provider_open_connection (GdaServerProvider *provider, GdaConnection *cnc,
+				     GdaQuarkList *params, G_GNUC_UNUSED GdaQuarkList *auth,
+				     G_GNUC_UNUSED guint *task_id, GdaServerProviderAsyncCallback async_cb,
+				     G_GNUC_UNUSED gpointer cb_data)
+{
+	g_return_val_if_fail (GDA_IS_THREAD_PROVIDER (provider), FALSE);
+	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
+
+	/* If asynchronous connection opening is not supported, then exit now */
+	if (async_cb) {
+		gda_connection_add_event_string (cnc, 
+						 _("Provider does not support asynchronous connection open"));
+                return FALSE;
+	}
+
+	ThreadConnectionData *cdata;
+	cdata =_gda_thread_connection_get_data (cnc);
+	if (!cdata)
+		cdata = create_connection_data (provider, cnc, params);
+	if (!cdata)
+		return FALSE;
+
+	gpointer result;
+	GError *error = NULL;
+	guint jid;
+	jid = gda_thread_wrapper_execute (cdata->wrapper,
+					  (GdaThreadWrapperFunc) sub_thread_open_connection, cdata->sub_connection,
+					  NULL, NULL);
+	result = gda_thread_wrapper_fetch_result (cdata->wrapper, TRUE, jid, &error);
+	if (!result) {
+		gda_connection_add_event_string (cnc, "%s", error && error->message ? error->message : _("No detail"));
+		if (error)
+			g_error_free (error);
+		return FALSE;
+	}
+	gda_connection_internal_set_provider_data (cnc, cdata, NULL);
 	return TRUE;
 }
 
@@ -522,7 +567,7 @@ _gda_thread_provider_handle_virtual_connection (GdaThreadProvider *provider, Gda
 	cdata->cnc_provider = g_object_ref (sub_prov);
 	cdata->wrapper = wr;
 	cdata->handlers_ids = g_array_sized_new (FALSE, FALSE, sizeof (gulong), 2);
-	gda_connection_internal_set_provider_data (cnc, cdata, (GDestroyNotify) gda_thread_free_cnc_data);
+	gda_connection_internal_set_provider_data (cnc, cdata, NULL);
 	setup_signals (cnc, cdata);
 
 	return cnc;
@@ -557,7 +602,7 @@ sub_cnc_closed_cb (G_GNUC_UNUSED GdaThreadWrapper *wrapper, G_GNUC_UNUSED GdaCon
 		   GdaConnection *wrapper_cnc)
 {
 	ThreadConnectionData *cdata;
-	cdata = (ThreadConnectionData*) gda_connection_internal_get_provider_data (wrapper_cnc);
+	cdata = _gda_thread_connection_get_data (wrapper_cnc);
 	if (!cdata) 
 		return;
 	cdata->sub_connection_has_closed = TRUE;
@@ -621,7 +666,9 @@ gda_thread_provider_close_connection (GdaServerProvider *provider, GdaConnection
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
 
-	cdata = (ThreadConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	cdata = _gda_thread_connection_get_data (cnc);
+	if (!cdata)
+		cdata = create_connection_data (provider, cnc, NULL);
 	if (!cdata) 
 		return FALSE;
 	
@@ -664,7 +711,9 @@ gda_thread_provider_get_server_version (GdaServerProvider *provider, GdaConnecti
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
 
-	cdata = (ThreadConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	cdata = _gda_thread_connection_get_data (cnc);
+	if (!cdata)
+		cdata = create_connection_data (provider, cnc, NULL);
 	if (!cdata) 
 		return NULL;
 	
@@ -706,7 +755,9 @@ gda_thread_provider_get_database (GdaServerProvider *provider, GdaConnection *cn
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
 
-	cdata = (ThreadConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	cdata = _gda_thread_connection_get_data (cnc);
+	if (!cdata)
+		cdata = create_connection_data (provider, cnc, NULL);
 	if (!cdata) 
 		return NULL;
 	
@@ -761,7 +812,9 @@ gda_thread_provider_supports_operation (GdaServerProvider *provider, GdaConnecti
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
 
-	cdata = (ThreadConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	cdata = _gda_thread_connection_get_data (cnc);
+	if (!cdata)
+		cdata = create_connection_data (provider, cnc, NULL);
 	if (!cdata) 
 		return FALSE;
 	
@@ -1328,7 +1381,9 @@ gda_thread_provider_get_data_handler (GdaServerProvider *provider, GdaConnection
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
 
-	cdata = (ThreadConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	cdata = _gda_thread_connection_get_data (cnc);
+	if (!cdata)
+		cdata = create_connection_data (provider, cnc, NULL);
 	if (!cdata) 
 		return FALSE;
 	
@@ -1377,7 +1432,9 @@ gda_thread_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConne
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
 
-	cdata = (ThreadConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	cdata = _gda_thread_connection_get_data (cnc);
+	if (!cdata)
+		cdata = create_connection_data (provider, cnc, NULL);
 	if (!cdata) 
 		return NULL;
 	
@@ -1424,8 +1481,10 @@ gda_thread_provider_create_parser (GdaServerProvider *provider, GdaConnection *c
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
 
-	cdata = (ThreadConnectionData*) gda_connection_internal_get_provider_data (cnc);
-	if (!cdata) 
+	cdata = _gda_thread_connection_get_data (cnc);
+	if (!cdata)
+		cdata = create_connection_data (provider, cnc, NULL);
+	if (!cdata)
 		return NULL;
 	
 	wdata.prov = cdata->cnc_provider;
@@ -2086,7 +2145,9 @@ gda_thread_provider_identifier_quote (GdaServerProvider *provider, GdaConnection
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
 
-	cdata = (ThreadConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	cdata = _gda_thread_connection_get_data (cnc);
+	if (!cdata)
+		cdata = create_connection_data (provider, cnc, NULL);
 	if (!cdata) 
 		return NULL;
 	
@@ -2101,49 +2162,3 @@ gda_thread_provider_identifier_quote (GdaServerProvider *provider, GdaConnection
 	res = gda_thread_wrapper_fetch_result (cdata->wrapper, TRUE, jid, NULL);
 	return res;
 }
-
-static gpointer
-sub_thread_unref_connection (GdaConnection *cnc, G_GNUC_UNUSED GError **error)
-{
-	/* WARNING: function executed in sub thread! */
-	g_object_unref (cnc);
-#ifdef GDA_DEBUG_NO
-	g_print ("/%s()\n", __FUNCTION__);
-#endif
-	return NULL;
-}
-
-/*
- * Free connection's specific data
- */
-static void
-gda_thread_free_cnc_data (ThreadConnectionData *cdata)
-{
-	if (!cdata)
-		return;
-
-	/* disconnect signals handlers */
-	gsize i;
-	for (i = 0; i < cdata->handlers_ids->len; i++) {
-		gulong hid = g_array_index (cdata->handlers_ids, gulong, i);
-		gda_thread_wrapper_disconnect (cdata->wrapper, hid);
-	}
-
-	/* unref cdata->sub_connection in sub thread */
-	guint jid;
-	jid = gda_thread_wrapper_execute (cdata->wrapper, 
-					  (GdaThreadWrapperFunc) sub_thread_unref_connection,
-					  cdata->sub_connection, NULL, NULL);
-	gda_thread_wrapper_fetch_result (cdata->wrapper, TRUE, jid, NULL);
-	g_object_unref (cdata->wrapper);
-
-	/* free async data */
-	if (cdata->async_tasks) {
-		g_slist_foreach (cdata->async_tasks, (GFunc) _ThreadConnectionAsyncTask_free, NULL);
-		g_slist_free (cdata->async_tasks);
-	}
-
-	g_object_unref (cdata->cnc_provider);
-
-	g_free (cdata);
-}



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