Remove locks

This commit is contained in:
2026-04-24 17:10:29 +10:00
parent 7a11c9617b
commit 3a527d2dad
51 changed files with 38 additions and 1251 deletions

View File

@@ -1,22 +1,25 @@
#include "Utility.h"
#include <ctime>
#include <chrono>
#include <mutex>
#include <map>
#include <memory>
// Bounded wait when acquiring GetZipPathLock inside extractor/writer entry
// points. A genuine extract is seconds, but adversarial I/O (slow NAS,
// antivirus holding files, libzip hang on malformed archive, a crashed
// thread that never unwound the lock) can make it block indefinitely.
// 15 minutes is generous enough for large models on slow storage yet short
// enough that a service-wide hang turns into a localized load-failure
// visible in DebugView.
static constexpr auto kZipPathLockTimeout = std::chrono::minutes(15);
// Per-path mutex to serialize concurrent zip operations on the same target.
// Without this, two LabVIEW threads can race: one extracting a zip while
// another truncates/writes the same file, corrupting data and crashing LabVIEW.
// Also used to serialize extract ↔ ONNX session creation on the same extracted
// 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.
// Scope is limited to the extractor / zip writer — once ExtractProtectedZipFile
// returns, the sidecar check makes subsequent calls fast no-ops, and readers
// (ORT / TRT session create) access stable files concurrently with no lock.
static std::mutex g_zipPathMapMutex;
static std::map<std::string, std::shared_ptr<std::recursive_timed_mutex>> g_zipPathLocks;
@@ -27,13 +30,6 @@ static std::shared_ptr<std::recursive_timed_mutex> GetZipPathLock(const std::str
return ptr;
}
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());
return ptr;
}
template <typename T>
T get_data(const boost::property_tree::ptree& pt, const std::string& key)
{
@@ -470,7 +466,17 @@ 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::recursive_timed_mutex> zipGuard(*pathLock);
ANS_DBG("Extract", "ZipFolderWithPassword: waiting on zip lock (%llds): %s",
(long long)std::chrono::duration_cast<std::chrono::seconds>(kZipPathLockTimeout).count(),
zipFilePath ? zipFilePath : "(null)");
std::unique_lock<std::recursive_timed_mutex> zipGuard(*pathLock, std::defer_lock);
if (!zipGuard.try_lock_for(kZipPathLockTimeout)) {
ANS_DBG("Extract", "ZipFolderWithPassword: TIMEOUT acquiring zip lock for %s",
zipFilePath ? zipFilePath : "(null)");
return false;
}
ANS_DBG("Extract", "ZipFolderWithPassword: zip lock acquired: %s",
zipFilePath ? zipFilePath : "(null)");
zip* zipArchive;
zip_flags_t flags = ZIP_CREATE | ZIP_TRUNCATE;
@@ -856,7 +862,16 @@ 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::recursive_timed_mutex> zipGuard(*pathLock);
ANS_DBG("Extract", "ExtractProtectedZipFile: waiting on zip lock (%llds): %s",
(long long)std::chrono::duration_cast<std::chrono::seconds>(kZipPathLockTimeout).count(),
outputFolder.c_str());
std::unique_lock<std::recursive_timed_mutex> zipGuard(*pathLock, std::defer_lock);
if (!zipGuard.try_lock_for(kZipPathLockTimeout)) {
ANS_DBG("Extract", "ExtractProtectedZipFile: TIMEOUT acquiring zip lock for %s (zip=%s)",
outputFolder.c_str(), zipFileName.c_str());
return false;
}
ANS_DBG("Extract", "ExtractProtectedZipFile: zip lock acquired: %s", outputFolder.c_str());
int error;
if (!FileExist(zipFileName))return false;