[evolution-data-server/gnome-3-0] addressbook file backend: libdb must be initialized for concurrent read/write
- From: Patrick Ohly <pohly src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-3-0] addressbook file backend: libdb must be initialized for concurrent read/write
- Date: Mon, 16 May 2011 15:43:59 +0000 (UTC)
commit 39d49903230cc1e106289709fad482c10f4baabb
Author: Patrick Ohly <patrick ohly intel com>
Date: Mon May 16 11:21:04 2011 +0200
addressbook file backend: libdb must be initialized for concurrent read/write
Very bad performance (100% CPU load, several minutes run time) were
seen for multiple concurrent writes. gdb shows that libdb is
apparently busy polling while writing.
The libdb API docs for DB_ENV->open() imply that either DB_INIT_CDB or
DB_INIT_LOCK must be used in apps which are not read-only, like
EDS. This patch adds DB_INIT_CDB because it is simple and fixes the
performance problem.
In some rare cases, DB_INIT_LOCK might provide better performance by
allowing concurrent writes of independent data, but that seems too
complicated for not enough gain right now (must check for deadlocks).
(cherry picked from commit faada76f22cd192252b9f052183e9f1544a6da04)
addressbook/backends/file/e-book-backend-file.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
---
diff --git a/addressbook/backends/file/e-book-backend-file.c b/addressbook/backends/file/e-book-backend-file.c
index bdb0d4d..8ace93e 100644
--- a/addressbook/backends/file/e-book-backend-file.c
+++ b/addressbook/backends/file/e-book-backend-file.c
@@ -1143,7 +1143,18 @@ e_book_backend_file_load_source (EBookBackend *backend,
(gpointer (*)(gpointer , gsize))g_try_realloc,
g_free);
- db_error = (*env->open) (env, NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_THREAD, 0);
+ /*
+ * We need either DB_INIT_CDB or DB_INIT_LOCK, because we will have
+ * multiple threads reading and writing concurrently without
+ * any locking above libdb.
+ *
+ * DB_INIT_CDB enforces multiple reader/single writer by locking inside
+ * the database. It is used instead of DB_INIT_LOCK because DB_INIT_LOCK
+ * may deadlock, which would have to be called in a separate thread.
+ * Considered too complicated for not enough gain (= concurrent writes)
+ * at this point.
+ */
+ db_error = (*env->open) (env, NULL, DB_INIT_CDB | DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_THREAD, 0);
if (db_error != 0) {
env->close (env, 0);
g_warning ("db_env_open failed with %s", db_strerror (db_error));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]