aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/module.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-10-22 14:32:49 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-10-22 14:32:49 +0200
commitdf69d473d3ab389e915698b8c2c4bb8d22975976 (patch)
tree3f624b109e8a91bb99aa649489f9a548ba088ddf /libbuild2/module.hxx
parent5483f5f54146ef6486db93a9a1c45b967d59c384 (diff)
Implement loaded_modules state locking
This would be necessary if someone runs two parallel top-level contexts.
Diffstat (limited to 'libbuild2/module.hxx')
-rw-r--r--libbuild2/module.hxx33
1 files changed, 33 insertions, 0 deletions
diff --git a/libbuild2/module.hxx b/libbuild2/module.hxx
index 3aaa1c7..50ca7da 100644
--- a/libbuild2/module.hxx
+++ b/libbuild2/module.hxx
@@ -10,6 +10,7 @@
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
+#include <libbuild2/context.hxx>
#include <libbuild2/variable.hxx>
#include <libbuild2/diagnostics.hxx>
@@ -153,6 +154,38 @@ namespace build2
// found.
//
using loaded_module_map = std::map<string, const module_functions*>;
+
+ // The loaded_modules map is locked per top-level (as opposed to nested)
+ // context (see context.hxx for details).
+ //
+ // Note: should only be constructed during context-wide serial execution.
+ //
+ class LIBBUILD2_SYMEXPORT loaded_modules_lock
+ {
+ public:
+ explicit
+ loaded_modules_lock (context& c)
+ : ctx_ (c), lock_ (mutex_, defer_lock)
+ {
+ if (ctx_.modules_lock == nullptr)
+ {
+ lock_.lock ();
+ ctx_.modules_lock = this;
+ }
+ }
+
+ ~loaded_modules_lock ()
+ {
+ if (ctx_.modules_lock == this)
+ ctx_.modules_lock = nullptr;
+ }
+
+ private:
+ static mutex mutex_;
+ context& ctx_;
+ mlock lock_;
+ };
+
LIBBUILD2_SYMEXPORT extern loaded_module_map loaded_modules;
// Load a builtin module (i.e., a module linked as a static/shared library