From 92c836c58acdc45bb46418343397a13a3f74ba8f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 25 Mar 2011 22:49:17 -0600 Subject: [PATCH] Simplify mutex code by providing stubs that are do nothing during CHAISCRIPT_NO_THREADS builds. --- include/chaiscript/chaiscript.hpp | 29 +++++--- include/chaiscript/chaiscript_threading.hpp | 40 +++++++++++ .../chaiscript/dispatchkit/bootstrap_stl.hpp | 11 +-- .../chaiscript/dispatchkit/dispatchkit.hpp | 67 ++++++------------- .../dispatchkit/dynamic_cast_conversion.hpp | 31 +++------ .../chaiscript/language/chaiscript_engine.hpp | 31 +++------ 6 files changed, 106 insertions(+), 103 deletions(-) diff --git a/include/chaiscript/chaiscript.hpp b/include/chaiscript/chaiscript.hpp index 10576ce..da1e4e5 100644 --- a/include/chaiscript/chaiscript.hpp +++ b/include/chaiscript/chaiscript.hpp @@ -7,15 +7,28 @@ #ifndef CHAISCRIPT_HPP_ #define CHAISCRIPT_HPP_ -#include -#include -#include -#include -#include -#include -#include -#include + +/// \mainpage +/// ChaiScript is a scripting language designed specifically for integration with C++. It provides +/// seamless integration with C++ on all levels, including shared_ptr objects, functors and exceptions. +/// +/// The parts of the ChaiScript API that the average user will be concerned with are contained in the +/// chaiscript namespace and the chaiscript::ChaiScript class. +/// +/// The end user parts of the API are extremely simple both in size and ease of use. +/// +/// Currently, all source control and project management aspects of ChaiScript occur on github. +/// +/// \sa chaiscript +/// \sa chaiscript::ChaiScript +/// \sa http://www.chaiscript.com +/// \sa http://www.github.com/ChaiScript/ChaiScript + + +/// \namespace chaiscript +/// The chaiscript namespace contains every API call that the average user will be concerned with. + #include "dispatchkit/dispatchkit.hpp" #include "dispatchkit/bootstrap.hpp" diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index ff3689f..bfc7d6c 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -13,6 +13,14 @@ #pragma message ("ChaiScript is compiling without thread safety.") #endif +/// \file +/// +/// This file contains code necessary for thread support in ChaiScript. +/// If the compiler definition CHAISCRIPT_NO_THREADS is defined then thread safety +/// is disabled in ChaiScript. This has the result that some code is faster, because mutex locks are not required. +/// It also has the side effect that the chaiscript::ChaiScript object may not be accessed from more than +/// one thread simultaneously. + namespace chaiscript { namespace detail @@ -21,6 +29,12 @@ namespace chaiscript { #ifndef CHAISCRIPT_NO_THREADS + using boost::unique_lock; + using boost::shared_lock; + using boost::lock_guard; + using boost::shared_mutex; + using boost::recursive_mutex; + template class Thread_Storage @@ -51,6 +65,32 @@ namespace chaiscript }; #else + template + class unique_lock + { + public: + unique_lock(T &) {} + }; + + template + class shared_lock + { + public: + shared_lock(T &) {} + void unlock() {} + }; + + template + class lock_guard + { + public: + lock_guard(T &) {} + }; + + class shared_mutex { }; + + class recursive_mutex {}; + template class Thread_Storage diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index 5aed07f..96710c0 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -5,10 +5,13 @@ // http://www.chaiscript.com /** -* This file contains utility functions for registration of STL container -* classes. The methodology used is based on the SGI STL concepts. -* http://www.sgi.com/tech/stl/table_of_contents.html -*/ + * \file + * This file contains utility functions for registration of STL container + * classes. The methodology used is based on the SGI STL concepts. + * http://www.sgi.com/tech/stl/table_of_contents.html + */ + + #ifndef CHAISCRIPT_BOOTSTRAP_STL_HPP_ #define CHAISCRIPT_BOOTSTRAP_STL_HPP_ diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 591238a..94d22f0 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -395,9 +395,7 @@ namespace chaiscript throw exception::global_non_const(); } -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_global_object_mutex); -#endif + chaiscript::detail::threading::unique_lock l(m_global_object_mutex); m_state.m_global_objects[name] = obj; } @@ -476,9 +474,7 @@ namespace chaiscript // Is the value we are looking for a global? { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_global_object_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_global_object_mutex); std::map::const_iterator itr = m_state.m_global_objects.find(name); if (itr != m_state.m_global_objects.end()) @@ -512,9 +508,7 @@ namespace chaiscript { add_global_const(const_var(ti), name + "_type"); -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); -#endif + chaiscript::detail::threading::unique_lock l(m_mutex); m_state.m_types.insert(std::make_pair(name, ti)); } @@ -524,9 +518,7 @@ namespace chaiscript */ Type_Info get_type(const std::string &name) const { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_mutex); Type_Name_Map::const_iterator itr = m_state.m_types.find(name); @@ -545,9 +537,7 @@ namespace chaiscript */ std::string get_type_name(const Type_Info &ti) const { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_mutex); for (Type_Name_Map::const_iterator itr = m_state.m_types.begin(); itr != m_state.m_types.end(); @@ -567,9 +557,7 @@ namespace chaiscript */ std::vector > get_types() const { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_mutex); return std::vector >(m_state.m_types.begin(), m_state.m_types.end()); } @@ -580,9 +568,7 @@ namespace chaiscript std::vector< Proxy_Function > get_function(const std::string &t_name) const { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_mutex); const std::map > &funs = get_functions_int(); @@ -603,9 +589,7 @@ namespace chaiscript */ bool function_exists(const std::string &name) const { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_mutex); const std::map > &functions = get_functions_int(); return functions.find(name) != functions.end(); @@ -616,9 +600,8 @@ namespace chaiscript */ std::vector > get_functions() const { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_mutex); + std::vector > rets; const std::map > &functions = get_functions_int(); @@ -640,9 +623,7 @@ namespace chaiscript void add_reserved_word(const std::string &name) { -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); -#endif + chaiscript::detail::threading::unique_lock l(m_mutex); m_state.m_reserved_words.insert(name); } @@ -779,20 +760,16 @@ namespace chaiscript State get_state() { -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); - boost::unique_lock l2(m_global_object_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_mutex); + chaiscript::detail::threading::shared_lock l2(m_global_object_mutex); return m_state; } void set_state(const State &t_state) { -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); - boost::unique_lock l2(m_global_object_mutex); -#endif + chaiscript::detail::threading::unique_lock l(m_mutex); + chaiscript::detail::threading::unique_lock l2(m_global_object_mutex); m_state = t_state; } @@ -918,9 +895,7 @@ namespace chaiscript */ void validate_object_name(const std::string &name) const { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_mutex); if (m_state.m_reserved_words.find(name) != m_state.m_reserved_words.end()) { @@ -935,9 +910,7 @@ namespace chaiscript */ bool add_function(const Proxy_Function &t_f, const std::string &t_name) { -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); -#endif + chaiscript::detail::threading::unique_lock l(m_mutex); std::map > &funcs = get_functions_int(); @@ -968,10 +941,8 @@ namespace chaiscript return true; } -#ifndef CHAISCRIPT_NO_THREADS - mutable boost::shared_mutex m_mutex; - mutable boost::shared_mutex m_global_object_mutex; -#endif + mutable chaiscript::detail::threading::shared_mutex m_mutex; + mutable chaiscript::detail::threading::shared_mutex m_global_object_mutex; struct Stack_Holder { diff --git a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp index 15ef49e..30f7d89 100644 --- a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp +++ b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp @@ -15,10 +15,6 @@ #include #include -#ifndef CHAISCRIPT_NO_THREADS -#include -#endif - namespace chaiscript { namespace exception @@ -156,9 +152,7 @@ namespace chaiscript template void cleanup(InItr begin, const InItr &end) { -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); -#endif + chaiscript::detail::threading::unique_lock l(m_mutex); while (begin != end) { @@ -173,28 +167,22 @@ namespace chaiscript void add_conversion(const boost::shared_ptr &conversion) { -#ifndef CHAISCRIPT_NO_THREADS - boost::unique_lock l(m_mutex); -#endif + chaiscript::detail::threading::unique_lock l(m_mutex); m_conversions.insert(conversion.get()); } - bool has_conversion(const Type_Info &base, const Type_Info &derived) + bool has_conversion(const Type_Info &base, const Type_Info &derived) const { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_mutex); return find(base, derived) != m_conversions.end(); } - Dynamic_Conversion *get_conversion(const Type_Info &base, const Type_Info &derived) + Dynamic_Conversion *get_conversion(const Type_Info &base, const Type_Info &derived) const { -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_lock l(m_mutex); -#endif + chaiscript::detail::threading::shared_lock l(m_mutex); std::set::const_iterator itr = find(base, derived); @@ -211,7 +199,7 @@ namespace chaiscript Dynamic_Conversions() {} std::set::const_iterator find( - const Type_Info &base, const Type_Info &derived) + const Type_Info &base, const Type_Info &derived) const { for (std::set::const_iterator itr = m_conversions.begin(); itr != m_conversions.end(); @@ -225,9 +213,8 @@ namespace chaiscript return m_conversions.end(); } -#ifndef CHAISCRIPT_NO_THREADS - boost::shared_mutex m_mutex; -#endif + + mutable chaiscript::detail::threading::shared_mutex m_mutex; std::set m_conversions; }; } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index b495048..093df7b 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -223,10 +223,9 @@ namespace chaiscript } class ChaiScript { -#ifndef CHAISCRIPT_NO_THREADS - mutable boost::shared_mutex m_mutex; - mutable boost::recursive_mutex m_use_mutex; -#endif + + mutable chaiscript::detail::threading::shared_mutex m_mutex; + mutable chaiscript::detail::threading::recursive_mutex m_use_mutex; std::set m_used_files; std::map m_loaded_modules; @@ -280,17 +279,13 @@ namespace chaiscript try { const std::string appendedpath = m_usepaths[i] + t_filename; -#ifndef CHAISCRIPT_NO_THREADS - boost::lock_guard l(m_use_mutex); - boost::shared_lock l2(m_mutex); -#endif + chaiscript::detail::threading::lock_guard l(m_use_mutex); + chaiscript::detail::threading::shared_lock l2(m_mutex); if (m_used_files.count(appendedpath) == 0) { -#ifndef CHAISCRIPT_NO_THREADS m_used_files.insert(appendedpath); l2.unlock(); -#endif eval_file(appendedpath); } } catch (const exception::file_not_found_error &) { @@ -403,10 +398,8 @@ namespace chaiscript */ State get_state() { -#ifndef CHAISCRIPT_NO_THREADS - boost::lock_guard l(m_use_mutex); - boost::shared_lock l2(m_mutex); -#endif + chaiscript::detail::threading::lock_guard l(m_use_mutex); + chaiscript::detail::threading::shared_lock l2(m_mutex); State s; s.used_files = m_used_files; @@ -420,10 +413,8 @@ namespace chaiscript */ void set_state(const State &t_state) { -#ifndef CHAISCRIPT_NO_THREADS - boost::lock_guard l(m_use_mutex); - boost::shared_lock l2(m_mutex); -#endif + chaiscript::detail::threading::lock_guard l(m_use_mutex); + chaiscript::detail::threading::shared_lock l2(m_mutex); m_used_files = t_state.used_files; m_active_loaded_modules = t_state.active_loaded_modules; @@ -505,9 +496,7 @@ namespace chaiscript */ void load_module(const std::string &t_module_name, const std::string &t_filename) { -#ifndef CHAISCRIPT_NO_THREADS - boost::lock_guard l(m_use_mutex); -#endif + chaiscript::detail::threading::lock_guard l(m_use_mutex); if (m_loaded_modules.count(t_module_name) == 0) {