Skip to content

Commit 12ba431

Browse files
committed
fix: fix deadlock in some cases caused by loadEngineSnapshot()
1 parent 6287c10 commit 12ba431

5 files changed

Lines changed: 27 additions & 26 deletions

File tree

src/legacy/api/EventAPI.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -908,14 +908,12 @@ void InitBasicEventListeners() {
908908
}
909909
#ifndef LSE_BACKEND_NODEJS
910910
try {
911-
auto snapshot = globalShareData->globalEngineSnapshot.load(std::memory_order_acquire);
912-
if (snapshot) {
913-
for (auto& engine : *snapshot) {
914-
if (EngineManager::isValid(engine.get())
915-
&& EngineManager::getEngineType(engine) == LLSE_BACKEND_TYPE) {
916-
EngineScope enter(engine.get());
917-
engine->messageQueue()->loopQueue(script::utils::MessageQueue::LoopType::kLoopOnce);
918-
}
911+
auto snapshot = EngineManager::getGlobalEngines();
912+
for (auto& engine : snapshot) {
913+
if (EngineManager::isValid(engine.get())
914+
&& EngineManager::getEngineType(engine) == LLSE_BACKEND_TYPE) {
915+
EngineScope enter(engine.get());
916+
engine->messageQueue()->loopQueue(script::utils::MessageQueue::LoopType::kLoopOnce);
919917
}
920918
}
921919
} catch (...) {

src/legacy/engine/EngineManager.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#include "legacy/main/NodeJsHelper.h"
88
#endif
99

10-
#include <atomic>
1110
#include <mutex>
11+
#include <shared_mutex>
1212

1313
using namespace script;
1414

@@ -19,19 +19,22 @@ void refreshEngineSnapshotLocked() {
1919
globalShareData->globalEngineList.begin(),
2020
globalShareData->globalEngineList.end()
2121
);
22-
globalShareData->globalEngineSnapshot.store(snapshot, std::memory_order_release);
22+
23+
std::unique_lock snapshotLock(globalShareData->engineSnapshotLock);
24+
globalShareData->globalEngineSnapshot = std::move(snapshot);
2325
}
2426

2527
std::shared_ptr<std::vector<std::shared_ptr<ScriptEngine>>> loadEngineSnapshot() {
26-
return globalShareData->globalEngineSnapshot.load(std::memory_order_acquire);
28+
std::shared_lock snapshotLock(globalShareData->engineSnapshotLock);
29+
return globalShareData->globalEngineSnapshot;
2730
}
2831

2932
} // namespace
3033

3134
///////////////////////////////// API /////////////////////////////////
3235

3336
bool EngineManager::unregisterEngine(std::shared_ptr<ScriptEngine> const& toDelete) {
34-
std::unique_lock lock(globalShareData->engineListLock);
37+
std::lock_guard lock(globalShareData->engineListLock);
3538
for (auto engine = globalShareData->globalEngineList.begin(); engine != globalShareData->globalEngineList.end();
3639
++engine) {
3740
if (*engine == toDelete) {
@@ -44,7 +47,7 @@ bool EngineManager::unregisterEngine(std::shared_ptr<ScriptEngine> const& toDele
4447
}
4548

4649
bool EngineManager::registerEngine(std::shared_ptr<ScriptEngine> const& engine) {
47-
std::unique_lock lock(globalShareData->engineListLock);
50+
std::lock_guard lock(globalShareData->engineListLock);
4851
globalShareData->globalEngineList.push_back(engine);
4952
refreshEngineSnapshotLocked();
5053
return true;

src/legacy/engine/GlobalShareData.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "legacy/engine/LocalShareData.h"
55

66
#include <Windows.h>
7-
#include <atomic>
7+
#include <mutex>
88
#include <string>
99
#include <vector>
1010

@@ -43,11 +43,11 @@ void InitGlobalShareData() {
4343
globalShareData = static_cast<GlobalDataType*>(address);
4444
}
4545

46-
globalShareData->globalEngineSnapshot.store(
47-
std::make_shared<std::vector<std::shared_ptr<ScriptEngine>>>(
46+
{
47+
std::unique_lock snapshotLock(globalShareData->engineSnapshotLock);
48+
globalShareData->globalEngineSnapshot = std::make_shared<std::vector<std::shared_ptr<ScriptEngine>>>(
4849
globalShareData->globalEngineList.begin(),
4950
globalShareData->globalEngineList.end()
50-
),
51-
std::memory_order_release
52-
);
51+
);
52+
}
5353
}

src/legacy/engine/GlobalShareData.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
#include "legacy/api/APIHelp.h"
33

44
#include <Windows.h>
5-
#include <atomic>
65
#include <map>
6+
#include <memory>
7+
#include <mutex>
78
#include <shared_mutex>
89
#include <string>
910
#include <vector>
@@ -27,9 +28,10 @@ struct MessageHandlers {
2728
// 全局共享数据
2829
struct GlobalDataType {
2930
// 引擎管理器表
30-
std::shared_mutex engineListLock;
31+
std::mutex engineListLock;
3132
std::vector<std::shared_ptr<ScriptEngine>> globalEngineList;
32-
std::atomic<std::shared_ptr<std::vector<std::shared_ptr<ScriptEngine>>>> globalEngineSnapshot;
33+
std::shared_mutex engineSnapshotLock;
34+
std::shared_ptr<std::vector<std::shared_ptr<ScriptEngine>>> globalEngineSnapshot;
3335

3436
// 导出函数表
3537
std::unordered_map<std::string, ExportedFuncData> exportedFuncs;

src/legacy/engine/MessageSystem.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,8 @@ bool ModuleMessageResult::cancel() const {
322322
void MessageSystemLoopOnce() {
323323
// if (!messageLoopLock.try_lock())
324324
// return;
325-
auto snapshot = globalShareData->globalEngineSnapshot.load(std::memory_order_acquire);
326-
if (!snapshot) return;
327-
328-
for (auto& engine : *snapshot) {
325+
auto snapshot = EngineManager::getGlobalEngines();
326+
for (auto& engine : snapshot) {
329327
if (EngineManager::isValid(engine) && EngineManager::getEngineType(engine) == LLSE_BACKEND_TYPE) {
330328
try {
331329
if (EngineScope::currentEngine() == engine.get())

0 commit comments

Comments
 (0)