From 3094ff6e3bf9122eaf52df43f9a02f0c33fdc3a3 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 5 Sep 2009 00:16:46 +0000 Subject: [PATCH] Made thread saftey a compilation option for performance and dependencies reasons --- .../chaiscript/dispatchkit/boxed_value.hpp | 7 +- .../chaiscript/dispatchkit/dispatchkit.hpp | 78 ++++++++++++------- .../chaiscript/language/chaiscript_engine.hpp | 12 +++ src/multithreaded.cpp | 2 +- 4 files changed, 63 insertions(+), 36 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index d553e62..4399809 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -8,6 +8,7 @@ #define __boxed_value_hpp__ #include "type_info.hpp" +#include "../chaiscript_threading.hpp" #include #include #include @@ -280,11 +281,7 @@ namespace chaiscript */ Object_Cache &get_object_cache() { - static boost::thread_specific_ptr oc; - if (!oc.get()) - { - oc.reset(new Object_Cache); - } + static chaiscript::threading::Thread_Storage oc; return *oc; } diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 0fbfb1f..8ab919a 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -18,12 +18,12 @@ #include #include #include -#include #include "boxed_value.hpp" #include "type_info.hpp" #include "proxy_functions.hpp" #include "proxy_constructors.hpp" +#include "../chaiscript_threading.hpp" namespace chaiscript { @@ -230,7 +230,10 @@ namespace chaiscript validate_object_name(name); stack.get<0>().erase(name); +#ifndef CHAISCRIPT_NO_THREADS boost::unique_lock l(m_shared_object_mutex); +#endif + m_shared_objects[name] = obj; } @@ -264,15 +267,6 @@ namespace chaiscript } } - /** - * Returns the current stack - */ - Stack get_stack() - { - setup_stack(); - return m_thread_stack->stack; - } - /** * Swaps out the stack with a new stack * \returns the old stack @@ -280,10 +274,8 @@ namespace chaiscript */ Stack set_stack(const Stack &s) { - setup_stack(); - - Stack old = m_thread_stack->stack; - m_thread_stack->stack = s; + Stack old = m_stack_holder->stack; + m_stack_holder->stack = s; return old; } @@ -295,10 +287,19 @@ namespace chaiscript return s; } + Stack get_stack() const + { + return m_stack_holder->stack; + } + void sync_cache() { - get_stack()->get<0>().clear(); + m_stack_holder->stack->get<0>().clear(); + +#ifndef CHAISCRIPT_NO_THREADS boost::shared_lock l(m_mutex); +#endif + get_function_cache() = m_functions; } @@ -339,7 +340,10 @@ namespace chaiscript // Are we in the 0th stack and should check the shared objects? if (stack.get<2>()) { +#ifndef CHAISCRIPT_NO_THREADS boost::shared_lock l(m_shared_object_mutex); +#endif + itr = m_shared_objects.find(name); if (itr != m_shared_objects.end()) { @@ -366,7 +370,10 @@ namespace chaiscript */ void add(const Type_Info &ti, const std::string &name) { +#ifndef CHAISCRIPT_NO_THREADS boost::unique_lock l(m_mutex); +#endif + m_types.insert(std::make_pair(name, ti)); } @@ -375,7 +382,10 @@ namespace chaiscript */ Type_Info get_type(const std::string &name) const { +#ifndef CHAISCRIPT_NO_THREADS boost::shared_lock l(m_mutex); +#endif + Type_Name_Map::const_iterator itr = m_types.find(name); if (itr != m_types.end()) @@ -393,7 +403,10 @@ namespace chaiscript */ std::string get_type_name(const Type_Info &ti) const { +#ifndef CHAISCRIPT_NO_THREADS boost::shared_lock l(m_mutex); +#endif + for (Type_Name_Map::const_iterator itr = m_types.begin(); itr != m_types.end(); ++itr) @@ -412,7 +425,10 @@ namespace chaiscript */ std::vector > get_types() const { +#ifndef CHAISCRIPT_NO_THREADS boost::shared_lock l(m_mutex); +#endif + return std::vector >(m_types.begin(), m_types.end()); } @@ -448,7 +464,10 @@ namespace chaiscript void add_reserved_word(const std::string &name) { +#ifndef CHAISCRIPT_NO_THREADS boost::unique_lock l(m_mutex); +#endif + m_reserved_words.insert(name); } @@ -464,34 +483,27 @@ namespace chaiscript private: /** * Returns the current stack + * make const/non const versions */ StackData &get_stack_data() const { - setup_stack(); - return *(m_thread_stack->stack); + return *(m_stack_holder->stack); } std::multimap &get_function_cache() const { - setup_stack(); - return m_thread_stack->function_cache; + return m_stack_holder->function_cache; } - void setup_stack() const - { - if (!m_thread_stack.get()) - { - m_thread_stack.reset(new Stack_Holder(new_stack())); - m_thread_stack->stack->get<2>() = true; - } - } /** * Throw a reserved_word exception if the name is not allowed */ void validate_object_name(const std::string &name) const { +#ifndef CHAISCRIPT_NO_THREADS boost::shared_lock l(m_mutex); +#endif if (m_reserved_words.find(name) != m_reserved_words.end()) { @@ -506,7 +518,9 @@ namespace chaiscript */ bool add_function(const Proxy_Function &f, const std::string &t_name) { +#ifndef CHAISCRIPT_NO_THREADS boost::unique_lock l(m_mutex); +#endif std::pair::const_iterator, std::multimap::const_iterator> range = m_functions.equal_range(t_name); @@ -526,14 +540,17 @@ namespace chaiscript return true; } +#ifndef CHAISCRIPT_NO_THREADS mutable boost::shared_mutex m_mutex; mutable boost::shared_mutex m_shared_object_mutex; +#endif struct Stack_Holder { - Stack_Holder(Stack s) - : stack(s) + Stack_Holder() + : stack(new StackData()) { + stack->get<2>() = true; } Stack stack; @@ -541,7 +558,8 @@ namespace chaiscript std::multimap function_cache; }; - mutable boost::thread_specific_ptr m_thread_stack; + chaiscript::threading::Thread_Storage m_stack_holder; + std::multimap m_functions; std::map m_shared_objects; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 058a6cc..51f02e9 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -21,8 +21,11 @@ namespace chaiscript Eval_Engine engine; std::set loaded_files; + +#ifndef CHAISCRIPT_NO_THREADS mutable boost::shared_mutex mutex; mutable boost::recursive_mutex use_mutex; +#endif /** @@ -40,12 +43,16 @@ namespace chaiscript // to the parser. This is so that the parser does not have the overhead of passing // around and copying strings // +#ifndef CHAISCRIPT_NO_THREADS boost::unique_lock l(mutex); +#endif loaded_files.insert(filename); try { if (parser.parse(input, loaded_files.find(filename)->c_str())) { +#ifndef CHAISCRIPT_NO_THREADS l.unlock(); +#endif //parser.show_match_stack(); value = eval_token(engine, parser.ast()); } @@ -68,11 +75,16 @@ namespace chaiscript void use(const std::string &filename) { +#ifndef CHAISCRIPT_NO_THREADS boost::lock_guard l(use_mutex); boost::shared_lock l2(mutex); +#endif + if (loaded_files.count(filename) == 0) { +#ifndef CHAISCRIPT_NO_THREADS l2.unlock(); +#endif eval_file(filename); } else { engine.sync_cache(); diff --git a/src/multithreaded.cpp b/src/multithreaded.cpp index 3b78808..b7e9187 100644 --- a/src/multithreaded.cpp +++ b/src/multithreaded.cpp @@ -9,7 +9,7 @@ #include #include - +#include void do_work(chaiscript::ChaiScript &c) {