Browse Source

Protect AngelScript module creation/deletion with a mutex as AngelScript itself doesn't do that.

Lasse Öörni 11 years ago
parent
commit
af46a915c2
2 changed files with 26 additions and 12 deletions
  1. 5 0
      Source/Engine/Script/Script.h
  2. 21 12
      Source/Engine/Script/ScriptFile.cpp

+ 5 - 0
Source/Engine/Script/Script.h

@@ -22,6 +22,7 @@
 
 
 #pragma once
 #pragma once
 
 
+#include "Mutex.h"
 #include "Object.h"
 #include "Object.h"
 
 
 class asIObjectType;
 class asIObjectType;
@@ -92,6 +93,8 @@ public:
     void ClearObjectTypeCache();
     void ClearObjectTypeCache();
     /// Query for an inbuilt object type by constant declaration. Can not be used for script types.
     /// Query for an inbuilt object type by constant declaration. Can not be used for script types.
     asIObjectType* GetObjectType(const char* declaration);
     asIObjectType* GetObjectType(const char* declaration);
+    /// Return the script module create/delete mutex.
+    Mutex& GetModuleMutex() { return moduleMutex_; }
 
 
 private:
 private:
     /// Increase script nesting level.
     /// Increase script nesting level.
@@ -119,6 +122,8 @@ private:
     Vector<asIScriptContext*> scriptFileContexts_;
     Vector<asIScriptContext*> scriptFileContexts_;
     /// Search cache for inbuilt object types.
     /// Search cache for inbuilt object types.
     HashMap<const char*, asIObjectType*> objectTypes_;
     HashMap<const char*, asIObjectType*> objectTypes_;
+    /// Script module create/delete mutex.
+    Mutex moduleMutex_;
     /// Current script execution nesting level.
     /// Current script execution nesting level.
     unsigned scriptNestingLevel_;
     unsigned scriptNestingLevel_;
     /// Flag for executing engine console commands as script code. Default to true.
     /// Flag for executing engine console commands as script code. Default to true.

+ 21 - 12
Source/Engine/Script/ScriptFile.cpp

@@ -115,16 +115,20 @@ void ScriptFile::RegisterObject(Context* context)
 bool ScriptFile::BeginLoad(Deserializer& source)
 bool ScriptFile::BeginLoad(Deserializer& source)
 {
 {
     ReleaseModule();
     ReleaseModule();
-    
     loadByteCode_.Reset();
     loadByteCode_.Reset();
-
-    // Create the module. Discard previous module if there was one
+    
     asIScriptEngine* engine = script_->GetScriptEngine();
     asIScriptEngine* engine = script_->GetScriptEngine();
-    scriptModule_ = engine->GetModule(GetName().CString(), asGM_ALWAYS_CREATE);
-    if (!scriptModule_)
+    
     {
     {
-        LOGERROR("Failed to create script module " + GetName());
-        return false;
+        MutexLock lock(script_->GetModuleMutex());
+    
+        // Create the module. Discard previous module if there was one
+        scriptModule_ = engine->GetModule(GetName().CString(), asGM_ALWAYS_CREATE);
+        if (!scriptModule_)
+        {
+            LOGERROR("Failed to create script module " + GetName());
+            return false;
+        }
     }
     }
     
     
     // Check if this file is precompiled bytecode
     // Check if this file is precompiled bytecode
@@ -737,8 +741,6 @@ void ScriptFile::ReleaseModule()
 {
 {
     if (scriptModule_)
     if (scriptModule_)
     {
     {
-        script_->ClearObjectTypeCache();
-        
         // Clear search caches and event handlers
         // Clear search caches and event handlers
         includeFiles_.Clear();
         includeFiles_.Clear();
         validClasses_.Clear();
         validClasses_.Clear();
@@ -747,10 +749,17 @@ void ScriptFile::ReleaseModule()
         delayedCalls_.Clear();
         delayedCalls_.Clear();
         eventInvokers_.Clear();
         eventInvokers_.Clear();
         
         
-        // Remove the module
-        scriptModule_->SetUserData(0);
         asIScriptEngine* engine = script_->GetScriptEngine();
         asIScriptEngine* engine = script_->GetScriptEngine();
-        engine->DiscardModule(GetName().CString());
+        scriptModule_->SetUserData(0);
+        
+        // Remove the module
+        {
+            MutexLock lock(script_->GetModuleMutex());
+            
+            script_->ClearObjectTypeCache();
+            engine->DiscardModule(GetName().CString());
+        }
+        
         scriptModule_ = 0;
         scriptModule_ = 0;
         compiled_ = false;
         compiled_ = false;
         SetMemoryUse(0);
         SetMemoryUse(0);