[evolution-data-server/openismus-work-master: 6/9] EBookBackendSqliteDB: Remodeled concurrent access.



commit c11ccca0d4877e3a20ea9a9a8a5e7b3ace6bf3a1
Author: Tristan Van Berkom <tristanvb openismus com>
Date:   Thu Feb 14 19:18:27 2013 +0900

    EBookBackendSqliteDB: Remodeled concurrent access.
    
    Now use a more traditional locking with a single mutex held at
    every API entry point, this protects a single SQLite connection
    from being accessed from multiple thread contexts (even in read mode).

 .../libedata-book/e-book-backend-sqlitedb.c        |  450 +++++++++++---------
 1 files changed, 252 insertions(+), 198 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.c 
b/addressbook/libedata-book/e-book-backend-sqlitedb.c
index 3987665..881d683 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.c
@@ -39,14 +39,29 @@
 
 #define d(x)
 
+#if d(1)+0
+#  define LOCK_MUTEX(mutex)                                    \
+       G_STMT_START {                                          \
+               g_message ("%s: DB Locking ", G_STRFUNC);       \
+               g_mutex_lock (mutex);                           \
+               g_message ("%s: DB Locked ", G_STRFUNC);        \
+       } G_STMT_END
+
+
+#  define UNLOCK_MUTEX(mutex)                                  \
+       G_STMT_START {                                          \
+               g_message ("%s: Unlocking ", G_STRFUNC);        \
+               g_mutex_unlock (mutex);                         \
+               g_message ("%s: DB Unlocked ", G_STRFUNC);      \
+       } G_STMT_END
+#else
+#  define LOCK_MUTEX(mutex)   g_mutex_lock (mutex)
+#  define UNLOCK_MUTEX(mutex) g_mutex_unlock (mutex)
+#endif
+
 #define DB_FILENAME "contacts.db"
 #define FOLDER_VERSION 3
 
-#define READER_LOCK(ebsdb) g_rw_lock_reader_lock (&ebsdb->priv->rwlock)
-#define READER_UNLOCK(ebsdb) g_rw_lock_reader_unlock (&ebsdb->priv->rwlock)
-#define WRITER_LOCK(ebssdb) g_rw_lock_writer_lock (&ebsdb->priv->rwlock)
-#define WRITER_UNLOCK(ebssdb) g_rw_lock_writer_unlock (&ebsdb->priv->rwlock)
-
 typedef enum {
        INDEX_PREFIX = (1 << 0),
        INDEX_SUFFIX = (1 << 1)
@@ -64,10 +79,10 @@ struct _EBookBackendSqliteDBPrivate {
        gchar *path;
        gchar *hash_key;
 
-       gboolean store_vcard;
-       GRWLock rwlock;
+       GMutex lock;
+       GMutex updates_lock; /* This is for deprecated e_book_backend_sqlitedb_lock_updates() */
 
-       GMutex in_transaction_lock;
+       gboolean store_vcard;
        guint32 in_transaction;
 
        SummaryField   *summary_fields;
@@ -189,14 +204,13 @@ e_book_backend_sqlitedb_finalize (GObject *object)
 
        priv = E_BOOK_BACKEND_SQLITEDB_GET_PRIVATE (object);
 
-       g_rw_lock_clear (&priv->rwlock);
-
        sqlite3_close (priv->db);
 
        g_free (priv->path);
        g_free (priv->summary_fields);
 
-       g_mutex_clear (&priv->in_transaction_lock);
+       g_mutex_clear (&priv->lock);
+       g_mutex_clear (&priv->updates_lock);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_book_backend_sqlitedb_parent_class)->finalize (object);
@@ -220,10 +234,10 @@ e_book_backend_sqlitedb_init (EBookBackendSqliteDB *ebsdb)
        ebsdb->priv = E_BOOK_BACKEND_SQLITEDB_GET_PRIVATE (ebsdb);
 
        ebsdb->priv->store_vcard = TRUE;
-       g_rw_lock_init (&ebsdb->priv->rwlock);
 
        ebsdb->priv->in_transaction = 0;
-       g_mutex_init (&ebsdb->priv->in_transaction_lock);
+       g_mutex_init (&ebsdb->priv->lock);
+       g_mutex_init (&ebsdb->priv->updates_lock);
 }
 
 static gint
@@ -373,7 +387,7 @@ book_backend_sql_exec (sqlite3 *db,
        return book_backend_sql_exec_real (db, stmt, callback, data, error);
 }
 
-/* the first caller holds the writer lock too */
+/* This function must always be called with the priv->lock held */
 static gboolean
 book_backend_sqlitedb_start_transaction (EBookBackendSqliteDB *ebsdb,
                                          GError **error)
