Only share const globals between threads. Require all globals to be const.

This commit is contained in:
Jason Turner 2009-11-11 05:47:54 +00:00
parent 07352a16a3
commit cca477dae6
4 changed files with 41 additions and 13 deletions

View File

@ -310,6 +310,11 @@ namespace chaiscript
return m_data->m_type_info.is_undef(); return m_data->m_type_info.is_undef();
} }
bool is_const() const
{
return m_data->m_type_info.is_const();
}
bool is_null() const bool is_null() const
{ {
if (m_data->m_is_null) if (m_data->m_is_null)

View File

@ -166,6 +166,19 @@ namespace chaiscript
virtual ~reserved_word_error() throw() {} virtual ~reserved_word_error() throw() {}
}; };
/**
* Exception thrown in the case that a non-const object was added as a shared object
*/
struct global_non_const : std::runtime_error
{
global_non_const() throw()
: std::runtime_error("a global object must be const")
{
}
virtual ~global_non_const() throw() {}
};
/** /**
* Main class for the dispatchkit. Handles management * Main class for the dispatchkit. Handles management
@ -238,19 +251,24 @@ namespace chaiscript
} }
/** /**
* Adds a new shared object, between all the threads * Adds a new global shared object, between all the threads
*/ */
void add_shared_object(const Boxed_Value &obj, const std::string &name) void add_global_const(const Boxed_Value &obj, const std::string &name)
{ {
StackData &stack = get_stack_data(); StackData &stack = get_stack_data();
validate_object_name(name); validate_object_name(name);
if (!obj.is_const())
{
throw global_non_const();
}
stack.get<0>().erase(name); stack.get<0>().erase(name);
#ifndef CHAISCRIPT_NO_THREADS #ifndef CHAISCRIPT_NO_THREADS
boost::unique_lock<boost::shared_mutex> l(m_shared_object_mutex); boost::unique_lock<boost::shared_mutex> l(m_global_object_mutex);
#endif #endif
m_shared_objects[name] = obj; m_global_objects[name] = obj;
} }
/** /**
@ -353,15 +371,14 @@ namespace chaiscript
} }
} }
// Are we in the 0th stack and should check the shared objects? // Is the value we are looking for a global?
if (stack.get<2>())
{ {
#ifndef CHAISCRIPT_NO_THREADS #ifndef CHAISCRIPT_NO_THREADS
boost::shared_lock<boost::shared_mutex> l(m_shared_object_mutex); boost::shared_lock<boost::shared_mutex> l(m_global_object_mutex);
#endif #endif
itr = m_shared_objects.find(name); itr = m_global_objects.find(name);
if (itr != m_shared_objects.end()) if (itr != m_global_objects.end())
{ {
cache[name] = itr->second; cache[name] = itr->second;
return itr->second; return itr->second;
@ -662,7 +679,7 @@ namespace chaiscript
#ifndef CHAISCRIPT_NO_THREADS #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_global_object_mutex;
#endif #endif
struct Stack_Holder struct Stack_Holder
@ -682,7 +699,7 @@ namespace chaiscript
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_global_objects;
Type_Name_Map m_types; Type_Name_Map m_types;
Boxed_Value m_place_holder; Boxed_Value m_place_holder;

View File

@ -333,9 +333,9 @@ namespace chaiscript
/** /**
* Adds a shared object, that can be used by all threads, to the system * Adds a shared object, that can be used by all threads, to the system
*/ */
ChaiScript_System &add_shared_object(const Boxed_Value &bv, const std::string &name) ChaiScript_System &add_global_const(const Boxed_Value &bv, const std::string &name)
{ {
engine.add_shared_object(bv, name); engine.add_global_const(bv, name);
return *this; return *this;
} }

View File

@ -146,6 +146,12 @@ int main(int argc, char *argv[]) {
chai.add(var(boost::shared_ptr<int>()), "nullvar"); chai.add(var(boost::shared_ptr<int>()), "nullvar");
chai("print(\"This should be true.\"); print(nullvar.is_null())"); chai("print(\"This should be true.\"); print(nullvar.is_null())");
// test the global const action
chai.add_global_const(const_var(1), "constvar");
chai("def getvar() { return constvar; }");
chai("print( getvar() )");
//Ability to create our own container types when needed. std::vector and std::map are //Ability to create our own container types when needed. std::vector and std::map are
//mostly supported currently //mostly supported currently
chai.add(bootstrap::vector_type<std::vector<int> >("IntVector")); chai.add(bootstrap::vector_type<std::vector<int> >("IntVector"));