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



commit 5388a319326fa5db8b137bbce225a5cc2a445d4a
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 dc6a703..cbd51c4 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]