[libgda] Threading issues corrections



commit f3bdb6e325ced6ca423581396fb9928060f8748d
Author: Vivien Malerba <malerba gnome-db org>
Date:   Tue Feb 24 22:36:03 2015 +0100

    Threading issues corrections

 libgda/gda-data-proxy.c              |   13 ++++--
 libgda/providers-support/gda-pstmt.c |   82 +++++++++++++++++++++++++--------
 2 files changed, 71 insertions(+), 24 deletions(-)
---
diff --git a/libgda/gda-data-proxy.c b/libgda/gda-data-proxy.c
index 66453bc..93886fb 100644
--- a/libgda/gda-data-proxy.c
+++ b/libgda/gda-data-proxy.c
@@ -3040,6 +3040,8 @@ sql_where_foreach (GdaSqlAnyPart *part, GdaDataProxy *proxy, G_GNUC_UNUSED GErro
 
 /*
  * Applies proxy->priv->filter_stmt
+ *
+ * Make sure proxy->priv->mutex is locked
  */
 static gboolean
 apply_filter_statement (GdaDataProxy *proxy, GError **error)
@@ -3115,6 +3117,7 @@ apply_filter_statement (GdaDataProxy *proxy, GError **error)
 
        /* execute statement */
        GError *lerror = NULL;
+       g_rec_mutex_unlock (& (proxy->priv->mutex));
        filtered_rows = gda_connection_statement_execute_select (vcnc, stmt, NULL, &lerror);
        if (!filtered_rows) {
                g_set_error (error, GDA_DATA_PROXY_ERROR, GDA_DATA_PROXY_FILTER_ERROR,
@@ -3122,6 +3125,7 @@ apply_filter_statement (GdaDataProxy *proxy, GError **error)
                g_clear_error (&lerror);
                proxy->priv->force_direct_mapping = FALSE;
                gda_vconnection_data_model_remove (GDA_VCONNECTION_DATA_MODEL (vcnc), "proxy", NULL);
+               g_rec_mutex_lock (& (proxy->priv->mutex));
                goto clean_previous_filter;
        }
 
@@ -3135,12 +3139,14 @@ apply_filter_statement (GdaDataProxy *proxy, GError **error)
                              "%s", _("Error in filter expression"));
                proxy->priv->force_direct_mapping = FALSE;
                filtered_rows = NULL;
+               g_rec_mutex_lock (& (proxy->priv->mutex));
                goto clean_previous_filter;
        }
        filtered_rows = copy;
        proxy->priv->force_direct_mapping = FALSE;
+       g_rec_mutex_lock (& (proxy->priv->mutex));
 
