[libgda] GdaVconnectionDataModel: fix weak ref implementation
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] GdaVconnectionDataModel: fix weak ref implementation
- Date: Wed, 9 Oct 2019 23:57:36 +0000 (UTC)
commit ae3dadff8a607e0f4fd8bc430aca6935f4827a2d
Author: Daniel Espinosa <esodan gmail com>
Date: Wed Oct 9 18:56:12 2019 -0500
GdaVconnectionDataModel: fix weak ref implementation
Fixes on VContext->context_object to use just GWeakRef
.../virtual/gda-vconnection-data-model-private.h | 2 +-
libgda/sqlite/virtual/gda-vconnection-data-model.c | 119 ++++++++++-----------
2 files changed, 56 insertions(+), 65 deletions(-)
---
diff --git a/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
b/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
index 90ddf2977..1d50290f1 100644
--- a/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
+++ b/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
@@ -40,7 +40,7 @@ typedef struct VirtualFilteredData VirtualFilteredData;
struct VContext{
GWeakRef context_object;
- GPtrArray *context_data;
+ GPtrArray *context_data;
GdaVConnectionTableData *vtable;
};
diff --git a/libgda/sqlite/virtual/gda-vconnection-data-model.c
b/libgda/sqlite/virtual/gda-vconnection-data-model.c
index 1ef1130e1..823396049 100644
--- a/libgda/sqlite/virtual/gda-vconnection-data-model.c
+++ b/libgda/sqlite/virtual/gda-vconnection-data-model.c
@@ -1,9 +1,8 @@
/*
- * Copyright (C) 2007 - 2014 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2007 - 2013 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2008 - 2011 Murray Cumming <murrayc murrayc com>
* Copyright (C) 2009 Bas Driessen <bas driessen xobas com>
* Copyright (C) 2010 David King <davidk openismus com>
- * Copyright (C) 2018 Daniel Espinosa <esodan gmail com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,7 +21,6 @@
*/
#include <glib/gi18n-lib.h>
-#include <glib.h>
#include <string.h>
#include "gda-vconnection-data-model.h"
#include "gda-vconnection-data-model-private.h"
@@ -31,12 +29,13 @@
#include <libgda/gda-connection-internal.h>
#include "../gda-sqlite.h"
-
+static void gda_vconnection_data_model_class_init (GdaVconnectionDataModelClass *klass);
+static void gda_vconnection_data_model_init (GdaVconnectionDataModel *cnc);
static void gda_vconnection_data_model_dispose (GObject *object);
+
typedef struct {
- GSList *table_data_list; /* list of GdaVConnectionTableData structures */
- gboolean being_disposed;
+ GSList *table_data_list; /* list of GdaVConnectionTableData structures */
GMutex lock_context;
GdaStatement *executed_stmt;
@@ -44,6 +43,7 @@ typedef struct {
G_DEFINE_TYPE_WITH_PRIVATE (GdaVconnectionDataModel, gda_vconnection_data_model, GDA_TYPE_VIRTUAL_CONNECTION)
+
static gboolean get_rid_of_vtable (GdaVconnectionDataModel *cnc, GdaVConnectionTableData *td, gboolean
force, GError **error);
enum {
@@ -54,14 +54,15 @@ enum {
static gint gda_vconnection_data_model_signals[LAST_SIGNAL] = { 0, 0 };
+static GObjectClass *parent_class = NULL;
+
#ifdef GDA_DEBUG_NO
static void
dump_all_tables (GdaVconnectionDataModel *cnc)
{
- GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
GSList *list;
g_print ("GdaVconnectionDataModel's tables:\n");
- for (list = priv->table_data_list; list; list = list->next) {
+ for (list = cnc->priv->table_data_list; list; list = list->next) {
GdaVConnectionTableData *td = (GdaVConnectionTableData *) list->data;
g_print (" table %s, td=%p, spec=%p\n", td->table_name, td, td->spec);
}
@@ -81,13 +82,11 @@ static void
vtable_dropped (GdaVconnectionDataModel *cnc, const gchar *table_name)
{
GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
-
GdaVConnectionTableData *td;
td = _gda_vconnection_get_table_data_by_name (cnc, table_name);
if (td)
priv->table_data_list = g_slist_remove (priv->table_data_list, td);
- if (! priv->being_disposed)
- _gda_connection_signal_meta_table_update ((GdaConnection *)cnc, table_name);
+ _gda_connection_signal_meta_table_update ((GdaConnection *)cnc, table_name);
#ifdef GDA_DEBUG_NO
dump_all_tables (cnc);
#endif
@@ -101,6 +100,8 @@ gda_vconnection_data_model_class_init (GdaVconnectionDataModelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ parent_class = g_type_class_peek_parent (klass);
+
/**
* GdaVconnectionDataModel::vtable-created
* @cnc: the #GdaVconnectionDataModel connection
@@ -142,8 +143,8 @@ static void
gda_vconnection_data_model_init (GdaVconnectionDataModel *cnc)
{
GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
+ priv = g_new (GdaVconnectionDataModelPrivate, 1);
priv->table_data_list = NULL;
- priv->being_disposed = FALSE;
g_mutex_init (& (priv->lock_context));
g_object_set (G_OBJECT (cnc), "cnc-string", "_IS_VIRTUAL=TRUE", NULL);
@@ -153,26 +154,22 @@ static void
gda_vconnection_data_model_dispose (GObject *object)
{
GdaVconnectionDataModel *cnc = (GdaVconnectionDataModel *) object;
+ g_return_if_fail (GDA_IS_VCONNECTION_DATA_MODEL (cnc));
GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
- g_return_if_fail (GDA_IS_VCONNECTION_DATA_MODEL (cnc));
+ /* free memory */
if (priv->table_data_list != NULL) {
- /* free memory */
- priv->being_disposed = TRUE;
while (priv->table_data_list) {
GdaVConnectionTableData *td;
td = (GdaVConnectionTableData *) priv->table_data_list->data;
get_rid_of_vtable (cnc, td, TRUE, NULL);
}
- priv->table_data_list = NULL;
}
- gda_connection_close ((GdaConnection *) cnc, NULL);
-
- g_mutex_clear (& (priv->lock_context));
+ g_mutex_clear (&(priv->lock_context));
/* chain to parent class */
- G_OBJECT_CLASS (gda_vconnection_data_model_parent_class)->dispose (object);
+ parent_class->dispose (object);
}
static void
@@ -217,13 +214,13 @@ gboolean
gda_vconnection_data_model_add_model (GdaVconnectionDataModel *cnc,
GdaDataModel *model, const gchar *table_name, GError **error)
{
+ g_return_val_if_fail (GDA_IS_DATA_MODEL (model), FALSE);
GdaVconnectionDataModelSpec *spec;
gboolean retval;
spec = g_new0 (GdaVconnectionDataModelSpec, 1);
- spec->data_model = model;
+ spec->data_model = g_object_ref (model);
spec->create_columns_func = create_columns;
- g_object_ref (model);
retval = gda_vconnection_data_model_add (cnc, spec, (GDestroyNotify) spec_destroy_func, table_name,
error);
return retval;
@@ -233,7 +230,7 @@ gda_vconnection_data_model_add_model (GdaVconnectionDataModel *cnc,
* gda_vconnection_data_model_add:
* @cnc: a #GdaVconnectionDataModel connection
* @spec: a #GdaVconnectionDataModelSpec structure, used AS IS (not copied) and can be modified
- * @spec_free_func: (nullable): function to call when freeing @spec, or %NULL
+ * @spec_free_func: (allow-none): function to call when freeing @spec, or %NULL
* @table_name: the name of the table
* @error: a place to store errors, or %NULL
*
@@ -254,14 +251,12 @@ gboolean
gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionDataModelSpec *spec,
GDestroyNotify spec_free_func, const gchar *table_name, GError **error)
{
- GdaVirtualProvider *prov;
+ GdaSqliteProvider *prov;
gchar *str;
int rc;
char *zErrMsg = NULL;
gboolean retval = TRUE;
SqliteConnectionData *scnc;
- GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
- GdaSqliteProvider *sprov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION (cnc)));
static gint counter = 0;
@@ -270,6 +265,8 @@ gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionData
g_return_val_if_fail (spec, FALSE);
g_return_val_if_fail (spec->data_model || (spec->create_columns_func && (spec->create_model_func ||
spec->create_filtered_model_func)), FALSE);
+ GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
+
/* cleaning functions */
if (spec->data_model) {
g_return_val_if_fail (GDA_IS_DATA_MODEL (spec->data_model), FALSE);
@@ -299,15 +296,15 @@ gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionData
priv->table_data_list = g_slist_append (priv->table_data_list, td);
/* actually create the virtual table in @cnc */
- prov = (GdaVirtualProvider *) gda_connection_get_provider (GDA_CONNECTION (cnc));
+ prov = (GdaSqliteProvider *) gda_connection_get_provider (GDA_CONNECTION (cnc));
str = g_strdup_printf ("CREATE VIRTUAL TABLE %s USING %s ('%s')", td->table_name, G_OBJECT_TYPE_NAME
(prov), td->unique_name);
- rc = SQLITE3_CALL (sprov, sqlite3_exec) (scnc->connection, str, NULL, 0, &zErrMsg);
+ rc = SQLITE3_CALL (prov, sqlite3_exec) (scnc->connection, str, NULL, 0, &zErrMsg);
g_free (str);
if (rc != SQLITE_OK) {
g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_INTERNAL_ERROR,
- _("Internal Error: when trying to add data model spec for virtual connection:
%s"), zErrMsg);
- SQLITE3_CALL (sprov, sqlite3_free) (zErrMsg);
+ "%s", zErrMsg);
+ SQLITE3_CALL (prov, sqlite3_free) (zErrMsg);
_gda_vconnection_data_model_table_data_free (td);
priv->table_data_list = g_slist_remove (priv->table_data_list, td);
retval = FALSE;
@@ -328,13 +325,14 @@ get_rid_of_vtable (GdaVconnectionDataModel *cnc, GdaVConnectionTableData *td, gb
int rc;
char *zErrMsg = NULL;
gboolean allok = TRUE;
+ GdaSqliteProvider *prov;
GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
- GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION (cnc)));
SqliteConnectionData *scnc;
scnc = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error ((GdaConnection *)
cnc, error);
if (!scnc && !force)
return FALSE;
+ prov = (GdaSqliteProvider *) gda_connection_get_provider (GDA_CONNECTION (cnc));
if (scnc) {
str = g_strdup_printf ("DROP TABLE %s", td->table_name);
@@ -400,7 +398,7 @@ gda_vconnection_data_model_remove (GdaVconnectionDataModel *cnc, const gchar *ta
* Find the #GdaVconnectionDataModelSpec specifying how the table named @table_name is represented
* in @cnc.
*
- * Returns: (transfer none) (nullable): a #GdaVconnectionDataModelSpec pointer, of %NULL if there is no
table named @table_name
+ * Returns: (transfer none) (allow-none): a #GdaVconnectionDataModelSpec pointer, of %NULL if there is no
table named @table_name
*
* Since: 4.2.6
*/
@@ -427,13 +425,14 @@ gda_vconnection_data_model_get (GdaVconnectionDataModel *cnc, const gchar *table
* either if no table named @table_name exists, or if that table actually exists but no #GdaDataModel
* has yet been created. For a more general approach, use the gda_vconnection_data_model_get().
*
- * Returns: (transfer none) (nullable): the #GdaDataModel, or %NULL
+ * Returns: (transfer none) (allow-none): the #GdaDataModel, or %NULL
*/
GdaDataModel *
gda_vconnection_data_model_get_model (GdaVconnectionDataModel *cnc, const gchar *table_name)
{
GdaVConnectionTableData *td;
g_return_val_if_fail (GDA_IS_VCONNECTION_DATA_MODEL (cnc), NULL);
+
if (!table_name || !(*table_name))
return NULL;
@@ -451,15 +450,17 @@ gda_vconnection_data_model_get_model (GdaVconnectionDataModel *cnc, const gchar
*
* Find the name of the table associated to @model in @cnc
*
- * Returns: (transfer none) (nullable): the table name, or %NULL if not found
+ * Returns: (transfer none) (allow-none): the table name, or %NULL if not found
*/
const gchar *
gda_vconnection_data_model_get_table_name (GdaVconnectionDataModel *cnc, GdaDataModel *model)
{
GdaVConnectionTableData *td;
g_return_val_if_fail (GDA_IS_VCONNECTION_DATA_MODEL (cnc), NULL);
+
if (!model)
return NULL;
+
g_return_val_if_fail (GDA_IS_DATA_MODEL (model), NULL);
td = _gda_vconnection_get_table_data_by_model (cnc, model);
@@ -488,7 +489,6 @@ gda_vconnection_data_model_foreach (GdaVconnectionDataModel *cnc,
GSList *copy, *list;
g_return_if_fail (GDA_IS_VCONNECTION_DATA_MODEL (cnc));
GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
-
if (!func || !priv->table_data_list)
return;
@@ -527,6 +527,7 @@ _gda_vconnection_get_table_data_by_unique_name (GdaVconnectionDataModel *cnc, co
{
GSList *list;
GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
+
for (list = priv->table_data_list; list; list = list->next) {
if (!strcmp (((GdaVConnectionTableData*) list->data)->unique_name, unique_name))
return (GdaVConnectionTableData*) list->data;
@@ -539,6 +540,7 @@ _gda_vconnection_get_table_data_by_model (GdaVconnectionDataModel *cnc, GdaDataM
{
GSList *list;
GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
+
for (list = priv->table_data_list; list; list = list->next) {
if (((GdaVConnectionTableData*) list->data)->real_model == model)
return (GdaVConnectionTableData*) list->data;
@@ -554,44 +556,29 @@ _gda_vconnection_data_model_table_data_free (GdaVConnectionTableData *td)
if (td->real_model)
g_object_unref (td->real_model);
if (td->columns) {
- g_list_free_full (td->columns, (GDestroyNotify) g_object_unref);
- td->columns = NULL;
+ g_list_free_full (td->columns, g_object_unref);
+ td->columns = NULL;
}
g_free (td->table_name);
- td->table_name = NULL;
g_free (td->unique_name);
- td->unique_name = NULL;
- if (td->spec_free_func) {
+ if (td->spec_free_func)
td->spec_free_func (td->spec);
- td->spec = NULL;
- }
for (i = 0; i < PARAMS_NB; i++) {
- if (td->modif_params[i]) {
+ if (td->modif_params[i])
g_object_unref (td->modif_params[i]);
- td->modif_params[i] = NULL;
- }
- if (td->modif_stmt[i]) {
+ if (td->modif_stmt[i])
g_object_unref (td->modif_stmt[i]);
- td->modif_stmt[i] = NULL;
- }
}
- if (td->context.hash) {
+ if (td->context.hash)
g_hash_table_destroy (td->context.hash);
- td->context.hash = NULL;
- }
g_free (td);
}
-
static void
vcontext_free (VContext *context)
{
- GObject *obj = g_weak_ref_get (&(context->context_object));
- if (obj) {
- g_hash_table_remove (context->vtable->context.hash, obj);
- g_object_unref (obj);
- }
+ g_weak_ref_set (&context->context_object, NULL);
if (context->context_data) {
g_ptr_array_free (context->context_data, TRUE);
context->context_data = NULL;
@@ -605,10 +592,10 @@ vcontext_free (VContext *context)
void
_gda_vconnection_set_working_obj (GdaVconnectionDataModel *cnc, GObject *obj)
{
- GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
- g_mutex_lock (& (priv->lock_context));
GSList *list;
+ GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
if (obj) {
+ g_mutex_lock (& (priv->lock_context));
for (list = priv->table_data_list; list; list = list->next) {
GdaVConnectionTableData *td = (GdaVConnectionTableData*) list->data;
VContext *vc = NULL;
@@ -623,8 +610,8 @@ _gda_vconnection_set_working_obj (GdaVconnectionDataModel *cnc, GObject *obj)
if (! vc) {
vc = g_new0 (VContext, 1);
- g_weak_ref_set (&(vc->context_object), obj);
- vc->context_data = g_ptr_array_new_full (1, (GDestroyNotify)
_gda_vconnection_virtual_filtered_data_unref);
+ g_weak_ref_set (&vc->context_object, obj);
+ vc->context_data = g_ptr_array_new_with_free_func ((GDestroyNotify)
_gda_vconnection_virtual_filtered_data_unref);
vc->vtable = td;
g_hash_table_insert (td->context.hash, obj, vc);
#ifdef DEBUG_VCONTEXT
@@ -641,14 +628,15 @@ _gda_vconnection_set_working_obj (GdaVconnectionDataModel *cnc, GObject *obj)
* an exception already occurred */
td->context.current_vcontext = NULL;
}
+ g_mutex_unlock (& (priv->lock_context));
}
- g_mutex_unlock (& (priv->lock_context));
}
void
_gda_vconnection_change_working_obj (GdaVconnectionDataModel *cnc, GObject *obj)
{
GSList *list;
+ GObject *old_obj;
GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
for (list = priv->table_data_list; list; list = list->next) {
@@ -661,7 +649,7 @@ _gda_vconnection_change_working_obj (GdaVconnectionDataModel *cnc, GObject *obj)
VContext *ovc, *nvc;
ovc = td->context.current_vcontext;
nvc = g_new0 (VContext, 1);
- g_weak_ref_set (&(nvc->context_object), obj);
+ g_weak_ref_init (&nvc->context_object, obj);
nvc->vtable = ovc->vtable;
nvc->context_data = ovc->context_data;
ovc->context_data = NULL;
@@ -669,6 +657,9 @@ _gda_vconnection_change_working_obj (GdaVconnectionDataModel *cnc, GObject *obj)
#ifdef DEBUG_VCONTEXT
g_print ("VCNew %p\n", nvc);
#endif
- g_hash_table_remove (td->context.hash, obj);
+ old_obj = g_weak_ref_get (&ovc->context_object);
+ if (old_obj != NULL) {
+ g_hash_table_remove (td->context.hash, old_obj);
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]