@@ -384,29 +398,19 @@ book_backend_sqlitedb_start_transaction (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (ebsdb->priv != NULL, FALSE);
        g_return_val_if_fail (ebsdb->priv->db != NULL, FALSE);
 
-       g_mutex_lock (&ebsdb->priv->in_transaction_lock);
-
        ebsdb->priv->in_transaction++;
-       if (ebsdb->priv->in_transaction == 0) {
-               g_mutex_unlock (&ebsdb->priv->in_transaction_lock);
-
-               g_return_val_if_fail (ebsdb->priv->in_transaction != 0, FALSE);
-               return FALSE;
-       }
+       g_return_val_if_fail (ebsdb->priv->in_transaction > 0, FALSE);
 
        if (ebsdb->priv->in_transaction == 1) {
-               WRITER_LOCK (ebsdb);
 
                success = book_backend_sql_exec (
                        ebsdb->priv->db, "BEGIN", NULL, NULL, error);
        }
 
-       g_mutex_unlock (&ebsdb->priv->in_transaction_lock);
-
        return success;
 }
 
-/* the last caller releases the writer lock too */
+/* This function must always be called with the priv->lock held */
 static gboolean
 book_backend_sqlitedb_commit_transaction (EBookBackendSqliteDB *ebsdb,
                                           GError **error)
@@ -417,30 +421,19 @@ book_backend_sqlitedb_commit_transaction (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (ebsdb->priv != NULL, FALSE);
        g_return_val_if_fail (ebsdb->priv->db != NULL, FALSE);
 
-       g_mutex_lock (&ebsdb->priv->in_transaction_lock);
-
-       if (ebsdb->priv->in_transaction == 0) {
-               g_mutex_unlock (&ebsdb->priv->in_transaction_lock);
-
-               g_return_val_if_fail (ebsdb->priv->in_transaction > 0, FALSE);
-               return FALSE;
-       }
+       g_return_val_if_fail (ebsdb->priv->in_transaction > 0, FALSE);
 
        ebsdb->priv->in_transaction--;
 
        if (ebsdb->priv->in_transaction == 0) {
                success = book_backend_sql_exec (
                        ebsdb->priv->db, "COMMIT", NULL, NULL, error);
-
-               WRITER_UNLOCK (ebsdb);
        }
 
-       g_mutex_unlock (&ebsdb->priv->in_transaction_lock);
-
        return success;
 }
 
-/* the last caller releases the writer lock too */
+/* This function must always be called with the priv->lock held */
 static gboolean
 book_backend_sqlitedb_rollback_transaction (EBookBackendSqliteDB *ebsdb,
                                             GError **error)
@@ -451,14 +444,7 @@ book_backend_sqlitedb_rollback_transaction (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (ebsdb->priv != NULL, FALSE);
        g_return_val_if_fail (ebsdb->priv->db != NULL, FALSE);
 
-       g_mutex_lock (&ebsdb->priv->in_transaction_lock);
-
-       if (ebsdb->priv->in_transaction == 0) {
-               g_mutex_unlock (&ebsdb->priv->in_transaction_lock);
-
-               g_return_val_if_fail (ebsdb->priv->in_transaction > 0, FALSE);
-               return FALSE;
-       }
+       g_return_val_if_fail (ebsdb->priv->in_transaction > 0, FALSE);
 
        ebsdb->priv->in_transaction--;
 
@@ -466,11 +452,7 @@ book_backend_sqlitedb_rollback_transaction (EBookBackendSqliteDB *ebsdb,
                success = book_backend_sql_exec (
                        ebsdb->priv->db, "ROLLBACK", NULL, NULL, error);
 
-               WRITER_UNLOCK (ebsdb);
        }
-
-       g_mutex_unlock (&ebsdb->priv->in_transaction_lock);
-
        return success;
 }
 
