Fix deadlock

This commit is contained in:
2026-04-24 12:54:16 +10:00
parent e2bf17289d
commit fd2394a85a
3 changed files with 138 additions and 16 deletions

View File

@@ -11,17 +11,23 @@
// model folder — without that, thread A can finish extraction and begin opening
// train_last.onnx while thread B re-enters extraction and truncates the file,
// producing "system error number 13" (EACCES) on the first reader.
// Recursive so the same thread can re-acquire the lock through layered load
// calls — ANSALPR_OD::LoadEngine -> ANSONNXYOLO::LoadModelFromFolder both
// acquire the SAME folder lock on the SAME thread. A non-recursive
// timed_mutex deadlocks that nesting for 120 s then fails. Recursive keeps
// cross-thread serialization intact while allowing legitimate re-entry from
// the lock-holding thread.
static std::mutex g_zipPathMapMutex;
static std::map<std::string, std::shared_ptr<std::timed_mutex>> g_zipPathLocks;
static std::map<std::string, std::shared_ptr<std::recursive_timed_mutex>> g_zipPathLocks;
static std::shared_ptr<std::timed_mutex> GetZipPathLock(const std::string& path) {
static std::shared_ptr<std::recursive_timed_mutex> GetZipPathLock(const std::string& path) {
std::lock_guard<std::mutex> guard(g_zipPathMapMutex);
auto& ptr = g_zipPathLocks[path];
if (!ptr) ptr = std::make_shared<std::timed_mutex>();
if (!ptr) ptr = std::make_shared<std::recursive_timed_mutex>();
return ptr;
}
std::shared_ptr<std::timed_mutex> GetModelFolderLock(const std::string& folderPath) {
std::shared_ptr<std::recursive_timed_mutex> GetModelFolderLock(const std::string& folderPath) {
auto ptr = GetZipPathLock(folderPath);
ANS_DBG("ModelLock", "GetModelFolderLock: folder=%s mutex=%p",
folderPath.c_str(), (void*)ptr.get());
@@ -464,7 +470,7 @@ bool AddFolderContentsToZip(zip* archive, const char* folderPath, const char* zi
bool ZipFolderWithPassword(const char* folderPath, const char* zipFilePath, const char* password) {
auto pathLock = GetZipPathLock(std::string(zipFilePath));
std::lock_guard<std::timed_mutex> zipGuard(*pathLock);
std::lock_guard<std::recursive_timed_mutex> zipGuard(*pathLock);
zip* zipArchive;
zip_flags_t flags = ZIP_CREATE | ZIP_TRUNCATE;
@@ -850,7 +856,7 @@ std::string GetDateTimeString(const std::string& format) {
bool ExtractProtectedZipFile(const std::string& zipFileName, const std::string& password, const std::string& modelName, const std::string outputFolder)
{
auto pathLock = GetZipPathLock(outputFolder);
std::lock_guard<std::timed_mutex> zipGuard(*pathLock);
std::lock_guard<std::recursive_timed_mutex> zipGuard(*pathLock);
int error;
if (!FileExist(zipFileName))return false;