// file : common/threads/driver.cxx // author : Boris Kolpackov // copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file // Test operations in a multi-threaded environment. // #include #include // std::auto_ptr #include // std::size_t #include #include #include #include #include #include #include #include "test.hxx" #include "test-odb.hxx" using namespace std; using namespace odb; const unsigned long thread_count = 32; const unsigned long iteration_count = 100; struct task { task (database& db, unsigned long n) : db_ (db), n_ (n) { } void execute () { try { for (unsigned long i (0); i < iteration_count; ++i) { unsigned long id ((n_ * iteration_count + i) * 3); { object o1 (id, "frist 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 (); } { transaction t (db_.begin ()); auto_ptr o (db_.load (id)); assert (o->str_ == "frist object"); o->str_ = "another value"; db_.update (*o); t.commit (); } { typedef odb::query query; typedef odb::result result; transaction t (db_.begin ()); result r (db_.query (query::str == "another value", 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 (); } { transaction t (db_.begin ()); db_.erase (id); t.commit (); } } } catch (const odb::exception& e) { cerr << e.what () << endl; } } static void* execute (void* arg) { static_cast (arg)->execute (); return 0; } database& db_; unsigned long n_; }; void test (int argc, char* argv[], size_t max_connections) { auto_ptr db (create_database (argc, argv, max_connections)); vector > threads; vector > tasks; for (unsigned long i (0); i < thread_count; ++i) { details::shared_ptr t (new (details::shared) task (*db, i)); tasks.push_back (t); threads.push_back ( details::shared_ptr ( new (details::shared) details::thread (&task::execute, t.get ()))); } for (unsigned long i (0); i < thread_count; ++i) threads[i]->join (); { typedef odb::result result; transaction t (db->begin ()); result r (db->query ()); for (result::iterator i (r.begin ()); i != r.end (); ++i) db->erase (i->id_); t.commit (); } } int main (int argc, char* argv[]) { try { test (argc, argv, 0); test (argc, argv, thread_count - 1); test (argc, argv, thread_count / 2); test (argc, argv, thread_count / 4); } catch (const odb::exception& e) { cerr << e.what () << endl; return 1; } }