From f88348f72d5267f76fb338e3e96a111225cc2ec0 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 27 Jul 2015 17:20:35 +0200 Subject: Make threads test more deadlock resilient --- common/threads/driver.cxx | 94 ++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 38 deletions(-) diff --git a/common/threads/driver.cxx b/common/threads/driver.cxx index bf12707..2bc1897 100644 --- a/common/threads/driver.cxx +++ b/common/threads/driver.cxx @@ -31,9 +31,9 @@ using namespace std; using namespace odb::core; namespace details = odb::details; -const unsigned long thread_count = 32; -const unsigned long iteration_count = 50; -const unsigned long sub_iteration_count = 20; +const unsigned long thread_count = 24; +const unsigned long iteration_count = 30; +const unsigned long sub_iteration_count = 40; struct task { @@ -51,21 +51,26 @@ struct task { unsigned long id ((n_ * iteration_count + i) * 3); + object o1 (id, "first object"); + object o2 (id + 1, "second object"); + object o3 (id + 2, "third object"); + + // The following transactions may lead to deadlocks. + // + while (true) { - object o1 (id, "first object"); - object o2 (id + 1, "second object"); - object o3 (id + 2, "third object"); - - transaction t (db_.begin ()); - db_.persist (o1); - db_.persist (o2); - db_.persist (o3); - t.commit (); + try + { + transaction t (db_.begin ()); + db_.persist (o1); + db_.persist (o2); + db_.persist (o3); + t.commit (); + break; + } + catch (const deadlock&) {} } - // The following transaction may lead to a deadlock in some database - // implementations (read to write lock upgrade). - // while (true) { try @@ -105,37 +110,50 @@ struct task typedef odb::prepared_query prep_query; typedef odb::result result; - transaction t (db_.begin ()); - - prep_query pq (db_.lookup_query ("object-query")); - - if (!pq) + while (true) { - pq = db_.prepare_query ( - "object-query", query::str == "another value"); - db_.cache_query (pq); - } - - result r (pq.execute (false)); - - bool found (false); - for (result::iterator i (r.begin ()); i != r.end (); ++i) - { - if (i->id_ == id) + try { - found = true; + transaction t (db_.begin ()); + + prep_query pq (db_.lookup_query ("object-query")); + + if (!pq) + { + pq = db_.prepare_query ( + "object-query", query::str == "another value"); + db_.cache_query (pq); + } + + result r (pq.execute (false)); + + bool found (false); + for (result::iterator i (r.begin ()); i != r.end (); ++i) + { + if (i->id_ == id) + { + found = true; + break; + } + } + assert (found); + t.commit (); break; } + catch (const deadlock&) {} } - assert (found); - - t.commit (); } + while (true) { - transaction t (db_.begin ()); - db_.erase (id); - t.commit (); + try + { + transaction t (db_.begin ()); + db_.erase (id); + t.commit (); + break; + } + catch (const deadlock&) {} } } } -- cgit v1.1