[libgda] Threading issues corrections
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] Threading issues corrections
- Date: Tue, 24 Feb 2015 21:37:00 +0000 (UTC)
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]