aboutsummaryrefslogtreecommitdiff
path: root/odb/sqlite/connection.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-03-29 16:31:59 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-03-29 16:31:59 +0200
commit7aadac132d8512e7ee63970561f40ade80772726 (patch)
tree001695ad14cd9c2e6937a8e5d45a32587d0a37d5 /odb/sqlite/connection.cxx
parent2cdc08a9bcf807b4b908434c7bbe5439b0da3191 (diff)
Support for shared cache and unlock notification
Diffstat (limited to 'odb/sqlite/connection.cxx')
-rw-r--r--odb/sqlite/connection.cxx55
1 files changed, 52 insertions, 3 deletions
diff --git a/odb/sqlite/connection.cxx b/odb/sqlite/connection.cxx
index 9af5a3b..91b430a 100644
--- a/odb/sqlite/connection.cxx
+++ b/odb/sqlite/connection.cxx
@@ -7,14 +7,22 @@
#include <string>
#include <cassert>
+#include <odb/details/lock.hxx>
+
#include <odb/sqlite/database.hxx>
#include <odb/sqlite/connection.hxx>
#include <odb/sqlite/statement.hxx>
#include <odb/sqlite/statement-cache.hxx>
#include <odb/sqlite/error.hxx>
+#include <odb/sqlite/exceptions.hxx> // deadlock
+
+#include <odb/sqlite/details/config.hxx> // LIBODB_SQLITE_HAVE_UNLOCK_NOTIFY
using namespace std;
+extern "C" void
+odb_sqlite_connection_unlock_callback (void**, int);
+
namespace odb
{
namespace sqlite
@@ -29,10 +37,10 @@ namespace odb
}
connection::
- connection (database_type& db)
- : db_ (db), statements_ (0)
+ connection (database_type& db, int extra_flags)
+ : db_ (db), unlock_cond_ (unlock_mutex_), statements_ (0)
{
- int f (db.flags ());
+ int f (db.flags () | extra_flags);
const string& n (db.name ());
// If we are opening a temporary database, then add the create flag.
@@ -57,6 +65,41 @@ namespace odb
statement_cache_.reset (new statement_cache_type (*this));
}
+ inline void
+ connection_unlock_callback (void** args, int n)
+ {
+ for (int i (0); i < n; ++i)
+ {
+ connection* c (static_cast<connection*> (args[i]));
+ details::lock l (c->unlock_mutex_);
+ c->unlocked_ = true;
+ c->unlock_cond_.signal ();
+ }
+ }
+
+ void connection::
+ wait ()
+ {
+#ifdef LIBODB_SQLITE_HAVE_UNLOCK_NOTIFY
+ unlocked_ = false;
+
+ // unlock_notify() returns SQLITE_OK or SQLITE_LOCKED (deadlock).
+ //
+ int e (sqlite3_unlock_notify (handle_,
+ &odb_sqlite_connection_unlock_callback,
+ this));
+ if (e == SQLITE_LOCKED)
+ throw deadlock ();
+
+ details::lock l (unlock_mutex_);
+
+ while (!unlocked_)
+ unlock_cond_.wait ();
+#else
+ translate_error (SQLITE_LOCKED, *this);
+#endif
+ }
+
void connection::
clear ()
{
@@ -75,3 +118,9 @@ namespace odb
}
}
}
+
+extern "C" void
+odb_sqlite_connection_unlock_callback (void** args, int n)
+{
+ odb::sqlite::connection_unlock_callback (args, n);
+}