@@ -867,8 +849,6 @@ create_contacts_table (EBookBackendSqliteDB *ebsdb,
        stmt = sqlite3_mprintf (string->str, folderid);
        g_string_free (string, TRUE);
 
-       WRITER_LOCK (ebsdb);
-
        success = book_backend_sql_exec (
                ebsdb->priv->db, stmt, NULL, NULL , error);
 
@@ -947,8 +927,6 @@ create_contacts_table (EBookBackendSqliteDB *ebsdb,
 
        }
 
-       WRITER_UNLOCK (ebsdb);
-
        if (success)
                success = introspect_summary (ebsdb, folderid, error);
 
@@ -982,8 +960,6 @@ book_backend_sqlitedb_load (EBookBackendSqliteDB *ebsdb,
                return FALSE;
        }
 
-       WRITER_LOCK (ebsdb);
-
        book_backend_sql_exec (
                ebsdb->priv->db,
                "ATTACH DATABASE ':memory:' AS mem",
@@ -1001,8 +977,6 @@ book_backend_sqlitedb_load (EBookBackendSqliteDB *ebsdb,
                "PRAGMA journal_mode = WAL",
                NULL, NULL, NULL);
 
-       WRITER_UNLOCK (ebsdb);
-
        return create_folders_table (ebsdb, error);
 }
 
@@ -1035,7 +1009,6 @@ e_book_backend_sqlitedb_new_internal (const gchar *path,
 
                if (ebsdb) {
                        g_object_ref (ebsdb);
-                       g_mutex_unlock (&dbcon_lock);
                        g_free (hash_key);
                        goto exit;
                }
@@ -1075,19 +1048,27 @@ e_book_backend_sqlitedb_new_internal (const gchar *path,
        g_hash_table_insert (db_connections, hash_key, ebsdb);
        ebsdb->priv->hash_key = g_strdup (hash_key);
 
+ exit:
+       /* While the global dbcon_lock is held, hold the ebsdb specific lock and
+        * prolong the locking on that instance until the folders are all set up
+        */
+       LOCK_MUTEX (&ebsdb->priv->lock);
        g_mutex_unlock (&dbcon_lock);
 
-exit:
        if (!add_folder_into_db (ebsdb, folderid, folder_name, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
                g_object_unref (ebsdb);
                return NULL;
        }
 
        if (!create_contacts_table (ebsdb, folderid, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
                g_object_unref (ebsdb);
                return NULL;
        }
 
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
+
        return ebsdb;
 }
 
@@ -1357,9 +1338,17 @@ gboolean
 e_book_backend_sqlitedb_lock_updates (EBookBackendSqliteDB *ebsdb,
                                       GError **error)
 {
+       gboolean success;
+
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
 
-       return book_backend_sqlitedb_start_transaction (ebsdb, error);
+       LOCK_MUTEX (&ebsdb->priv->updates_lock);
+
+       LOCK_MUTEX (&ebsdb->priv->lock);
+       success = book_backend_sqlitedb_start_transaction (ebsdb, error);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
+
+       return success;
 }
 
 gboolean
@@ -1367,11 +1356,19 @@ e_book_backend_sqlitedb_unlock_updates (EBookBackendSqliteDB *ebsdb,
                                         gboolean do_commit,
                                         GError **error)
 {
+       gboolean success;
+
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
 
-       return do_commit ?
+       LOCK_MUTEX (&ebsdb->priv->lock);
+       success = do_commit ?
                book_backend_sqlitedb_commit_transaction (ebsdb, error) :
                book_backend_sqlitedb_rollback_transaction (ebsdb, error);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
+
+       UNLOCK_MUTEX (&ebsdb->priv->updates_lock);
+
+       return success;
 }
 
 /* Add Contact (free the result with g_free() ) */
@@ -1586,13 +1583,18 @@ e_book_backend_sqlitedb_new_contacts (EBookBackendSqliteDB *ebsdb,
                                       GError **error)
 {
        GSList *l;
-       gboolean success;
+       gboolean success = TRUE;
 
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
        g_return_val_if_fail (folderid != NULL, FALSE);
        g_return_val_if_fail (contacts != NULL, FALSE);
 
-       success = book_backend_sqlitedb_start_transaction (ebsdb, error);
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!book_backend_sqlitedb_start_transaction (ebsdb, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
+               return FALSE;
+       }
 
        for (l = contacts; success && l != NULL; l = g_slist_next (l)) {
                EContact *contact = (EContact *) l->data;
@@ -1601,12 +1603,14 @@ e_book_backend_sqlitedb_new_contacts (EBookBackendSqliteDB *ebsdb,
        }
 
        if (success)
-               return book_backend_sqlitedb_commit_transaction (ebsdb, error);
+               success = book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       else
+               /* The GError is already set. */
+               book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
 
-       /* The GError is already set. */
-       book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
-       return FALSE;
+       return success;
 }
 
 /**
@@ -1746,14 +1750,19 @@ e_book_backend_sqlitedb_remove_contacts (EBookBackendSqliteDB *ebsdb,
                                          GSList *uids,
                                          GError **error)
 {
-       gboolean success;
+       gboolean success = TRUE;
        gchar *stmt;
 
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
        g_return_val_if_fail (folderid != NULL, FALSE);
        g_return_val_if_fail (uids != NULL, FALSE);
 
-       success = book_backend_sqlitedb_start_transaction (ebsdb, error);
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!book_backend_sqlitedb_start_transaction (ebsdb, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
+               return FALSE;
+       }
 
        /* Delete the auxillary contact infos first */
        if (success && ebsdb->priv->have_attr_list) {
@@ -1773,12 +1782,14 @@ e_book_backend_sqlitedb_remove_contacts (EBookBackendSqliteDB *ebsdb,
        }
 
        if (success)
-               return book_backend_sqlitedb_commit_transaction (ebsdb, error);
+               success = book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       else
+               /* The GError is already set. */
+               book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
 
-       /* The GError is already set. */
-       book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
-       return FALSE;
+       return success;
 }
 
 struct _contact_info {
@@ -1825,7 +1836,7 @@ e_book_backend_sqlitedb_has_contact (EBookBackendSqliteDB *ebsdb,
        cinfo.exists = FALSE;
        cinfo.partial_content = FALSE;
 
-       READER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        stmt = sqlite3_mprintf (
                "SELECT partial_content FROM %Q WHERE uid = %Q",
@@ -1837,7 +1848,7 @@ e_book_backend_sqlitedb_has_contact (EBookBackendSqliteDB *ebsdb,
        if (success)
                *partial_content = cinfo.partial_content;
 
-       READER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        /* FIXME Returning FALSE can mean either "contact not found" or
         *       "error occurred".  Add a boolean (out) "exists" parameter. */
@@ -1970,7 +1981,7 @@ e_book_backend_sqlitedb_is_summary_fields (GHashTable *fields_of_interest)
  **/
 gboolean
 e_book_backend_sqlitedb_check_summary_fields (EBookBackendSqliteDB *ebsdb,
-                                              GHashTable *fields_of_interest)
+                                             GHashTable *fields_of_interest)
 {
        gboolean summary_fields = TRUE;
        GHashTableIter iter;
@@ -1979,6 +1990,8 @@ e_book_backend_sqlitedb_check_summary_fields (EBookBackendSqliteDB *ebsdb,
        if (!fields_of_interest)
                return FALSE;
 
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
        g_hash_table_iter_init (&iter, fields_of_interest);
        while (g_hash_table_iter_next (&iter, &key, &value)) {
                const gchar  *field_name = key;
@@ -1990,6 +2003,8 @@ e_book_backend_sqlitedb_check_summary_fields (EBookBackendSqliteDB *ebsdb,
                }
        }
 
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
+
        return summary_fields;
 }
 
@@ -2087,7 +2102,7 @@ e_book_backend_sqlitedb_get_vcard_string (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (folderid != NULL, NULL);
        g_return_val_if_fail (uid != NULL, NULL);
 
-       READER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        /* Try constructing contacts from only UID/REV first if that's requested */
        if (uid_rev_fields (fields_of_interest)) {
@@ -2134,7 +2149,7 @@ e_book_backend_sqlitedb_get_vcard_string (EBookBackendSqliteDB *ebsdb,
 
        }
 
-       READER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        if (with_all_required_fields)
                *with_all_required_fields = local_with_all_required_fields;
@@ -2264,21 +2279,10 @@ static const struct {
        { "exists", func_check, 0 }
 };
 
-/**
- * e_book_backend_sqlitedb_check_summary_query:
- * @ebsdb: an #EBookBackendSqliteDB
- * @query: the query to check
- * @with_list_attrs: Return location to store whether the query touches upon list attributes
- *
- * Checks whether @query contains only checks for the summary fields
- * configured in @ebsdb
- *
- * Since: 3.8
- **/
-gboolean
-e_book_backend_sqlitedb_check_summary_query (EBookBackendSqliteDB *ebsdb,
-                                             const gchar *query,
-                                             gboolean *with_list_attrs)
+static gboolean
+e_book_backend_sqlitedb_check_summary_query_locked (EBookBackendSqliteDB *ebsdb,
+                                                   const gchar *query,
+                                                   gboolean *with_list_attrs)
 {
        ESExp *sexp;
        ESExpResult *r;
@@ -2325,6 +2329,33 @@ e_book_backend_sqlitedb_check_summary_query (EBookBackendSqliteDB *ebsdb,
 }
 
 /**
+ * e_book_backend_sqlitedb_check_summary_query:
+ * @ebsdb: an #EBookBackendSqliteDB
+ * @query: the query to check
+ * @with_list_attrs: Return location to store whether the query touches upon list attributes
+ *
+ * Checks whether @query contains only checks for the summary fields
+ * configured in @ebsdb
+ *
+ * Since: 3.8
+ **/
+gboolean
+e_book_backend_sqlitedb_check_summary_query (EBookBackendSqliteDB *ebsdb,
+                                             const gchar *query,
+                                             gboolean *with_list_attrs)
+{
+       gboolean is_summary;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
+
+       LOCK_MUTEX (&ebsdb->priv->lock);
+       is_summary = e_book_backend_sqlitedb_check_summary_query_locked (ebsdb, query, with_list_attrs);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
+
+       return is_summary;
+}
+
+/**
  * e_book_backend_sqlitedb_is_summary_query:
  *
  * Checks whether the query contains only checks for the default summary fields
@@ -2336,7 +2367,7 @@ e_book_backend_sqlitedb_check_summary_query (EBookBackendSqliteDB *ebsdb,
 gboolean
 e_book_backend_sqlitedb_is_summary_query (const gchar *query)
 {
-       return e_book_backend_sqlitedb_check_summary_query (NULL, query, NULL);
+       return e_book_backend_sqlitedb_check_summary_query_locked (NULL, query, NULL);
 }
 
 static ESExpResult *
@@ -2850,8 +2881,6 @@ book_backend_sqlitedb_search_query (EBookBackendSqliteDB *ebsdb,
        gboolean local_with_all_required_fields = FALSE;
        gboolean success = TRUE;
 
-       READER_LOCK (ebsdb);
-
        /* Try constructing contacts from only UID/REV first if that's requested */
        if (uid_rev_fields (fields_of_interest)) {
                gchar *select_portion;
@@ -2928,8 +2957,6 @@ book_backend_sqlitedb_search_query (EBookBackendSqliteDB *ebsdb,
                        _("Full search_contacts are not stored in cache. vcards cannot be returned."));
        }
 
-       READER_UNLOCK (ebsdb);
-
        if (!success) {
                g_warn_if_fail (vcard_data == NULL);
                return NULL;
@@ -2953,15 +2980,11 @@ book_backend_sqlitedb_search_full (EBookBackendSqliteDB *ebsdb,
        gboolean success;
        gchar *stmt;
 
-       READER_LOCK (ebsdb);
-
        stmt = sqlite3_mprintf ("SELECT uid, vcard, bdata FROM %Q", folderid);
        success = book_backend_sql_exec (
                ebsdb->priv->db, stmt, addto_vcard_list_cb , &all, error);
        sqlite3_free (stmt);
 
-       READER_UNLOCK (ebsdb);
-
        if (!success) {
                g_warn_if_fail (all == NULL);
                return NULL;
@@ -3043,8 +3066,10 @@ e_book_backend_sqlitedb_search (EBookBackendSqliteDB *ebsdb,
        if (sexp && !*sexp)
                sexp = NULL;
 
-       if (!sexp || e_book_backend_sqlitedb_check_summary_query (ebsdb, sexp,
-                                                                 &query_with_list_attrs)) {
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!sexp || e_book_backend_sqlitedb_check_summary_query_locked (ebsdb, sexp,
+                                                                        &query_with_list_attrs)) {
                gchar *sql_query;
 
                sql_query = sexp ? sexp_to_sql_query (ebsdb, folderid, sexp) : NULL;
@@ -3071,6 +3096,8 @@ e_book_backend_sqlitedb_search (EBookBackendSqliteDB *ebsdb,
                        "Hence only summary query is supported."));
        }
 
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
+
        if (searched)
                *searched = local_searched;
        if (with_all_required_fields)
@@ -3103,12 +3130,12 @@ e_book_backend_sqlitedb_search_uids (EBookBackendSqliteDB *ebsdb,
        if (sexp && !*sexp)
                sexp = NULL;
 
-       if (!sexp || e_book_backend_sqlitedb_check_summary_query (ebsdb, sexp, &query_with_list_attrs)) {
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!sexp || e_book_backend_sqlitedb_check_summary_query_locked (ebsdb, sexp, 
&query_with_list_attrs)) {
                gchar *stmt;
                gchar *sql_query = sexp ? sexp_to_sql_query (ebsdb, folderid, sexp) : NULL;
 
-               READER_LOCK (ebsdb);
-
                if (sql_query && sql_query[0]) {
 
                        if (query_with_list_attrs) {
@@ -3133,8 +3160,6 @@ e_book_backend_sqlitedb_search_uids (EBookBackendSqliteDB *ebsdb,
                        sqlite3_free (stmt);
                }
 
-               READER_UNLOCK (ebsdb);
-
                local_searched = TRUE;
 
                g_free (sql_query);
@@ -3152,6 +3177,8 @@ e_book_backend_sqlitedb_search_uids (EBookBackendSqliteDB *ebsdb,
                        "Hence only summary query is supported."));
        }
 
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
+
        if (searched)
                *searched = local_searched;
 
@@ -3195,7 +3222,7 @@ e_book_backend_sqlitedb_get_uids_and_rev (EBookBackendSqliteDB *ebsdb,
 
        uids_and_rev = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
-       READER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        stmt = sqlite3_mprintf ("SELECT uid,rev FROM %Q", folderid);
        book_backend_sql_exec (
@@ -3203,7 +3230,7 @@ e_book_backend_sqlitedb_get_uids_and_rev (EBookBackendSqliteDB *ebsdb,
                get_uids_and_rev_cb, uids_and_rev, error);
        sqlite3_free (stmt);
 
-       READER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        return uids_and_rev;
 }
@@ -3226,7 +3253,7 @@ e_book_backend_sqlitedb_get_is_populated (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
        g_return_val_if_fail (folderid != NULL, FALSE);
 
-       READER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        stmt = sqlite3_mprintf (
                "SELECT is_populated FROM folders WHERE folder_id = %Q",
@@ -3235,7 +3262,7 @@ e_book_backend_sqlitedb_get_is_populated (EBookBackendSqliteDB *ebsdb,
                ebsdb->priv->db, stmt, get_bool_cb , &ret, error);
        sqlite3_free (stmt);
 
-       READER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        return ret;
 
@@ -3260,26 +3287,29 @@ e_book_backend_sqlitedb_set_is_populated (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
        g_return_val_if_fail (folderid != NULL, FALSE);
 
-       if (!book_backend_sqlitedb_start_transaction (ebsdb, error))
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!book_backend_sqlitedb_start_transaction (ebsdb, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
                return FALSE;
+       }
 
        stmt = sqlite3_mprintf (
-               "UPDATE folders SET is_populated = %d "
+               "UPDATE folders SET is_populated = %d "
                "WHERE folder_id = %Q", populated, folderid);
-       success =book_backend_sql_exec (
-               ebsdb->priv->db, stmt, NULL, NULL, error);
+       success = book_backend_sql_exec (
+                ebsdb->priv->db, stmt, NULL, NULL, error);
        sqlite3_free (stmt);
 
-       if (!success)
-               goto rollback;
+       if (success)
+               success = book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       else
+               /* The GError is already set. */
+               book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
 
-       return book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
-rollback:
-       /* The GError is already set. */
-       book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
-
-       return FALSE;
+       return success;
 }
 
 /**
@@ -3312,7 +3342,7 @@ e_book_backend_sqlitedb_get_revision (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (folderid && folderid[0], FALSE);
        g_return_val_if_fail (revision_out != NULL && *revision_out == NULL, FALSE);
 
-       READER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        stmt = sqlite3_mprintf (
                "SELECT revision FROM folders WHERE folder_id = %Q", folderid);
@@ -3320,7 +3350,7 @@ e_book_backend_sqlitedb_get_revision (EBookBackendSqliteDB *ebsdb,
                ebsdb->priv->db, stmt, get_string_cb, &revision_out, error);
        sqlite3_free (stmt);
 
-       READER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        return success;
 }
@@ -3350,26 +3380,29 @@ e_book_backend_sqlitedb_set_revision (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
        g_return_val_if_fail (folderid && folderid[0], FALSE);
 
-       if (!book_backend_sqlitedb_start_transaction (ebsdb, error))
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!book_backend_sqlitedb_start_transaction (ebsdb, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
                return FALSE;
+       }
 
        stmt = sqlite3_mprintf (
-               "UPDATE folders SET revision = %Q "
+               "UPDATE folders SET revision = %Q "
                "WHERE folder_id = %Q", revision, folderid);
        success = book_backend_sql_exec (
-               ebsdb->priv->db, stmt, NULL, NULL, error);
+               ebsdb->priv->db, stmt, NULL, NULL, error);
        sqlite3_free (stmt);
 
-       if (!success)
-               goto rollback;
+       if (success)
+               success = book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       else
+               /* The GError is already set. */
+               book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
 
-       return book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
-rollback:
-       /* The GError is already set. */
-       book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
-
-       return FALSE;
+       return success;
 }
 
 /**
@@ -3395,7 +3428,7 @@ e_book_backend_sqlitedb_get_has_partial_content (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
        g_return_val_if_fail (folderid != NULL, FALSE);
 
-       READER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        stmt = sqlite3_mprintf (
                "SELECT partial_content FROM folders "
@@ -3404,7 +3437,7 @@ e_book_backend_sqlitedb_get_has_partial_content (EBookBackendSqliteDB *ebsdb,
                ebsdb->priv->db, stmt, get_bool_cb , &ret, error);
        sqlite3_free (stmt);
 
-       READER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        return ret;
 }
@@ -3428,26 +3461,29 @@ e_book_backend_sqlitedb_set_has_partial_content (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
        g_return_val_if_fail (folderid != NULL, FALSE);
 
-       if (!book_backend_sqlitedb_start_transaction (ebsdb, error))
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!book_backend_sqlitedb_start_transaction (ebsdb, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
                return FALSE;
+       }
 
        stmt = sqlite3_mprintf (
-               "UPDATE folders SET partial_content = %d "
+               "UPDATE folders SET partial_content = %d "
                "WHERE folder_id = %Q", partial_content, folderid);
        success = book_backend_sql_exec (
-               ebsdb->priv->db, stmt, NULL, NULL, error);
+               ebsdb->priv->db, stmt, NULL, NULL, error);
        sqlite3_free (stmt);
 
-       if (!success)
-               goto rollback;
-
-       return book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       if (success)
+               success = book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       else
+               /* The GError is already set. */
+               book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
 
-rollback:
-       /* The GError is already set. */
-       book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
-       return FALSE;
+       return success;
 }
 
 /**
@@ -3470,7 +3506,7 @@ e_book_backend_sqlitedb_get_contact_bdata (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (folderid != NULL, NULL);
        g_return_val_if_fail (uid != NULL, NULL);
 
-       READER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        stmt = sqlite3_mprintf (
                "SELECT bdata FROM %Q WHERE uid = %Q", folderid, uid);
@@ -3478,7 +3514,7 @@ e_book_backend_sqlitedb_get_contact_bdata (EBookBackendSqliteDB *ebsdb,
                ebsdb->priv->db, stmt, get_string_cb , &ret, error);
        sqlite3_free (stmt);
 
-       READER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        if (!success) {
                g_warn_if_fail (ret == NULL);
@@ -3510,26 +3546,29 @@ e_book_backend_sqlitedb_set_contact_bdata (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (uid != NULL, FALSE);
        g_return_val_if_fail (value != NULL, FALSE);
 
-       if (!book_backend_sqlitedb_start_transaction (ebsdb, error))
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!book_backend_sqlitedb_start_transaction (ebsdb, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
                return FALSE;
+       }
 
        stmt = sqlite3_mprintf (
-               "UPDATE %Q SET bdata = %Q WHERE uid = %Q",
+               "UPDATE %Q SET bdata = %Q WHERE uid = %Q",
                folderid, value, uid);
        success = book_backend_sql_exec (
-               ebsdb->priv->db, stmt, NULL, NULL, error);
+               ebsdb->priv->db, stmt, NULL, NULL, error);
        sqlite3_free (stmt);
 
-       if (!success)
-               goto rollback;
-
-       return book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       if (success)
+               success = book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       else
+               /* The GError is already set. */
+               book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
 
-rollback:
-       /* The GError is already set. */
-       book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
-       return FALSE;
+       return success;
 }
 
 /**
@@ -3549,7 +3588,7 @@ e_book_backend_sqlitedb_get_sync_data (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), NULL);
        g_return_val_if_fail (folderid != NULL, NULL);
 
-       READER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        stmt = sqlite3_mprintf (
                "SELECT sync_data FROM folders WHERE folder_id = %Q",
@@ -3558,7 +3597,7 @@ e_book_backend_sqlitedb_get_sync_data (EBookBackendSqliteDB *ebsdb,
                ebsdb->priv->db, stmt, get_string_cb , &ret, error);
        sqlite3_free (stmt);
 
-       READER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        return ret;
 }
@@ -3583,26 +3622,29 @@ e_book_backend_sqlitedb_set_sync_data (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (folderid != NULL, FALSE);
        g_return_val_if_fail (sync_data != NULL, FALSE);
 
-       if (!book_backend_sqlitedb_start_transaction (ebsdb, error))
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!book_backend_sqlitedb_start_transaction (ebsdb, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
                return FALSE;
+       }
 
        stmt = sqlite3_mprintf (
-               "UPDATE folders SET sync_data = %Q "
+               "UPDATE folders SET sync_data = %Q "
                "WHERE folder_id = %Q", sync_data, folderid);
        success = book_backend_sql_exec (
-               ebsdb->priv->db, stmt, NULL, NULL, error);
+               ebsdb->priv->db, stmt, NULL, NULL, error);
        sqlite3_free (stmt);
 
-       if (!success)
-               goto rollback;
+       if (success)
+               success = book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       else
+               /* The GError is already set. */
+               book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
 
-       return book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
-rollback:
-       /* The GError is already set. */
-       book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
-
-       return FALSE;
+       return success;
 }
 
 /**
@@ -3624,7 +3666,7 @@ e_book_backend_sqlitedb_get_key_value (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (folderid != NULL, NULL);
        g_return_val_if_fail (key != NULL, NULL);
 
-       READER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        stmt = sqlite3_mprintf (
                "SELECT value FROM keys WHERE folder_id = %Q AND key = %Q",
@@ -3633,7 +3675,7 @@ e_book_backend_sqlitedb_get_key_value (EBookBackendSqliteDB *ebsdb,
                ebsdb->priv->db, stmt, get_string_cb , &ret, error);
        sqlite3_free (stmt);
 
-       READER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        return ret;
 }
@@ -3660,26 +3702,29 @@ e_book_backend_sqlitedb_set_key_value (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (key != NULL, FALSE);
        g_return_val_if_fail (value != NULL, FALSE);
 
-       if (!book_backend_sqlitedb_start_transaction (ebsdb, error))
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!book_backend_sqlitedb_start_transaction (ebsdb, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
                return FALSE;
+       }
 
        stmt = sqlite3_mprintf (
-               "INSERT or REPLACE INTO keys (key, value, folder_id) "
+               "INSERT or REPLACE INTO keys (key, value, folder_id) "
                "values (%Q, %Q, %Q)", key, value, folderid);
        success = book_backend_sql_exec (
-               ebsdb->priv->db, stmt, NULL, NULL, error);
+               ebsdb->priv->db, stmt, NULL, NULL, error);
        sqlite3_free (stmt);
 
-       if (!success)
-               goto rollback;
-
-       return book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       if (success)
+               success = book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       else
+               /* The GError is already set. */
+               book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
 
-rollback:
-       /* The GError is already set. */
-       book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
-       return FALSE;
+       return success;
 }
 
 /**
@@ -3700,7 +3745,7 @@ e_book_backend_sqlitedb_get_partially_cached_ids (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), NULL);
        g_return_val_if_fail (folderid != NULL, NULL);
 
-       READER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        stmt = sqlite3_mprintf (
                "SELECT uid FROM %Q WHERE partial_content = 1",
@@ -3709,7 +3754,7 @@ e_book_backend_sqlitedb_get_partially_cached_ids (EBookBackendSqliteDB *ebsdb,
                ebsdb->priv->db, stmt, addto_slist_cb, &uids, error);
        sqlite3_free (stmt);
 
-       READER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        return uids;
 }
@@ -3732,8 +3777,12 @@ e_book_backend_sqlitedb_delete_addressbook (EBookBackendSqliteDB *ebsdb,
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
        g_return_val_if_fail (folderid != NULL, FALSE);
 
-       if (!book_backend_sqlitedb_start_transaction (ebsdb, error))
+       LOCK_MUTEX (&ebsdb->priv->lock);
+
+       if (!book_backend_sqlitedb_start_transaction (ebsdb, error)) {
+               UNLOCK_MUTEX (&ebsdb->priv->lock);
                return FALSE;
+       }
 
        /* delete the contacts table */
        stmt = sqlite3_mprintf ("DROP TABLE %Q ", folderid);
@@ -3764,12 +3813,17 @@ e_book_backend_sqlitedb_delete_addressbook (EBookBackendSqliteDB *ebsdb,
        if (!success)
                goto rollback;
 
-       return book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       success = book_backend_sqlitedb_commit_transaction (ebsdb, error);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
+
+       return success;
 
 rollback:
        /* The GError is already set. */
        book_backend_sqlitedb_rollback_transaction (ebsdb, NULL);
 
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
+
        return FALSE;
 }
 
@@ -3807,7 +3861,7 @@ e_book_backend_sqlitedb_remove (EBookBackendSqliteDB *ebsdb,
 
        g_return_val_if_fail (E_IS_BOOK_BACKEND_SQLITEDB (ebsdb), FALSE);
 
-       WRITER_LOCK (ebsdb);
+       LOCK_MUTEX (&ebsdb->priv->lock);
 
        sqlite3_close (ebsdb->priv->db);
 
@@ -3815,7 +3869,7 @@ e_book_backend_sqlitedb_remove (EBookBackendSqliteDB *ebsdb,
        ret = g_unlink (filename);
        g_free (filename);
 
-       WRITER_UNLOCK (ebsdb);
+       UNLOCK_MUTEX (&ebsdb->priv->lock);
 
        if (ret == -1) {
                g_set_error (


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