From faada76f22cd192252b9f052183e9f1544a6da04 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Mon, 16 May 2011 11:21:04 +0200 Subject: [PATCH] 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 file changed, 12 insertions(+), 1 deletion(-) 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)); -- 2.7.4