[libgda] Allow a virtual connection to be wrapped in a sub thread
- From: Vivien Malerba <vivien src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [libgda] Allow a virtual connection to be wrapped in a sub thread
- Date: Mon, 19 Oct 2009 18:41:38 +0000 (UTC)
commit 86b86f44c5b30d0cef260881538cddd3f3c41841
Author: Vivien Malerba <malerba gnome-db org>
Date: Mon Oct 12 21:07:21 2009 +0200
Allow a virtual connection to be wrapped in a sub thread
added gda_virtual_connection_open_extended()
doc/C/libgda-sections.txt | 1 +
doc/C/tmpl/gda-virtual-connection.sgml | 11 +++++
libgda/gda-connection-internal.h | 3 +-
libgda/gda-connection.c | 14 ++++++-
libgda/libgda.symbols | 1 +
libgda/sqlite/virtual/gda-virtual-connection.c | 48 +++++++++++++++++++++++
libgda/sqlite/virtual/gda-virtual-connection.h | 2 +
libgda/thread-wrapper/Makefile.am | 1 +
libgda/thread-wrapper/gda-thread-provider.c | 50 +++++++++++++++++++++++-
libgda/thread-wrapper/gda-thread-provider.h | 1 +
10 files changed, 129 insertions(+), 3 deletions(-)
---
diff --git a/doc/C/libgda-sections.txt b/doc/C/libgda-sections.txt
index 577cf54..3e591e7 100644
--- a/doc/C/libgda-sections.txt
+++ b/doc/C/libgda-sections.txt
@@ -560,6 +560,7 @@ gda_vprovider_hub_get_type
<TITLE>GdaVirtualConnection</TITLE>
GdaVirtualConnection
gda_virtual_connection_open
+gda_virtual_connection_open_extended
<SUBSECTION>
gda_virtual_connection_internal_set_provider_data
gda_virtual_connection_internal_get_provider_data
diff --git a/doc/C/tmpl/gda-virtual-connection.sgml b/doc/C/tmpl/gda-virtual-connection.sgml
index d896fe2..04f084a 100644
--- a/doc/C/tmpl/gda-virtual-connection.sgml
+++ b/doc/C/tmpl/gda-virtual-connection.sgml
@@ -33,6 +33,17 @@ This is a base virtual class for all virtual connection implementations
@Returns:
+<!-- ##### FUNCTION gda_virtual_connection_open_extended ##### -->
+<para>
+
+</para>
+
+ virtual_provider:
+ options:
+ error:
+ Returns:
+
+
<!-- ##### FUNCTION gda_virtual_connection_internal_set_provider_data ##### -->
<para>
diff --git a/libgda/gda-connection-internal.h b/libgda/gda-connection-internal.h
index 39a61bf..737eb5c 100644
--- a/libgda/gda-connection-internal.h
+++ b/libgda/gda-connection-internal.h
@@ -69,7 +69,8 @@ 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);
+void _gda_connection_force_transaction_status (GdaConnection *cnc, GdaConnection *wrapped_cnc);
+GdaServerProvider *_gda_connection_get_internal_thread_provider (void);
G_END_DECLS
diff --git a/libgda/gda-connection.c b/libgda/gda-connection.c
index 69ba8bb..292a3d3 100644
--- a/libgda/gda-connection.c
+++ b/libgda/gda-connection.c
@@ -299,7 +299,7 @@ gda_connection_class_init (GdaConnectionClass *klass)
NULL,
(G_PARAM_READABLE | G_PARAM_WRITABLE)));
g_object_class_install_property (object_class, PROP_OPTIONS,
- g_param_spec_flags ("options", NULL, _("Options (connection sharing)"),
+ g_param_spec_flags ("options", NULL, _("Options"),
GDA_TYPE_CONNECTION_OPTIONS, GDA_CONNECTION_OPTIONS_NONE,
(G_PARAM_READABLE | G_PARAM_WRITABLE)));
g_object_class_install_property (object_class, PROP_META_STORE,
@@ -822,6 +822,18 @@ cnc_task_free (CncTask *task)
}
/**
+ * _gda_connection_get_internal_thread_provider
+ */
+GdaServerProvider *
+_gda_connection_get_internal_thread_provider (void)
+{
+ if (!_gda_thread_wrapper_provider)
+ _gda_thread_wrapper_provider = GDA_SERVER_PROVIDER (g_object_new (GDA_TYPE_THREAD_PROVIDER, NULL));
+
+ return _gda_thread_wrapper_provider;
+}
+
+/**
* gda_connection_open_from_dsn
* @dsn: data source name.
* @auth_string: authentication string, or %NULL
diff --git a/libgda/libgda.symbols b/libgda/libgda.symbols
index de4e514..dbb7c2a 100644
--- a/libgda/libgda.symbols
+++ b/libgda/libgda.symbols
@@ -882,6 +882,7 @@
gda_virtual_connection_internal_get_provider_data
gda_virtual_connection_internal_set_provider_data
gda_virtual_connection_open
+ gda_virtual_connection_open_extended
gda_virtual_provider_get_type
gda_vprovider_data_model_get_type
gda_vprovider_data_model_new
diff --git a/libgda/sqlite/virtual/gda-virtual-connection.c b/libgda/sqlite/virtual/gda-virtual-connection.c
index 138da71..5124636 100644
--- a/libgda/sqlite/virtual/gda-virtual-connection.c
+++ b/libgda/sqlite/virtual/gda-virtual-connection.c
@@ -26,6 +26,8 @@
#include <sqlite3.h>
#include "gda-virtual-connection.h"
#include <gda-connection-private.h>
+#include <libgda/gda-connection-internal.h>
+#include <libgda/thread-wrapper/gda-thread-provider.h>
#define PARENT_TYPE GDA_TYPE_CONNECTION
#define CLASS(obj) (GDA_VIRTUAL_CONNECTION_CLASS (G_OBJECT_GET_CLASS (obj)))
@@ -153,6 +155,52 @@ gda_virtual_connection_open (GdaVirtualProvider *virtual_provider, GError **erro
}
/**
+ * gda_virtual_connection_open_extended
+ * @virtual_provider: a #GdaVirtualProvider object
+ * @options: a set of options to specify the new connection
+ * @error: a place to store errors, or %NULL
+ *
+ * Creates and opens a new virtual connection using the @virtual_provider provider. If @options
+ * contains the %GDA_CONNECTION_OPTIONS_THREAD_SAFE flag, then the returned connection will be
+ * a thread wrapped connection, and the actual (wrapped) virtual connection can be obtained through
+ * the "gda-virtual-connection" user property (use g_object_get_data() to get it).
+ *
+ * Returns: a new #GdaConnection object, or %NULL if an error occurred
+ */
+GdaConnection *
+gda_virtual_connection_open_extended (GdaVirtualProvider *virtual_provider, GdaConnectionOptions options, GError **error)
+{
+ GdaConnection *cnc = NULL;
+ g_return_val_if_fail (GDA_IS_VIRTUAL_PROVIDER (virtual_provider), NULL);
+
+ if (PROV_CLASS (virtual_provider)->create_connection) {
+ cnc = PROV_CLASS (virtual_provider)->create_connection ((GdaServerProvider*) virtual_provider);
+ if (cnc) {
+ g_object_set (G_OBJECT (cnc), "provider", virtual_provider,
+ "options", options & (~GDA_CONNECTION_OPTIONS_THREAD_SAFE), NULL);
+ if (!gda_connection_open (cnc, error)) {
+ g_object_unref (cnc);
+ cnc = NULL;
+ }
+ }
+ }
+ else
+ g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_PROVIDER_ERROR, "%s",
+ _("Internal error: virtual provider does not implement the create_operation() virtual method"));
+
+ if (cnc && (options & GDA_CONNECTION_OPTIONS_THREAD_SAFE)) {
+ GdaConnection *wcnc;
+ wcnc = _gda_thread_provider_handle_virtual_connection (GDA_THREAD_PROVIDER (_gda_connection_get_internal_thread_provider ()),
+ cnc);
+ g_object_set_data (G_OBJECT (wcnc), "gda-virtual-connection", cnc);
+ g_object_unref (cnc);
+ cnc = wcnc;
+ }
+
+ return cnc;
+}
+
+/**
* gda_virtual_connection_internal_set_provider_data
* @vcnc: a #GdaConnection object
* @data: an opaque structure, known only to the provider for which @vcnc is opened
diff --git a/libgda/sqlite/virtual/gda-virtual-connection.h b/libgda/sqlite/virtual/gda-virtual-connection.h
index ddf847f..1f7e50c 100644
--- a/libgda/sqlite/virtual/gda-virtual-connection.h
+++ b/libgda/sqlite/virtual/gda-virtual-connection.h
@@ -55,6 +55,8 @@ struct _GdaVirtualConnectionClass {
GType gda_virtual_connection_get_type (void) G_GNUC_CONST;
GdaConnection *gda_virtual_connection_open (GdaVirtualProvider *virtual_provider, GError **error);
+GdaConnection *gda_virtual_connection_open_extended (GdaVirtualProvider *virtual_provider,
+ GdaConnectionOptions options, GError **error);
void gda_virtual_connection_internal_set_provider_data (GdaVirtualConnection *vcnc,
gpointer data, GDestroyNotify destroy_func);
gpointer gda_virtual_connection_internal_get_provider_data (GdaVirtualConnection *cnc);
diff --git a/libgda/thread-wrapper/Makefile.am b/libgda/thread-wrapper/Makefile.am
index 6ca6725..6a4fb0b 100644
--- a/libgda/thread-wrapper/Makefile.am
+++ b/libgda/thread-wrapper/Makefile.am
@@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libgda_threadwrapper-4.0.la
AM_CPPFLAGS = \
-I$(top_srcdir) -I$(srcdir)/.. \
+ -I$(top_srcdir)/libgda/sqlite \
-I$(top_builddir) \
$(LIBGDA_CFLAGS)
diff --git a/libgda/thread-wrapper/gda-thread-provider.c b/libgda/thread-wrapper/gda-thread-provider.c
index a8775c0..2bb15c6 100644
--- a/libgda/thread-wrapper/gda-thread-provider.c
+++ b/libgda/thread-wrapper/gda-thread-provider.c
@@ -36,6 +36,8 @@
#include "gda-thread-meta.h"
#include "gda-thread-wrapper.h"
#include "gda-thread-recordset.h"
+#include <libgda/sqlite/virtual/gda-virtual-provider.h>
+#include <libgda/sqlite/virtual/gda-virtual-connection.h>
#define PROV_CLASS(provider) (GDA_SERVER_PROVIDER_CLASS (G_OBJECT_GET_CLASS (provider)))
@@ -434,7 +436,7 @@ gda_thread_provider_open_connection (GdaServerProvider *provider, GdaConnection
ThreadConnectionData *cdata;
cdata = g_new0 (ThreadConnectionData, 1);
cdata->sub_connection = sub_cnc;
- cdata->cnc_provider = data->out_cnc_provider;
+ cdata->cnc_provider = g_object_ref (data->out_cnc_provider);
cdata->wrapper = wr;
cdata->handlers_ids = g_array_sized_new (FALSE, FALSE, sizeof (gulong), 2);
g_free (data);
@@ -451,6 +453,49 @@ gda_thread_provider_open_connection (GdaServerProvider *provider, GdaConnection
return TRUE;
}
+/**
+ * _gda_thread_provider_handle_virtual_connection
+ * @provider: a #GdaThreadProvider provider
+ * @sub_cnc: a #GdaConnection which has already been opened, normally a virtual connection
+ *
+ * Creates a new connection, wrapping @sub_cnc which has to be a virtual connection. @sub_cnc's
+ * reference count is incremented by this call.
+ *
+ * Returns: a new #GdaConnection, or %NULL if an error occurred.
+ */
+GdaConnection *
+_gda_thread_provider_handle_virtual_connection (GdaThreadProvider *provider, GdaConnection *sub_cnc)
+{
+ ThreadConnectionData *cdata;
+ GdaServerProvider *sub_prov;
+ GdaThreadWrapper *wr;
+ gboolean wr_created = FALSE;
+ GdaConnection *cnc;
+
+ g_return_val_if_fail (GDA_IS_THREAD_PROVIDER (provider), NULL);
+ g_return_val_if_fail (GDA_IS_VIRTUAL_CONNECTION (sub_cnc), NULL);
+
+ sub_prov = gda_connection_get_provider (sub_cnc);
+ g_return_val_if_fail (GDA_IS_VIRTUAL_PROVIDER (sub_prov), NULL);
+ wr = gda_thread_wrapper_new ();
+ if (!wr) {
+ g_warning (_("Multi threading is not supported or enabled"));
+ return NULL;
+ }
+
+ cnc = gda_thread_provider_create_connection (GDA_SERVER_PROVIDER (provider));
+
+ cdata = g_new0 (ThreadConnectionData, 1);
+ cdata->sub_connection = g_object_ref (sub_cnc);
+ 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);
+ setup_signals (cnc, cdata);
+
+ return cnc;
+}
+
static void
sub_cnc_error_cb (GdaThreadWrapper *wrapper, GdaConnection *sub_cnc, const gchar *signal,
gint n_param_values, const GValue *param_values,
@@ -1975,5 +2020,8 @@ gda_thread_free_cnc_data (ThreadConnectionData *cdata)
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);
}
diff --git a/libgda/thread-wrapper/gda-thread-provider.h b/libgda/thread-wrapper/gda-thread-provider.h
index fd857ef..7a680ba 100644
--- a/libgda/thread-wrapper/gda-thread-provider.h
+++ b/libgda/thread-wrapper/gda-thread-provider.h
@@ -51,6 +51,7 @@ struct _GdaThreadProviderClass {
G_BEGIN_DECLS
GType _gda_thread_provider_get_type (void) G_GNUC_CONST;
+GdaConnection *_gda_thread_provider_handle_virtual_connection (GdaThreadProvider *provider, GdaConnection *sub_cnc);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]