[evolution-data-server/gnome-3-0] addressbook file backend: libdb must be initialized for concurrent read/write



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]