aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-09-28 10:51:12 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-09-28 10:51:12 +0200
commitb4825d95472f8d9e2b9892a56c585a035b6230ac (patch)
tree05d7124cc044205160c4bf4c8bcf8a7bf87dc2d4
parent2e258ea80deae21b478c6aa8deae50bd24194c11 (diff)
Make schema version access (but not modification) thread-safe
Also cache the version in statements so that we don't have to lock the mutex (slow) every time we need to check the version.
-rw-r--r--odb/database.cxx25
-rw-r--r--odb/database.hxx28
-rw-r--r--odb/database.ixx15
3 files changed, 29 insertions, 39 deletions
diff --git a/odb/database.cxx b/odb/database.cxx
index c9692ba..5578abd 100644
--- a/odb/database.cxx
+++ b/odb/database.cxx
@@ -4,10 +4,14 @@
#include <odb/database.hxx>
+#include <odb/details/lock.hxx>
+
using namespace std;
namespace odb
{
+ using details::lock;
+
database::
~database ()
{
@@ -20,25 +24,23 @@ namespace odb
return c.execute (st, n);
}
- const database::schema_version_info& database::
- schema_version_migration_ (const string& name) const
+ const database::schema_version_migration_type& database::
+ schema_version_migration (const string& name) const
{
+ lock l (mutex_); // Prevents concurrent loading.
+
schema_version_map::const_iterator i (schema_version_map_.find (name));
- const schema_version_info& svi (
- i != schema_version_map_.end () && i->second.version != 0
+ return i != schema_version_map_.end () && i->second.version != 0
? i->second
- : load_schema_version (name));
-
- if (default_schema_version_ == 0 && name.empty ())
- default_schema_version_ = &svi;
-
- return svi;
+ : load_schema_version (name);
}
void database::
schema_version_migration (const schema_version_migration_type& svm,
const string& name)
{
+ // Note: no lock, not thread-safe.
+
schema_version_info& svi (schema_version_map_[name]);
if (svi.version != svm.version || svi.migration != svm.migration)
{
@@ -46,8 +48,5 @@ namespace odb
svi.migration = svm.migration;
schema_version_seq_++;
}
-
- if (default_schema_version_ == 0 && name.empty ())
- default_schema_version_ = &svi;
}
}
diff --git a/odb/database.hxx b/odb/database.hxx
index 7ddbecb..91d8e94 100644
--- a/odb/database.hxx
+++ b/odb/database.hxx
@@ -28,6 +28,7 @@
#include <odb/exceptions.hxx>
#include <odb/details/export.hxx>
+#include <odb/details/mutex.hxx>
#include <odb/details/c-string.hxx>
namespace odb
@@ -339,31 +340,34 @@ namespace odb
typedef odb::schema_version_migration schema_version_migration_type;
schema_version_type
- schema_version (const std::string& schema_name = std::string ()) const;
+ schema_version (const std::string& schema_name = "") const;
bool
- schema_migration (const std::string& schema_name = std::string ()) const;
+ schema_migration (const std::string& schema_name = "") const;
// Note that there is code that relies on the returned reference
// being valid until the version is changed or the database instance
// is destroyed.
//
const schema_version_migration_type&
- schema_version_migration (
- const std::string& schema_name = std::string ()) const;
+ schema_version_migration (const std::string& schema_name = "") const;
// Set schema version and migration state manually.
//
+ // Note that the modifier API is not thread-safe. That is, you should
+ // not modify the schema version while other threads may be accessing
+ // or modifying the same information.
+ //
void
schema_version_migration (schema_version_type,
bool migration,
- const std::string& schema_name = std::string ());
+ const std::string& schema_name = "");
void
schema_version_migration (const schema_version_migration_type&,
- const std::string& schema_name = std::string ());
+ const std::string& schema_name = "");
- // Set default schema version table for all schema names. The table
+ // Set default schema version table for all the schema names. The table
// name should already be quoted if necessary.
//
void
@@ -375,9 +379,9 @@ namespace odb
schema_version_table (const std::string& table_name,
const std::string& schema_name);
- // Schema version sequence number. It is incremented every time
- // the schema version or migration flag is changed and can be
- // used to detect version changes. The starting value is 1.
+ // Schema version sequence number. It is incremented every time the
+ // schema version or migration flag is changed and can be used to
+ // detect overall version changes. The starting value is 1.
//
unsigned int
schema_version_sequence () const;
@@ -485,9 +489,9 @@ namespace odb
tracer_type* tracer_;
query_factory_map query_factory_map_;
- std::string schema_version_table_;
+ mutable details::mutex mutex_;
mutable schema_version_map schema_version_map_;
- mutable const schema_version_info* default_schema_version_; // Cached.
+ std::string schema_version_table_;
unsigned int schema_version_seq_;
};
}
diff --git a/odb/database.ixx b/odb/database.ixx
index 378a376..a15bb7d 100644
--- a/odb/database.ixx
+++ b/odb/database.ixx
@@ -11,10 +11,7 @@ namespace odb
{
inline database::
database (database_id id)
- : id_ (id),
- tracer_ (0),
- default_schema_version_ (0),
- schema_version_seq_ (1)
+ : id_ (id), tracer_ (0), schema_version_seq_ (1)
{
}
@@ -36,16 +33,6 @@ namespace odb
return schema_version_migration (name).migration;
}
- inline const database::schema_version_migration_type& database::
- schema_version_migration (const std::string& name) const
- {
- return name.empty () &&
- default_schema_version_ != 0 &&
- default_schema_version_->version != 0
- ? *default_schema_version_
- : schema_version_migration_ (name);
- }
-
inline void database::
schema_version_migration (schema_version_type v,
bool m,