[Top][All Lists]

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

[Monotone-devel] RFC: do no exit mtn if database is locked

From: Thomas Keller
Subject: [Monotone-devel] RFC: do no exit mtn if database is locked
Date: Fri, 27 Oct 2006 16:36:46 +0200
User-agent: Thunderbird 1.5 (X11/20060317)

Hi all!

I've written (and attached) a small, yet incomplete patch to handle the
mtn error "Database is locked" from SQLite. SQLite has a special
function[0] with which it triggers a callback whenever SQLITE_BUSY pops
up (e.g. during sqlite3_exec). This callback has to return nonzero to
block any running request from returning immediately with SQLITE_BUSY
and could contain code to notify the user of waiting and putting the
current process to sleep (in the hope that the other process who also
uses the db exits some time).

Now, while all this sounds pretty straight forward, I remembered
unfortunately that there is no platform independent version of
(u)sleep() available in C++, so I checked boost and found
boost::thread::sleep(). My first compilation showed me however that
boost threads have been specifically disabled for monotone and I now
wonder why this is the case? (I read m4/boost.m4's comments, but still
don't know why...)
I don't know if it is the right thing to enable boost_threads just for
the sleep thing (the other possibility would be using ifdef's directly
in place for the particular platforms, but I can only test Linux and
Mac, nothing else...) - in general, I'm thinking "use a library, trust
their code" might be the better version. But one of the core developers
might disagree here.



- "I know that I don't know." (Sokrates)
Guitone, a frontend for monotone:
Music lyrics and more:
# old_revision [207c6adcf37658180f428d49c7d1a2eef33d547d]
# patch ""
#  from [c7696873fbacdd84c3ee1265b4bc2d6bf6fa86e5]
#    to [7b407a1a235bacceeeb40c4c384976e3e1770023]
--- c7696873fbacdd84c3ee1265b4bc2d6bf6fa86e5
+++ 7b407a1a235bacceeeb40c4c384976e3e1770023
@@ -18,6 +18,7 @@
 #include <string.h>
+#include <boost/thread.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/lexical_cast.hpp>
@@ -294,6 +295,22 @@ assert_sqlite3_ok(sqlite3 *s)
   E(false, F("sqlite error: %s\n%s") % errmsg % auxiliary_message);
+static int
+sqlite3_busy_handler_callback(void * dummy, int tries)
+    W(F("database is busy, waiting (%d)") % tries);
+    // sleep a second, the boost way
+    boost::xtime xt;
+    boost::xtime_get(&xt, boost::TIME_UTC);
+    xt.sec += 1;
+    boost::thread::sleep(xt);
+    // return 0 here if this should be the last try, for now, we always
+    // want to retry
+    return 1;
 struct sqlite3 *
 database::sql(bool init, bool migrating_format)
@@ -313,6 +330,9 @@ database::sql(bool init, bool migrating_
           sqlite3_exec(__sql, schema_constant, NULL, NULL, NULL);
+          // add a busy_handler callback to avoid that mtn exits
+          // on SQLITE_BUSY errors
+          sqlite3_busy_handler(__sql, &sqlite3_busy_handler_callback, NULL);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]