[evolution-data-server/evolution-data-server-3-12] [SQLite VFS] Track pending sync requests
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/evolution-data-server-3-12] [SQLite VFS] Track pending sync requests
- Date: Fri, 5 Dec 2014 11:35:48 +0000 (UTC)
commit a1bc3301e7e2d5ad810370f048c209d45f709017
Author: Milan Crha <mcrha redhat com>
Date: Fri Dec 5 12:22:05 2014 +0100
[SQLite VFS] Track pending sync requests
The sync request are done asynchronously, in a dedicated thread,
which means that the database file can be closed meanwhile. The
database has no reference counting, thus it's required to track
whether there are any pending sync requests, to not free the
structure too early.
camel/camel-db.c | 29 +++++++++++++++++++++++++++++
libebackend/e-sqlite3-vfs.c | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 0 deletions(-)
---
diff --git a/camel/camel-db.c b/camel/camel-db.c
index fb0e581..0106741 100644
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@ -53,6 +53,12 @@ typedef struct {
GRecMutex sync_mutex;
guint timeout_id;
gint flags;
+
+ /* Do know how many syncs are pending, to not close
+ the file before the last sync is over */
+ guint pending_syncs;
+ GMutex pending_syncs_lock;
+ GCond pending_syncs_cond;
} CamelSqlite3File;
static gint
@@ -91,6 +97,13 @@ sync_request_thread_cb (gpointer task_data,
call_old_file_Sync (sync_data->cFile, sync_data->flags);
+ g_mutex_lock (&sync_data->cFile->pending_syncs_lock);
+ g_warn_if_fail (sync_data->cFile->pending_syncs > 0);
+ sync_data->cFile->pending_syncs--;
+ if (!sync_data->cFile->pending_syncs)
+ g_cond_signal (&sync_data->cFile->pending_syncs_cond);
+ g_mutex_unlock (&sync_data->cFile->pending_syncs_lock);
+
done = sync_data->done;
g_free (sync_data);
@@ -136,6 +149,10 @@ sync_push_request (CamelSqlite3File *cFile,
cFile->flags = 0;
+ g_mutex_lock (&cFile->pending_syncs_lock);
+ cFile->pending_syncs++;
+ g_mutex_unlock (&cFile->pending_syncs_lock);
+
g_rec_mutex_unlock (&cFile->sync_mutex);
g_thread_pool_push (sync_pool, data, &error);
@@ -269,6 +286,12 @@ camel_sqlite3_file_xClose (sqlite3_file *pFile)
/* Make the last sync. */
sync_push_request (cFile, TRUE);
+ g_mutex_lock (&cFile->pending_syncs_lock);
+ while (cFile->pending_syncs > 0) {
+ g_cond_wait (&cFile->pending_syncs_cond, &cFile->pending_syncs_lock);
+ }
+ g_mutex_unlock (&cFile->pending_syncs_lock);
+
if (cFile->old_vfs_file->pMethods)
res = cFile->old_vfs_file->pMethods->xClose (cFile->old_vfs_file);
else
@@ -278,6 +301,8 @@ camel_sqlite3_file_xClose (sqlite3_file *pFile)
cFile->old_vfs_file = NULL;
g_rec_mutex_clear (&cFile->sync_mutex);
+ g_mutex_clear (&cFile->pending_syncs_lock);
+ g_cond_clear (&cFile->pending_syncs_cond);
return res;
}
@@ -340,6 +365,10 @@ camel_sqlite3_vfs_xOpen (sqlite3_vfs *pVfs,
}
g_rec_mutex_init (&cFile->sync_mutex);
+ g_mutex_init (&cFile->pending_syncs_lock);
+ g_cond_init (&cFile->pending_syncs_cond);
+
+ cFile->pending_syncs = 0;
g_rec_mutex_lock (&only_once_lock);
diff --git a/libebackend/e-sqlite3-vfs.c b/libebackend/e-sqlite3-vfs.c
index cf49682..264b734 100644
--- a/libebackend/e-sqlite3-vfs.c
+++ b/libebackend/e-sqlite3-vfs.c
@@ -40,6 +40,12 @@ typedef struct {
GRecMutex sync_mutex;
guint timeout_id;
gint flags;
+
+ /* Do know how many syncs are pending, to not close
+ the file before the last sync is over */
+ guint pending_syncs;
+ GMutex pending_syncs_lock;
+ GCond pending_syncs_cond;
} ESqlite3File;
static gint
@@ -72,6 +78,13 @@ sync_request_thread_cb (gpointer task_data,
call_old_file_Sync (sync_data->cFile, sync_data->flags);
+ g_mutex_lock (&sync_data->cFile->pending_syncs_lock);
+ g_warn_if_fail (sync_data->cFile->pending_syncs > 0);
+ sync_data->cFile->pending_syncs--;
+ if (!sync_data->cFile->pending_syncs)
+ g_cond_signal (&sync_data->cFile->pending_syncs_cond);
+ g_mutex_unlock (&sync_data->cFile->pending_syncs_lock);
+
sync_op = sync_data->sync_op;
g_free (sync_data);
@@ -92,6 +105,13 @@ sync_push_request (ESqlite3File *cFile,
g_rec_mutex_lock (&cFile->sync_mutex);
+ if (!cFile->flags) {
+ /* nothing to sync, might be when xClose is called
+ without any pending xSync request */
+ g_rec_mutex_unlock (&cFile->sync_mutex);
+ return;
+ }
+
if (wait_for_finish)
sync_op = e_flag_new ();
@@ -102,6 +122,10 @@ sync_push_request (ESqlite3File *cFile,
cFile->flags = 0;
+ g_mutex_lock (&cFile->pending_syncs_lock);
+ cFile->pending_syncs++;
+ g_mutex_unlock (&cFile->pending_syncs_lock);
+
g_rec_mutex_unlock (&cFile->sync_mutex);
g_thread_pool_push (sync_pool, data, &error);
@@ -227,6 +251,12 @@ e_sqlite3_file_xClose (sqlite3_file *pFile)
/* Make the last sync. */
sync_push_request (cFile, TRUE);
+ g_mutex_lock (&cFile->pending_syncs_lock);
+ while (cFile->pending_syncs > 0) {
+ g_cond_wait (&cFile->pending_syncs_cond, &cFile->pending_syncs_lock);
+ }
+ g_mutex_unlock (&cFile->pending_syncs_lock);
+
if (cFile->old_vfs_file->pMethods)
res = cFile->old_vfs_file->pMethods->xClose (cFile->old_vfs_file);
else
@@ -236,6 +266,8 @@ e_sqlite3_file_xClose (sqlite3_file *pFile)
cFile->old_vfs_file = NULL;
g_rec_mutex_clear (&cFile->sync_mutex);
+ g_mutex_clear (&cFile->pending_syncs_lock);
+ g_cond_clear (&cFile->pending_syncs_cond);
return res;
}
@@ -294,6 +326,10 @@ e_sqlite3_vfs_xOpen (sqlite3_vfs *pVfs,
}
g_rec_mutex_init (&cFile->sync_mutex);
+ g_mutex_init (&cFile->pending_syncs_lock);
+ g_cond_init (&cFile->pending_syncs_cond);
+
+ cFile->pending_syncs = 0;
g_rec_mutex_lock (&only_once_lock);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]