[evolution-data-server] 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] addressbook file backend: libdb must be initialized for concurrent read/write
- Date: Mon, 16 May 2011 15:24:49 +0000 (UTC)
commit faada76f22cd192252b9f052183e9f1544a6da04
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).
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 7f8f465..6f33d8d 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]