Ticket #3708: JS_ShutDown_SVN_1.0.diff
File JS_ShutDown_SVN_1.0.diff, 7.6 KB (added by , 8 years ago) |
---|
-
source/main.cpp
73 73 #include "graphics/TextureManager.h" 74 74 #include "gui/GUIManager.h" 75 75 #include "renderer/Renderer.h" 76 #include "scriptinterface/ScriptEngine.h" 76 77 #include "simulation2/Simulation2.h" 77 78 78 79 #if OS_UNIX … … 422 423 return; 423 424 } 424 425 425 // We need to initialise libxml2 in the main thread before 426 // any thread uses it. So initialise it here before we 427 // might run Atlas. 426 // We need to initialize libxml2 and SpiderMonkey in the main thread before 427 // any thread uses them. So initialize them here before we might run Atlas. 428 428 CXeromyces::Startup(); 429 ScriptEngine scriptEngine; 429 430 430 431 // Atlas handles the whole init/shutdown/etc sequence by itself; 431 432 if (ATLAS_RunIfOnCmdLine(args, false)) -
source/scriptinterface/ScriptEngine.h
1 /* Copyright (C) 2016 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef INCLUDED_SCRIPTENGINE 19 #define INCLUDED_SCRIPTENGINE 20 21 #include "ScriptTypes.h" 22 #include "ps/Singleton.h" 23 24 /** 25 * A class using the RAII (Resource Acquisition Is Initialization) idiom to manage initialization 26 * and shutdown of the SpiderMonkey script engine. It also keeps a count of active script runtimes 27 * in order to validate the following constraints: 28 * 1. JS_Init must be called before any ScriptRuntimes are initialized 29 * 2. JS_Shutdown must be called after all ScriptRuntimes have been destroyed 30 */ 31 32 class ScriptEngine : public Singleton<ScriptEngine> 33 { 34 public: 35 ScriptEngine() 36 { 37 ENSURE(m_Runtimes.size() == 0 && "JS_Init must be called before any runtimes are created!"); 38 JS_Init(); 39 } 40 41 ~ScriptEngine() 42 { 43 ENSURE(m_Runtimes.size() == 0 && "All runtimes must be destroyed before calling JS_ShutDown!"); 44 JS_ShutDown(); 45 } 46 47 void RegisterRuntime(const JSRuntime* rt) { m_Runtimes.push_back(rt); } 48 void UnRegisterRuntime(const JSRuntime* rt) { m_Runtimes.remove(rt); } 49 50 private: 51 52 std::list<const JSRuntime*> m_Runtimes; 53 }; 54 55 #endif // INCLUDED_SCRIPTENGINE -
source/scriptinterface/ScriptInterface.cpp
433 433 } 434 434 } 435 435 436 void ScriptInterface::ShutDown()437 {438 JS_ShutDown();439 }440 441 436 void ScriptInterface::SetCallbackData(void* pCBData) 442 437 { 443 438 m_CxPrivate.pCBData = pCBData; -
source/scriptinterface/ScriptInterface.h
97 97 98 98 ~ScriptInterface(); 99 99 100 /**101 * Shut down the JS system to clean up memory. Must only be called when there102 * are no ScriptInterfaces alive.103 */104 static void ShutDown();105 106 100 struct CxPrivate 107 101 { 108 102 ScriptInterface* pScriptInterface; // the ScriptInterface object the current context belongs to -
source/scriptinterface/ScriptRuntime.cpp
21 21 22 22 #include "ps/GameSetup/Config.h" 23 23 #include "ps/Profile.h" 24 #include "scriptinterface/ScriptEngine.h" 24 25 25 26 26 27 void GCSliceCallbackHook(JSRuntime* UNUSED(rt), JS::GCProgress progress, const JS::GCDescription& UNUSED(desc)) … … 104 105 m_FinalizationListObjectIdCache.push_back(obj); 105 106 } 106 107 107 bool ScriptRuntime::m_Initialized = false;108 109 108 ScriptRuntime::ScriptRuntime(shared_ptr<ScriptRuntime> parentRuntime, int runtimeSize, int heapGrowthBytesGCTrigger): 110 109 m_LastGCBytes(0), 111 110 m_LastGCCheck(0.0f), … … 112 111 m_HeapGrowthBytesGCTrigger(heapGrowthBytesGCTrigger), 113 112 m_RuntimeSize(runtimeSize) 114 113 { 115 if (!m_Initialized) 116 { 117 ENSURE(JS_Init()); 118 m_Initialized = true; 119 } 114 ENSURE(ScriptEngine::IsInitialised() && "The ScriptEngine must be initialized before constructing any ScriptRuntimes!"); 120 115 121 116 JSRuntime* parentJSRuntime = parentRuntime ? parentRuntime->m_rt : nullptr; 122 117 m_rt = JS_NewRuntime(runtimeSize, JS_USE_HELPER_THREADS, parentJSRuntime); … … 135 130 136 131 m_dummyContext = JS_NewContext(m_rt, STACK_CHUNK_SIZE); 137 132 ENSURE(m_dummyContext); 133 134 ScriptEngine::GetSingleton().RegisterRuntime(m_rt); 138 135 } 139 136 140 137 ScriptRuntime::~ScriptRuntime() … … 143 140 JS_SetGCCallback(m_rt, nullptr, nullptr); 144 141 JS_DestroyRuntime(m_rt); 145 142 ENSURE(m_FinalizationListObjectIdCache.empty() && "Leak: Removing callback while some objects still aren't finalized!"); 143 144 ENSURE(ScriptEngine::IsInitialised() && "The ScriptEngine must be active (initiaized and not yet shut down) when destroying a ScriptRuntime!"); 145 ScriptEngine::GetSingleton().UnRegisterRuntime(m_rt); 146 146 } 147 147 148 148 void ScriptRuntime::RegisterContext(JSContext* cx) -
source/scriptinterface/ScriptRuntime.h
79 79 80 80 std::list<JSContext*> m_Contexts; 81 81 std::vector<std::shared_ptr<void> > m_FinalizationListObjectIdCache; 82 static bool m_Initialized;83 82 84 83 int m_RuntimeSize; 85 84 int m_HeapGrowthBytesGCTrigger; -
source/test_setup.cpp
1 /* Copyright (C) 201 4Wildfire Games.1 /* Copyright (C) 2016 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 36 36 #include "lib/timer.h" 37 37 #include "lib/sysdep/sysdep.h" 38 38 #include "ps/Profiler2.h" 39 #include "scriptinterface/ScriptEngine.h" 39 40 #include "scriptinterface/ScriptInterface.h" 40 41 41 42 class LeakReporter : public CxxTest::GlobalFixture … … 42 43 { 43 44 virtual bool tearDownWorld() 44 45 { 45 // Shut down JS to prevent leak reports from it46 ScriptInterface::ShutDown();47 48 46 // Enable leak reporting on exit. 49 47 // (This is done in tearDownWorld so that it doesn't report 'leaks' 50 48 // if the program is aborted before finishing cleanly.) … … 81 79 ThreadUtil::SetMainThread(); 82 80 83 81 g_Profiler2.Initialise(); 82 m_ScriptEngine = new ScriptEngine; 84 83 g_ScriptRuntime = ScriptInterface::CreateRuntime(); 85 84 86 85 return true; … … 89 88 virtual bool tearDownWorld() 90 89 { 91 90 g_ScriptRuntime.reset(); 91 delete m_ScriptEngine; 92 92 g_Profiler2.Shutdown(); 93 93 94 94 return true; 95 95 } 96 97 private: 98 99 // We're doing the initialization and shutdown of the ScriptEngine explicitly here 100 // to make sure it's only initialized when setUpWorld is called. 101 ScriptEngine* m_ScriptEngine; 96 102 }; 97 103 98 104 static LeakReporter leakReporter;