[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