From 27a6fdf4b5295281853254cfdde8730128038dd2 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 29 Mar 2011 16:33:41 +0200 Subject: Handle deadlocks and SQLite-specific issues --- common/threads/driver.cxx | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) (limited to 'common') diff --git a/common/threads/driver.cxx b/common/threads/driver.cxx index 9aab254..192a3b7 100644 --- a/common/threads/driver.cxx +++ b/common/threads/driver.cxx @@ -18,8 +18,13 @@ #include #include +#include // DATABASE_SQLITE #include +#ifdef DATABASE_SQLITE +# include +#endif + #include "test.hxx" #include "test-odb.hxx" @@ -28,7 +33,8 @@ using namespace odb::core; namespace details = odb::details; const unsigned long thread_count = 32; -const unsigned long iteration_count = 100; +const unsigned long iteration_count = 50; +const unsigned long sub_iteration_count = 20; struct task { @@ -47,7 +53,7 @@ struct task unsigned long id ((n_ * iteration_count + i) * 3); { - object o1 (id, "frist object"); + object o1 (id, "first object"); object o2 (id + 1, "second object"); object o3 (id + 2, "third object"); @@ -58,15 +64,37 @@ struct task t.commit (); } + // The following transaction may lead to a deadlock in some database + // implementations (read to write lock upgrade). + // + while (true) { - transaction t (db_.begin ()); - auto_ptr o (db_.load (id)); - assert (o->str_ == "frist object"); - o->str_ = "another value"; - db_.update (*o); - t.commit (); + try + { +#ifndef DATABASE_SQLITE + transaction t (db_.begin ()); +#else + // SQLite has a peculiar table locking mode (shared cache) + // which can lead to any of the transactions in this test + // deadlocking even though they shouldn't from the user's + // perspective. One way to work around this problem is to + // start a "write" transaction as such right away. + // + transaction t ( + static_cast (db_).begin_immediate ()); +#endif + + auto_ptr o (db_.load (id)); + assert (o->str_ == "first object"); + o->str_ = "another value"; + db_.update (*o); + t.commit (); + break; + } + catch (deadlock const&) {} } + for (unsigned long j (0); j < sub_iteration_count; ++j) { typedef odb::query query; typedef odb::result result; -- cgit v1.1