diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-03-29 16:31:59 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-03-29 16:31:59 +0200 |
commit | 7aadac132d8512e7ee63970561f40ade80772726 (patch) | |
tree | 001695ad14cd9c2e6937a8e5d45a32587d0a37d5 /odb/sqlite/connection.cxx | |
parent | 2cdc08a9bcf807b4b908434c7bbe5439b0da3191 (diff) |
Support for shared cache and unlock notification
Diffstat (limited to 'odb/sqlite/connection.cxx')
-rw-r--r-- | odb/sqlite/connection.cxx | 55 |
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); +} |