- clean_previous_filter:
+ clean_previous_filter: /* NEED TO BE LOCKED HERE */
        if (proxy->priv->filter_expr) {
                g_free (proxy->priv->filter_expr);
                proxy->priv->filter_expr = NULL;
@@ -3173,6 +3179,7 @@ apply_filter_statement (GdaDataProxy *proxy, GError **error)
        gda_data_model_reset (GDA_DATA_MODEL (proxy));
 
        adjust_displayed_chunk (proxy);
+       g_rec_mutex_unlock (& (proxy->priv->mutex));
 
        if (!stmt)
                return TRUE;
@@ -3215,7 +3222,6 @@ gda_data_proxy_set_filter_expr (GdaDataProxy *proxy, const gchar *filter_expr, G
                if (proxy->priv->filter_stmt)
                        g_object_unref (proxy->priv->filter_stmt);
                proxy->priv->filter_stmt = NULL;
-               g_rec_mutex_unlock (& (proxy->priv->mutex));
 
                gboolean retval = apply_filter_statement (proxy, error);
                return retval;
@@ -3260,7 +3266,6 @@ gda_data_proxy_set_filter_expr (GdaDataProxy *proxy, const gchar *filter_expr, G
                g_object_unref (proxy->priv->filter_stmt);
        proxy->priv->filter_stmt = stmt;
 
-       g_rec_mutex_unlock (& (proxy->priv->mutex));
        gboolean retval = apply_filter_statement (proxy, error);
        return retval;
 }
@@ -3351,11 +3356,11 @@ gda_data_proxy_set_ordering_column (GdaDataProxy *proxy, gint col, GError **erro
        else {
                gchar *str;
                str = g_strdup_printf ("ORDER BY _%d", col + 1);
+               g_rec_mutex_unlock (& (proxy->priv->mutex));
                retval = gda_data_proxy_set_filter_expr (proxy, str, error);
                g_free (str);
        }
 
-       g_rec_mutex_unlock (& (proxy->priv->mutex));
        return retval;
 }
 
diff --git a/libgda/providers-support/gda-pstmt.c b/libgda/providers-support/gda-pstmt.c
index 924db12..37bd71e 100644
--- a/libgda/providers-support/gda-pstmt.c
+++ b/libgda/providers-support/gda-pstmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 - 2011 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2008 - 2015 Vivien Malerba <malerba gnome-db org>
  * Copyright (C) 2010 David King <davidk openismus com>
  * Copyright (C) 2010 Jonh Wendell <jwendell gnome org>
  *
@@ -32,7 +32,8 @@ static void gda_pstmt_finalize   (GObject *object);
 static GObjectClass *parent_class = NULL;
 
 struct _GdaPStmtPrivate {
-       GdaStatement *gda_stmt; /* GdaPStmt object holds a weak reference on this stmt object, may be NULL */
+       GRecMutex mutex;
+       GWeakRef gda_stmt_ref; /* holds a weak reference to #GdaStatement, or %NULL */
 };
 
 /**
@@ -84,7 +85,8 @@ gda_pstmt_init (GdaPStmt *pstmt, G_GNUC_UNUSED GdaPStmtClass *klass)
 {
        g_return_if_fail (GDA_IS_PSTMT (pstmt));
        pstmt->priv = g_new0 (GdaPStmtPrivate, 1);
-       pstmt->priv->gda_stmt = NULL;
+       g_rec_mutex_init (& pstmt->priv->mutex);
+       g_weak_ref_init (& pstmt->priv->gda_stmt_ref, NULL);
        pstmt->sql = NULL;
        pstmt->param_ids = NULL;
        pstmt->ncols = -1;
@@ -92,14 +94,28 @@ gda_pstmt_init (GdaPStmt *pstmt, G_GNUC_UNUSED GdaPStmtClass *klass)
        pstmt->tmpl_columns = NULL;
 }
 
+/*
+ * @stmt may be %NULL
+ */
 static void
 gda_stmt_reset_cb (GdaStatement *stmt, GdaPStmt *pstmt)
 {
-       g_signal_handlers_disconnect_by_func (G_OBJECT (stmt), 
-                                             G_CALLBACK (gda_stmt_reset_cb), pstmt);
-       /*g_print ("g_object_remove_weak_pointer (%p, %p)\n", pstmt->priv->gda_stmt, 
&(pstmt->priv->gda_stmt));*/
-       g_object_remove_weak_pointer ((GObject*) pstmt->priv->gda_stmt, (gpointer*) &(pstmt->priv->gda_stmt));
-       pstmt->priv->gda_stmt = NULL;
+       g_rec_mutex_lock (& pstmt->priv->mutex);
+       if (stmt)
+               g_signal_handlers_disconnect_by_func (G_OBJECT (stmt),
+                                                     G_CALLBACK (gda_stmt_reset_cb), pstmt);
+       else {
+               stmt = g_weak_ref_get (& pstmt->priv->gda_stmt_ref);
+               if (stmt) {
+                       g_signal_handlers_disconnect_by_func (G_OBJECT (stmt),
+                                                             G_CALLBACK (gda_stmt_reset_cb), pstmt);
+                       g_object_unref (stmt);
+               }
+       }
+
+       g_weak_ref_clear (& pstmt->priv->gda_stmt_ref);
+       g_weak_ref_init (& pstmt->priv->gda_stmt_ref, NULL);
+       g_rec_mutex_unlock (& pstmt->priv->mutex);
 }
 
 static void
@@ -107,8 +123,7 @@ gda_pstmt_dispose (GObject *object)
 {
        GdaPStmt *pstmt = (GdaPStmt *) object;
 
-       if (pstmt->priv->gda_stmt) 
-               gda_stmt_reset_cb (pstmt->priv->gda_stmt, pstmt);
+       gda_stmt_reset_cb (NULL, pstmt);
 
        /* chain to parent class */
        parent_class->dispose (object);
@@ -120,6 +135,8 @@ gda_pstmt_finalize (GObject *object)
        GdaPStmt *pstmt = (GdaPStmt *) object;
 
        /* free memory */
+       g_weak_ref_clear (& pstmt->priv->gda_stmt_ref);
+       g_rec_mutex_clear (& pstmt->priv->mutex);
        g_free (pstmt->priv);
 
        if (pstmt->sql) {
@@ -147,7 +164,7 @@ gda_pstmt_finalize (GObject *object)
 /**
  * gda_pstmt_set_gda_statement:
  * @pstmt: a #GdaPStmt object
- * @stmt: a #GdaStatement object
+ * @stmt: (allow-none): a #GdaStatement object, or %NULL
  *
  * Informs @pstmt that it corresponds to the preparation of the @stmt statement
  */
@@ -157,17 +174,25 @@ gda_pstmt_set_gda_statement (GdaPStmt *pstmt, GdaStatement *stmt)
        g_return_if_fail (GDA_IS_PSTMT (pstmt));
        g_return_if_fail (!stmt || GDA_IS_STATEMENT (stmt));
 
-       if (pstmt->priv->gda_stmt == stmt)
+       g_rec_mutex_lock (& pstmt->priv->mutex);
+
+       GdaStatement *estmt;
+       estmt = g_weak_ref_get (& pstmt->priv->gda_stmt_ref);
+       if (estmt == stmt) {
+               if (estmt)
+                       g_object_unref (estmt);
+               g_rec_mutex_unlock (& pstmt->priv->mutex);
                return;
-       if (pstmt->priv->gda_stmt) 
-               gda_stmt_reset_cb (pstmt->priv->gda_stmt, pstmt);
+       }
+
+       gda_stmt_reset_cb (NULL, pstmt);
 
-       pstmt->priv->gda_stmt = stmt;
        if (stmt) {
-               g_object_add_weak_pointer ((GObject*) stmt, (gpointer*) &(pstmt->priv->gda_stmt));
-               /*g_print ("g_object_add_weak_pointer (%p, %p)\n", stmt, &(pstmt->priv->gda_stmt));*/
+               g_object_ref (stmt);
+               g_weak_ref_set (& pstmt->priv->gda_stmt_ref, stmt);
                g_signal_connect (G_OBJECT (stmt), "reset", G_CALLBACK (gda_stmt_reset_cb), pstmt);
        }
+       g_rec_mutex_unlock (& pstmt->priv->mutex);
 }
 
 /**
@@ -184,6 +209,9 @@ gda_pstmt_copy_contents (GdaPStmt *src, GdaPStmt *dest)
        g_return_if_fail (GDA_IS_PSTMT (src));
        g_return_if_fail (GDA_IS_PSTMT (dest));
 
+       g_rec_mutex_lock (& src->priv->mutex);
+       g_rec_mutex_lock (& dest->priv->mutex);
+
        g_free (dest->sql);
        dest->sql = NULL;
        if (src->sql)
@@ -209,8 +237,16 @@ gda_pstmt_copy_contents (GdaPStmt *src, GdaPStmt *dest)
                        dest->tmpl_columns = g_slist_append (dest->tmpl_columns, 
                                                             gda_column_copy (GDA_COLUMN (list->data)));
        }
-       if (src->priv->gda_stmt)
-               gda_pstmt_set_gda_statement (dest, src->priv->gda_stmt);
+       GdaStatement *stmt;
+       stmt = g_weak_ref_get (& src->priv->gda_stmt_ref);
+       if (stmt) {
+               gda_pstmt_set_gda_statement (dest, stmt);
+               g_object_unref (stmt);
+       }
+
+       g_rec_mutex_unlock (& src->priv->mutex);
+       g_rec_mutex_unlock (& dest->priv->mutex);
+
 }
 
 /**
@@ -228,5 +264,11 @@ GdaStatement *
 gda_pstmt_get_gda_statement (GdaPStmt *pstmt)
 {
        g_return_val_if_fail (GDA_IS_PSTMT (pstmt), NULL);
-       return pstmt->priv->gda_stmt;
+       g_rec_mutex_lock (& pstmt->priv->mutex);
+       GdaStatement *stmt;
+       stmt = g_weak_ref_get (& pstmt->priv->gda_stmt_ref);
+       if (stmt)
+               g_object_unref (stmt);
+       g_rec_mutex_unlock (& pstmt->priv->mutex);
+       return stmt;
 }


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