[evolution-data-server] Limit SQLite busy-wait for a lock



commit 67bf39213939c4092251775a95113b33df2426a2
Author: Milan Crha <mcrha redhat com>
Date:   Wed Nov 19 11:13:51 2014 +0100

    Limit SQLite busy-wait for a lock
    
    The previous busy-wait could cause flood of the kernel with a lock
    request, with basically no outer limit. This change adds a 15 seconds
    time limit with a 100 ms delay between each lock request.

 .../libedata-book/e-book-backend-sqlitedb.c        |    9 ++++++++-
 addressbook/libedata-book/e-book-sqlite.c          |    8 +++++++-
 camel/camel-db.c                                   |   10 +++++++++-
 3 files changed, 24 insertions(+), 3 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.c 
b/addressbook/libedata-book/e-book-backend-sqlitedb.c
index 3ab1c9a..fa32132 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.c
@@ -320,15 +320,22 @@ book_backend_sql_exec_real (sqlite3 *db,
                             GError **error)
 {
        gchar *errmsg = NULL;
-       gint ret = -1;
+       gint ret = -1, retries = 0;
 
        ret = sqlite3_exec (db, stmt, callback, data, &errmsg);
        while (ret == SQLITE_BUSY || ret == SQLITE_LOCKED || ret == -1) {
+               /* try for ~15 seconds, then give up */
+               if (retries > 150)
+                       break;
+               retries++;
+
                if (errmsg) {
                        sqlite3_free (errmsg);
                        errmsg = NULL;
                }
                g_thread_yield ();
+               g_usleep (100 * 1000); /* Sleep for 100 ms */
+
                ret = sqlite3_exec (db, stmt, callback, data, &errmsg);
        }
 
diff --git a/addressbook/libedata-book/e-book-sqlite.c b/addressbook/libedata-book/e-book-sqlite.c
index 65cb5e7..682f9d6 100644
--- a/addressbook/libedata-book/e-book-sqlite.c
+++ b/addressbook/libedata-book/e-book-sqlite.c
@@ -1110,7 +1110,7 @@ ebsql_exec (EBookSqlite *ebsql,
 {
        gboolean had_cancel;
        gchar *errmsg = NULL;
-       gint ret = -1;
+       gint ret = -1, retries = 0;
        gint64 t1 = 0, t2;
 
        /* Debug output for statements and query plans */
@@ -1134,11 +1134,17 @@ ebsql_exec (EBookSqlite *ebsql,
        ret = sqlite3_exec (ebsql->priv->db, stmt, callback, data, &errmsg);
 
        while (ret == SQLITE_BUSY || ret == SQLITE_LOCKED || ret == -1) {
+               /* try for ~15 seconds, then give up */
+               if (retries > 150)
+                       break;
+               retries++;
+
                if (errmsg) {
                        sqlite3_free (errmsg);
                        errmsg = NULL;
                }
                g_thread_yield ();
+               g_usleep (100 * 1000); /* Sleep for 100 ms */
 
                if (t1)
                        t1 = g_get_monotonic_time();
diff --git a/camel/camel-db.c b/camel/camel-db.c
index e14f0ef..7dfea0a 100644
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@ -474,16 +474,24 @@ cdb_sql_exec (sqlite3 *db,
               GError **error)
 {
        gchar *errmsg = NULL;
-       gint   ret = -1;
+       gint   ret = -1, retries = 0;
 
        d (g_print ("Camel SQL Exec:\n%s\n", stmt));
 
        ret = sqlite3_exec (db, stmt, callback, data, &errmsg);
        while (ret == SQLITE_BUSY || ret == SQLITE_LOCKED || ret == -1) {
+               /* try for ~15 seconds, then give up */
+               if (retries > 150)
+                       break;
+               retries++;
+
                if (errmsg) {
                        sqlite3_free (errmsg);
                        errmsg = NULL;
                }
+               g_thread_yield ();
+               g_usleep (100 * 1000); /* Sleep for 100 ms */
+
                ret = sqlite3_exec (db, stmt, NULL, NULL, &errmsg);
        }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]