Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit a49054c

Browse files
authored
fix: deadlock when unload engine (#1769)
* fix: deadlock when unload engine * fix: add lock
1 parent 4d2d236 commit a49054c

File tree

2 files changed

+33
-46
lines changed

2 files changed

+33
-46
lines changed

engine/services/engine_service.cc

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,6 @@ EngineService::GetInstalledEngineVariants(const std::string& engine) const {
656656
}
657657

658658
bool EngineService::IsEngineLoaded(const std::string& engine) {
659-
std::lock_guard<std::mutex> lock(engines_mutex_);
660659
auto ne = NormalizeEngine(engine);
661660
return engines_.find(ne) != engines_.end();
662661
}
@@ -675,7 +674,7 @@ cpp::result<EngineV, std::string> EngineService::GetLoadedEngine(
675674
cpp::result<void, std::string> EngineService::LoadEngine(
676675
const std::string& engine_name) {
677676
auto ne = NormalizeEngine(engine_name);
678-
677+
std::lock_guard<std::mutex> lock(engines_mutex_);
679678
if (IsEngineLoaded(ne)) {
680679
CTL_INF("Engine " << ne << " is already loaded");
681680
return {};
@@ -779,7 +778,7 @@ cpp::result<void, std::string> EngineService::LoadEngine(
779778
should_use_dll_search_path) {
780779

781780
{
782-
std::lock_guard<std::mutex> lock(engines_mutex_);
781+
783782
// Remove llamacpp dll directory
784783
if (!RemoveDllDirectory(engines_[kLlamaRepo].cookie)) {
785784
CTL_WRN("Could not remove dll directory: " << kLlamaRepo);
@@ -801,11 +800,8 @@ cpp::result<void, std::string> EngineService::LoadEngine(
801800
}
802801
}
803802
#endif
804-
{
805-
std::lock_guard<std::mutex> lock(engines_mutex_);
806-
engines_[ne].dl = std::make_unique<cortex_cpp::dylib>(
807-
engine_dir_path.string(), "engine");
808-
}
803+
engines_[ne].dl =
804+
std::make_unique<cortex_cpp::dylib>(engine_dir_path.string(), "engine");
809805
#if defined(__linux__)
810806
const char* name = "LD_LIBRARY_PATH";
811807
auto data = getenv(name);
@@ -826,45 +822,39 @@ cpp::result<void, std::string> EngineService::LoadEngine(
826822

827823
} catch (const cortex_cpp::dylib::load_error& e) {
828824
CTL_ERR("Could not load engine: " << e.what());
829-
{
830-
std::lock_guard<std::mutex> lock(engines_mutex_);
831-
engines_.erase(ne);
832-
}
825+
engines_.erase(ne);
833826
return cpp::fail("Could not load engine " + ne + ": " + e.what());
834827
}
835828

836-
{
837-
std::lock_guard<std::mutex> lock(engines_mutex_);
838-
auto func = engines_[ne].dl->get_function<EngineI*()>("get_engine");
839-
engines_[ne].engine = func();
840-
841-
auto& en = std::get<EngineI*>(engines_[ne].engine);
842-
if (ne == kLlamaRepo) { //fix for llamacpp engine first
843-
auto config = file_manager_utils::GetCortexConfig();
844-
if (en->IsSupported("SetFileLogger")) {
845-
en->SetFileLogger(config.maxLogLines,
846-
(std::filesystem::path(config.logFolderPath) /
847-
std::filesystem::path(config.logLlamaCppPath))
848-
.string());
849-
} else {
850-
CTL_WRN("Method SetFileLogger is not supported yet");
851-
}
852-
if (en->IsSupported("SetLogLevel")) {
853-
en->SetLogLevel(logging_utils_helper::global_log_level);
854-
} else {
855-
CTL_WRN("Method SetLogLevel is not supported yet");
856-
}
829+
auto func = engines_[ne].dl->get_function<EngineI*()>("get_engine");
830+
engines_[ne].engine = func();
831+
832+
auto& en = std::get<EngineI*>(engines_[ne].engine);
833+
if (ne == kLlamaRepo) { //fix for llamacpp engine first
834+
auto config = file_manager_utils::GetCortexConfig();
835+
if (en->IsSupported("SetFileLogger")) {
836+
en->SetFileLogger(config.maxLogLines,
837+
(std::filesystem::path(config.logFolderPath) /
838+
std::filesystem::path(config.logLlamaCppPath))
839+
.string());
840+
} else {
841+
CTL_WRN("Method SetFileLogger is not supported yet");
842+
}
843+
if (en->IsSupported("SetLogLevel")) {
844+
en->SetLogLevel(logging_utils_helper::global_log_level);
845+
} else {
846+
CTL_WRN("Method SetLogLevel is not supported yet");
857847
}
858-
CTL_DBG("loaded engine: " << ne);
859848
}
849+
CTL_DBG("loaded engine: " << ne);
860850
return {};
861851
}
862852

863853
cpp::result<void, std::string> EngineService::UnloadEngine(
864854
const std::string& engine) {
865855
auto ne = NormalizeEngine(engine);
856+
std::lock_guard<std::mutex> lock(engines_mutex_);
866857
{
867-
std::lock_guard<std::mutex> lock(engines_mutex_);
868858
if (!IsEngineLoaded(ne)) {
869859
return cpp::fail("Engine " + ne + " is not loaded yet!");
870860
}
@@ -893,14 +883,12 @@ cpp::result<void, std::string> EngineService::UnloadEngine(
893883
}
894884

895885
std::vector<EngineV> EngineService::GetLoadedEngines() {
896-
{
897-
std::lock_guard<std::mutex> lock(engines_mutex_);
898-
std::vector<EngineV> loaded_engines;
899-
for (const auto& [key, value] : engines_) {
900-
loaded_engines.push_back(value.engine);
901-
}
902-
return loaded_engines;
886+
std::lock_guard<std::mutex> lock(engines_mutex_);
887+
std::vector<EngineV> loaded_engines;
888+
for (const auto& [key, value] : engines_) {
889+
loaded_engines.push_back(value.engine);
903890
}
891+
return loaded_engines;
904892
}
905893

906894
cpp::result<github_release_utils::GitHubRelease, std::string>
@@ -1084,6 +1072,7 @@ std::string EngineService::DeleteEngine(int id) {
10841072

10851073
cpp::result<Json::Value, std::string> EngineService::GetRemoteModels(
10861074
const std::string& engine_name) {
1075+
std::lock_guard<std::mutex> lock(engines_mutex_);
10871076
if (auto r = IsEngineReady(engine_name); r.has_error()) {
10881077
return cpp::fail(r.error());
10891078
}
@@ -1093,7 +1082,6 @@ cpp::result<Json::Value, std::string> EngineService::GetRemoteModels(
10931082
if (exist_engine.has_error()) {
10941083
return cpp::fail("Remote engine '" + engine_name + "' is not installed");
10951084
}
1096-
10971085
if (engine_name == kOpenAiEngine) {
10981086
engines_[engine_name].engine = new remote_engine::OpenAiEngine();
10991087
} else {
@@ -1102,7 +1090,6 @@ cpp::result<Json::Value, std::string> EngineService::GetRemoteModels(
11021090

11031091
CTL_INF("Loaded engine: " << engine_name);
11041092
}
1105-
11061093
auto& e = std::get<RemoteEngineI*>(engines_[engine_name].engine);
11071094
auto res = e->GetRemoteModels();
11081095
if (!res["error"].isNull()) {

engine/services/engine_service.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,6 @@ class EngineService : public EngineServiceI {
112112
cpp::result<std::vector<EngineVariantResponse>, std::string>
113113
GetInstalledEngineVariants(const std::string& engine) const;
114114

115-
bool IsEngineLoaded(const std::string& engine);
116-
117115
cpp::result<EngineV, std::string> GetLoadedEngine(
118116
const std::string& engine_name);
119117

@@ -152,6 +150,8 @@ class EngineService : public EngineServiceI {
152150
const std::string& engine_name);
153151

154152
private:
153+
bool IsEngineLoaded(const std::string& engine);
154+
155155
cpp::result<void, std::string> DownloadEngine(
156156
const std::string& engine, const std::string& version = "latest",
157157
const std::optional<std::string> variant_name = std::nullopt);

0 commit comments

Comments
 (0)