Made thread saftey a compilation option for performance and dependencies reasons
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
#define __boxed_value_hpp__
|
#define __boxed_value_hpp__
|
||||||
|
|
||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
|
#include "../chaiscript_threading.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/any.hpp>
|
#include <boost/any.hpp>
|
||||||
@@ -280,11 +281,7 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
Object_Cache &get_object_cache()
|
Object_Cache &get_object_cache()
|
||||||
{
|
{
|
||||||
static boost::thread_specific_ptr<Object_Cache> oc;
|
static chaiscript::threading::Thread_Storage<Object_Cache> oc;
|
||||||
if (!oc.get())
|
|
||||||
{
|
|
||||||
oc.reset(new Object_Cache);
|
|
||||||
}
|
|
||||||
return *oc;
|
return *oc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,12 +18,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <boost/thread.hpp>
|
|
||||||
|
|
||||||
#include "boxed_value.hpp"
|
#include "boxed_value.hpp"
|
||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
#include "proxy_functions.hpp"
|
#include "proxy_functions.hpp"
|
||||||
#include "proxy_constructors.hpp"
|
#include "proxy_constructors.hpp"
|
||||||
|
#include "../chaiscript_threading.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@@ -230,7 +230,10 @@ namespace chaiscript
|
|||||||
validate_object_name(name);
|
validate_object_name(name);
|
||||||
stack.get<0>().erase(name);
|
stack.get<0>().erase(name);
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::unique_lock<boost::shared_mutex> l(m_shared_object_mutex);
|
boost::unique_lock<boost::shared_mutex> l(m_shared_object_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
m_shared_objects[name] = obj;
|
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
|
* Swaps out the stack with a new stack
|
||||||
* \returns the old stack
|
* \returns the old stack
|
||||||
@@ -280,10 +274,8 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
Stack set_stack(const Stack &s)
|
Stack set_stack(const Stack &s)
|
||||||
{
|
{
|
||||||
setup_stack();
|
Stack old = m_stack_holder->stack;
|
||||||
|
m_stack_holder->stack = s;
|
||||||
Stack old = m_thread_stack->stack;
|
|
||||||
m_thread_stack->stack = s;
|
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,10 +287,19 @@ namespace chaiscript
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stack get_stack() const
|
||||||
|
{
|
||||||
|
return m_stack_holder->stack;
|
||||||
|
}
|
||||||
|
|
||||||
void sync_cache()
|
void sync_cache()
|
||||||
{
|
{
|
||||||
get_stack()->get<0>().clear();
|
m_stack_holder->stack->get<0>().clear();
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
get_function_cache() = m_functions;
|
get_function_cache() = m_functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,7 +340,10 @@ namespace chaiscript
|
|||||||
// Are we in the 0th stack and should check the shared objects?
|
// Are we in the 0th stack and should check the shared objects?
|
||||||
if (stack.get<2>())
|
if (stack.get<2>())
|
||||||
{
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::shared_lock<boost::shared_mutex> l(m_shared_object_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_shared_object_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
itr = m_shared_objects.find(name);
|
itr = m_shared_objects.find(name);
|
||||||
if (itr != m_shared_objects.end())
|
if (itr != m_shared_objects.end())
|
||||||
{
|
{
|
||||||
@@ -366,7 +370,10 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
void add(const Type_Info &ti, const std::string &name)
|
void add(const Type_Info &ti, const std::string &name)
|
||||||
{
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
m_types.insert(std::make_pair(name, ti));
|
m_types.insert(std::make_pair(name, ti));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,7 +382,10 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
Type_Info get_type(const std::string &name) const
|
Type_Info get_type(const std::string &name) const
|
||||||
{
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
Type_Name_Map::const_iterator itr = m_types.find(name);
|
Type_Name_Map::const_iterator itr = m_types.find(name);
|
||||||
|
|
||||||
if (itr != m_types.end())
|
if (itr != m_types.end())
|
||||||
@@ -393,7 +403,10 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
std::string get_type_name(const Type_Info &ti) const
|
std::string get_type_name(const Type_Info &ti) const
|
||||||
{
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (Type_Name_Map::const_iterator itr = m_types.begin();
|
for (Type_Name_Map::const_iterator itr = m_types.begin();
|
||||||
itr != m_types.end();
|
itr != m_types.end();
|
||||||
++itr)
|
++itr)
|
||||||
@@ -412,7 +425,10 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
std::vector<std::pair<std::string, Type_Info> > get_types() const
|
std::vector<std::pair<std::string, Type_Info> > get_types() const
|
||||||
{
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
return std::vector<std::pair<std::string, Type_Info> >(m_types.begin(), m_types.end());
|
return std::vector<std::pair<std::string, Type_Info> >(m_types.begin(), m_types.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,7 +464,10 @@ namespace chaiscript
|
|||||||
|
|
||||||
void add_reserved_word(const std::string &name)
|
void add_reserved_word(const std::string &name)
|
||||||
{
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
m_reserved_words.insert(name);
|
m_reserved_words.insert(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,34 +483,27 @@ namespace chaiscript
|
|||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Returns the current stack
|
* Returns the current stack
|
||||||
|
* make const/non const versions
|
||||||
*/
|
*/
|
||||||
StackData &get_stack_data() const
|
StackData &get_stack_data() const
|
||||||
{
|
{
|
||||||
setup_stack();
|
return *(m_stack_holder->stack);
|
||||||
return *(m_thread_stack->stack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::multimap<std::string, Proxy_Function> &get_function_cache() const
|
std::multimap<std::string, Proxy_Function> &get_function_cache() const
|
||||||
{
|
{
|
||||||
setup_stack();
|
return m_stack_holder->function_cache;
|
||||||
return m_thread_stack->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
|
* Throw a reserved_word exception if the name is not allowed
|
||||||
*/
|
*/
|
||||||
void validate_object_name(const std::string &name) const
|
void validate_object_name(const std::string &name) const
|
||||||
{
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_reserved_words.find(name) != m_reserved_words.end())
|
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)
|
bool add_function(const Proxy_Function &f, const std::string &t_name)
|
||||||
{
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::pair<std::multimap<std::string, Proxy_Function >::const_iterator, std::multimap<std::string, Proxy_Function >::const_iterator> range
|
std::pair<std::multimap<std::string, Proxy_Function >::const_iterator, std::multimap<std::string, Proxy_Function >::const_iterator> range
|
||||||
= m_functions.equal_range(t_name);
|
= m_functions.equal_range(t_name);
|
||||||
@@ -526,14 +540,17 @@ namespace chaiscript
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
mutable boost::shared_mutex m_mutex;
|
mutable boost::shared_mutex m_mutex;
|
||||||
mutable boost::shared_mutex m_shared_object_mutex;
|
mutable boost::shared_mutex m_shared_object_mutex;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct Stack_Holder
|
struct Stack_Holder
|
||||||
{
|
{
|
||||||
Stack_Holder(Stack s)
|
Stack_Holder()
|
||||||
: stack(s)
|
: stack(new StackData())
|
||||||
{
|
{
|
||||||
|
stack->get<2>() = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack stack;
|
Stack stack;
|
||||||
@@ -541,7 +558,8 @@ namespace chaiscript
|
|||||||
std::multimap<std::string, Proxy_Function> function_cache;
|
std::multimap<std::string, Proxy_Function> function_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable boost::thread_specific_ptr<Stack_Holder> m_thread_stack;
|
chaiscript::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
||||||
|
|
||||||
|
|
||||||
std::multimap<std::string, Proxy_Function> m_functions;
|
std::multimap<std::string, Proxy_Function> m_functions;
|
||||||
std::map<std::string, Boxed_Value> m_shared_objects;
|
std::map<std::string, Boxed_Value> m_shared_objects;
|
||||||
|
@@ -21,8 +21,11 @@ namespace chaiscript
|
|||||||
Eval_Engine engine;
|
Eval_Engine engine;
|
||||||
|
|
||||||
std::set<std::string> loaded_files;
|
std::set<std::string> loaded_files;
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
mutable boost::shared_mutex mutex;
|
mutable boost::shared_mutex mutex;
|
||||||
mutable boost::recursive_mutex use_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
|
// to the parser. This is so that the parser does not have the overhead of passing
|
||||||
// around and copying strings
|
// around and copying strings
|
||||||
//
|
//
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::unique_lock<boost::shared_mutex> l(mutex);
|
boost::unique_lock<boost::shared_mutex> l(mutex);
|
||||||
|
#endif
|
||||||
loaded_files.insert(filename);
|
loaded_files.insert(filename);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (parser.parse(input, loaded_files.find(filename)->c_str())) {
|
if (parser.parse(input, loaded_files.find(filename)->c_str())) {
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
l.unlock();
|
l.unlock();
|
||||||
|
#endif
|
||||||
//parser.show_match_stack();
|
//parser.show_match_stack();
|
||||||
value = eval_token<Eval_Engine>(engine, parser.ast());
|
value = eval_token<Eval_Engine>(engine, parser.ast());
|
||||||
}
|
}
|
||||||
@@ -68,11 +75,16 @@ namespace chaiscript
|
|||||||
|
|
||||||
void use(const std::string &filename)
|
void use(const std::string &filename)
|
||||||
{
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
boost::lock_guard<boost::recursive_mutex> l(use_mutex);
|
boost::lock_guard<boost::recursive_mutex> l(use_mutex);
|
||||||
boost::shared_lock<boost::shared_mutex> l2(mutex);
|
boost::shared_lock<boost::shared_mutex> l2(mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (loaded_files.count(filename) == 0)
|
if (loaded_files.count(filename) == 0)
|
||||||
{
|
{
|
||||||
|
#ifndef CHAISCRIPT_NO_THREADS
|
||||||
l2.unlock();
|
l2.unlock();
|
||||||
|
#endif
|
||||||
eval_file(filename);
|
eval_file(filename);
|
||||||
} else {
|
} else {
|
||||||
engine.sync_cache();
|
engine.sync_cache();
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include <chaiscript/chaiscript.hpp>
|
#include <chaiscript/chaiscript.hpp>
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
void do_work(chaiscript::ChaiScript &c)
|
void do_work(chaiscript::ChaiScript &c)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user