[dss-commits] r8799 - in dss/trunk: core tests
dss-commits at forum.digitalstrom.org
dss-commits at forum.digitalstrom.org
Mon Sep 28 10:47:53 CEST 2009
Author: pstaehlin
Date: 2009-09-28 10:47:53 +0200 (Mon, 28 Sep 2009)
New Revision: 8799
Modified:
dss/trunk/core/jshandler.cpp
dss/trunk/core/jshandler.h
dss/trunk/tests/modeljstests.cpp
Log:
Ensure that only one thread uses a script-context concurrently
Modified: dss/trunk/core/jshandler.cpp
===================================================================
--- dss/trunk/core/jshandler.cpp 2009-09-25 10:44:18 UTC (rev 8798)
+++ dss/trunk/core/jshandler.cpp 2009-09-28 08:47:53 UTC (rev 8799)
@@ -301,6 +301,7 @@
template <>
jsval ScriptContext::evaluate() {
+ AssertLocked(this);
jsval rval;
JSBool ok = JS_ExecuteScript(m_pContext, m_pRootObject, m_pScriptToExecute, &rval);
if(ok) {
@@ -338,6 +339,7 @@
template <>
jsval ScriptContext::evaluateScript(const std::string& _script) {
+ AssertLocked(this);
const char* filename = "temporary_script";
jsval rval;
JSBool ok = JS_EvaluateScript(m_pContext, m_pRootObject, _script.c_str(), _script.size(),
@@ -408,12 +410,14 @@
template<>
void ScriptFunctionParameterList::add(const std::string& _value) {
+ AssertLocked objLock(&m_Context);
JSString* str = JS_NewStringCopyN(m_Context.getJSContext(), _value.c_str(), _value.size());
m_Parameter.push_back(STRING_TO_JSVAL(str));
} // add<const std::string&>
template<>
void ScriptFunctionParameterList::add(std::string _value) {
+ AssertLocked objLock(&m_Context);
JSString* str = JS_NewStringCopyN(m_Context.getJSContext(), _value.c_str(), _value.size());
m_Parameter.push_back(STRING_TO_JSVAL(str));
} // add<std::string&>
@@ -432,6 +436,7 @@
: m_pObject(NULL),
m_Context(_context)
{
+ AssertLocked objLock(&m_Context);
JSObject* parentObj = NULL;
if(_pParent != NULL) {
parentObj = _pParent->m_pObject;
@@ -441,6 +446,7 @@
template<>
jsval ScriptObject::getProperty(const std::string& _name) {
+ AssertLocked objLock(&m_Context);
JSBool found;
if(!JS_HasProperty(m_Context.getJSContext(), m_pObject, _name.c_str(), &found)) {
throw ScriptException("Could not enumerate property");
@@ -524,6 +530,7 @@
template<>
jsval ScriptObject::callFunctionByName(const std::string& _functionName,
ScriptFunctionParameterList& _parameter) {
+ AssertLocked objLock(&m_Context);
int paramc = _parameter.size();
jsval* paramv = (jsval*)malloc(sizeof(jsval) * paramc);
for(int iParam = 0; iParam < paramc; iParam++) {
@@ -573,6 +580,7 @@
template<>
jsval ScriptObject::callFunctionByReference(jsval _function,
ScriptFunctionParameterList& _parameter) {
+ AssertLocked objLock(&m_Context);
int paramc = _parameter.size();
jsval* paramv = (jsval*)malloc(sizeof(jsval) * paramc);
for(int iParam = 0; iParam < paramc; iParam++) {
Modified: dss/trunk/core/jshandler.h
===================================================================
--- dss/trunk/core/jshandler.h 2009-09-25 10:44:18 UTC (rev 8798)
+++ dss/trunk/core/jshandler.h 2009-09-28 08:47:53 UTC (rev 8799)
@@ -26,8 +26,6 @@
#include "config.h"
#endif
-#include "base.h"
-
#ifdef HAVE_MOZJS_JSAPI_H
#include <mozjs/jsapi.h>
#else
@@ -37,6 +35,9 @@
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/scoped_ptr.hpp>
+#include "base.h"
+#include "mutex.h"
+
namespace dss {
class ScriptContext;
@@ -73,7 +74,7 @@
/** ScriptContext is a wrapper for a scripts execution context.
* A script can either be loaded from a file or from
* a std::string contained in memory. */
- class ScriptContext {
+ class ScriptContext : public LockableObject {
private:
JSScript* m_pScriptToExecute;
std::string m_FileName;
Modified: dss/trunk/tests/modeljstests.cpp
===================================================================
--- dss/trunk/tests/modeljstests.cpp 2009-09-25 10:44:18 UTC (rev 8798)
+++ dss/trunk/tests/modeljstests.cpp 2009-09-28 08:47:53 UTC (rev 8799)
@@ -248,8 +248,87 @@
BOOST_CHECK_EQUAL(propSys.getBoolValue("/triggered"), false);
BOOST_CHECK_EQUAL(propSys.getIntValue("/testing"), 2);
+}
+BOOST_AUTO_TEST_CASE(testReentrancy) {
+ PropertySystem propSys;
+ boost::scoped_ptr<ScriptEnvironment> env(new ScriptEnvironment());
+ env->initialize();
+ ScriptExtension* ext = new PropertyScriptExtension(propSys);
+ env->addExtension(ext);
-}
+ boost::scoped_ptr<ScriptContext> ctx(env->getContext());
+ ctx->evaluateScript<void>("setProperty('/testing', 1); setProperty('/triggered', false); "
+ "setListener('/triggered', function() { setProperty('/itWorks', true); } ); "
+ "listener_ident = setListener('/testing', function(changedNode) { setProperty('/triggered', true); }); "
+ );
+
+ propSys.setBoolValue("/testing", true);
+
+ BOOST_CHECK_EQUAL(propSys.getBoolValue("/itWorks"), true);
+} // testReentrancy
+class TestThreadingThread : public Thread {
+public:
+ TestThreadingThread(PropertyNodePtr _node)
+ : Thread("TestThreadingThread"),
+ m_pNode(_node)
+ {
+ }
+
+ virtual void execute() {
+ while(!m_Terminated) {
+ m_pNode->setIntegerValue(2);
+ }
+ }
+
+private:
+ PropertyNodePtr m_pNode;
+}; // TestThreadingThread
+
+BOOST_AUTO_TEST_CASE(testThreading) {
+ PropertySystem propSys;
+ boost::scoped_ptr<ScriptEnvironment> env(new ScriptEnvironment());
+ env->initialize();
+ ScriptExtension* ext = new PropertyScriptExtension(propSys);
+ env->addExtension(ext);
+
+ boost::scoped_ptr<ScriptContext> ctx(env->getContext());
+ ctx->evaluateScript<void>("var func = setProperty('/testing1', 1); setProperty('/testing2', 1); "
+ "setListener('/testing1', function() { setProperty('/itWorks', true); } ); "
+ "setListener('/testing2', function() { setProperty('/itWorks', true); } ); "
+ );
+
+ PropertyNodePtr node1 = propSys.getProperty("/testing1");
+ PropertyNodePtr node2 = propSys.getProperty("/testing2");
+
+ // different nodes
+ {
+ TestThreadingThread t1(node1);
+ TestThreadingThread t2(node2);
+ t1.run();
+ t2.run();
+
+ sleepSeconds(1);
+
+ t1.terminate();
+ t2.terminate();
+ sleepMS(500);
+ }
+
+ // same node
+ {
+ TestThreadingThread t1(node1);
+ TestThreadingThread t2(node1);
+ t1.run();
+ t2.run();
+
+ sleepSeconds(1);
+
+ t1.terminate();
+ t2.terminate();
+ sleepMS(500);
+ }
+} // testThreading
+
BOOST_AUTO_TEST_SUITE_END()
More information about the dss-commits
mailing list