From e2bf17289d9f82e9feb3b860ee9bf08c01fc6fe0 Mon Sep 17 00:00:00 2001 From: Tuan Nghia Nguyen Date: Fri, 24 Apr 2026 12:19:54 +1000 Subject: [PATCH] Fix model extract race issue to all classes --- .claude/settings.local.json | 3 +- core/ANSLicensingSystem/Utility.cpp | 155 +++++++++++++----- core/ANSLicensingSystem/Utility.h | 102 ++++++++++++ modules/ANSFR/ANSFaceRecognizer.cpp | 18 ++ modules/ANSFR/ARCFaceRT.cpp | 18 ++ modules/ANSFR/FaceNet.cpp | 18 ++ modules/ANSLPR/ANSLPR.cpp | 9 + modules/ANSLPR/ANSLPR_CPU.cpp | 18 ++ modules/ANSLPR/ANSLPR_OCR.cpp | 18 ++ modules/ANSLPR/ANSLPR_OD.cpp | 18 ++ modules/ANSOCR/ANSCpuOCR.cpp | 9 + modules/ANSOCR/ANSOCR.cpp | 9 + modules/ANSOCR/ANSOCRBase.cpp | 18 ++ modules/ANSOCR/ANSOnnxOCR.cpp | 9 + modules/ANSOCR/ANSRtOCR.cpp | 9 + modules/ANSODEngine/ANSANOMALIB.cpp | 27 +++ modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp | 18 ++ modules/ANSODEngine/ANSCUSTOMPY.cpp | 9 + modules/ANSODEngine/ANSEngineCommon.h | 6 + modules/ANSODEngine/ANSFaceDetectorEngine.cpp | 20 ++- .../ANSODEngine/ANSFaceRecognizerEngine.cpp | 22 ++- modules/ANSODEngine/ANSMotionDetector.cpp | 18 ++ modules/ANSODEngine/ANSODHUB.cpp | 27 +++ modules/ANSODEngine/ANSONNXCL.cpp | 27 +++ modules/ANSODEngine/ANSONNXOBB.cpp | 27 +++ modules/ANSODEngine/ANSONNXPOSE.cpp | 27 +++ modules/ANSODEngine/ANSONNXSAM3.cpp | 27 +++ modules/ANSODEngine/ANSONNXSEG.cpp | 27 +++ modules/ANSODEngine/ANSONNXYOLO.cpp | 114 ++----------- modules/ANSODEngine/ANSOPENVINOCL.cpp | 27 +++ modules/ANSODEngine/ANSOPENVINOOD.cpp | 27 +++ modules/ANSODEngine/ANSOVFBFaceDetector.cpp | 20 ++- modules/ANSODEngine/ANSOVFaceDetector.cpp | 27 +++ modules/ANSODEngine/ANSOVSEG.cpp | 27 +++ modules/ANSODEngine/ANSPOSE.cpp | 27 +++ modules/ANSODEngine/ANSRTYOLO.cpp | 27 +++ modules/ANSODEngine/ANSSAM.cpp | 27 +++ modules/ANSODEngine/ANSSAM3.cpp | 27 +++ modules/ANSODEngine/ANSTENSORRTCL.cpp | 27 +++ modules/ANSODEngine/ANSTENSORRTPOSE.cpp | 27 +++ modules/ANSODEngine/ANSTENSORRTSEG.cpp | 27 +++ modules/ANSODEngine/ANSTENSORTRTOD.cpp | 27 +++ modules/ANSODEngine/ANSYOLO12OD.cpp | 27 +++ modules/ANSODEngine/ANSYOLOOD.cpp | 27 +++ modules/ANSODEngine/ANSYOLOV10OVOD.cpp | 27 +++ modules/ANSODEngine/ANSYOLOV10RTOD.cpp | 27 +++ modules/ANSODEngine/ANSYOLOV12RTOD.cpp | 27 +++ modules/ANSODEngine/Movienet.cpp | 27 +++ modules/ANSODEngine/RetinaFaceDetector.cpp | 20 ++- modules/ANSODEngine/SCRFDFaceDetector.cpp | 27 +++ modules/ANSODEngine/SCRFDOVFaceDetector.cpp | 20 ++- 51 files changed, 1252 insertions(+), 148 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 9f1a871..2a05419 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -101,7 +101,8 @@ "Read(//tmp/**)", "Bash(grep -oE ']*>[^<]{0,400}' \"/c/Users/nghia/Downloads/error.xml\")", "Bash(echo \"Exit: $?\")", - "Bash(python -)" + "Bash(python -)", + "Bash(git show *)" ] } } diff --git a/core/ANSLicensingSystem/Utility.cpp b/core/ANSLicensingSystem/Utility.cpp index 2614a2c..0ce20a5 100644 --- a/core/ANSLicensingSystem/Utility.cpp +++ b/core/ANSLicensingSystem/Utility.cpp @@ -855,56 +855,104 @@ bool ExtractProtectedZipFile(const std::string& zipFileName, const std::string& int error; if (!FileExist(zipFileName))return false; - // Idempotent fast-path: if the target folder already has a complete, fresh - // extraction (at least one non-empty regular file, all >= the zip's mtime), - // skip re-extraction. This prevents redundant passes from concurrent - // CreateANSODHandle calls from truncating files that another thread is - // already mmap'ing via ORT (which surfaces as EACCES / system error 13). + // Idempotent fast-path: skip re-extraction when the target folder already + // holds exactly the content of the current zip. Identity is tracked by a + // small sidecar file (.ans_extract_info) written inside outputFolder after + // every successful extract. The sidecar records three fields — zip path, + // zip size, zip mtime — and we SKIP only if ALL match the current zip AND + // the folder still has at least one non-empty file. + // + // Why sidecar and not just mtime? mtime alone breaks on: + // • downgrades — a reverted older zip has an older mtime, so "file mtime + // >= zip mtime" falsely reports fresh and we never re-extract. + // • preserved-timestamp copies (cp --preserve=timestamps, some installers, + // Git-LFS checkouts) — new-but-older-mtime zips look "not newer". + // Size differs whenever content differs (libzip's CRC/compression shifts + // bytes even for tiny payload changes), so size+mtime+path uniquely pins + // the zip identity in practice. + // + // Any mismatch / missing sidecar / FS error → fall through to full extract, + // which unconditionally rewrites the sidecar at the end. This means the + // first run after deploying this patched binary will do one re-extract per + // model to establish the sidecar; subsequent runs hit the fast path. + const std::filesystem::path sidecarPath = + std::filesystem::path(outputFolder) / ".ans_extract_info"; + ANS_DBG("Extract", "ExtractProtectedZipFile: zip=%s -> folder=%s", zipFileName.c_str(), outputFolder.c_str()); + + // Capture the current zip's identity up-front so both the fast-path check + // and the post-extract sidecar write see consistent values. + std::uintmax_t curZipSize = 0; + long long curZipMtime = 0; + bool zipStatOk = false; try { - if (std::filesystem::exists(outputFolder) && - std::filesystem::is_directory(outputFolder)) + curZipSize = std::filesystem::file_size(zipFileName); + curZipMtime = std::filesystem::last_write_time(zipFileName) + .time_since_epoch().count(); + zipStatOk = true; + } + catch (const std::exception& ex) { + ANS_DBG("Extract", + "ExtractProtectedZipFile: failed to stat zip (%s); extracting anyway", + ex.what()); + } + + try { + if (zipStatOk && + std::filesystem::exists(outputFolder) && + std::filesystem::is_directory(outputFolder) && + std::filesystem::exists(sidecarPath)) { - const auto zipTime = std::filesystem::last_write_time(zipFileName); - bool anyFile = false; - bool allFresh = true; - size_t numFiles = 0; - std::string staleFile; - for (const auto& e : std::filesystem::directory_iterator(outputFolder)) { - if (!e.is_regular_file()) continue; - anyFile = true; - ++numFiles; - std::error_code ec; - const auto sz = e.file_size(ec); - if (ec || sz == 0) { - allFresh = false; - staleFile = e.path().filename().string() + " (zero/err)"; - break; + // Read sidecar: 3 lines — zipPath, zipSize, zipMtime. + std::ifstream sf(sidecarPath); + std::string storedPath; + std::uintmax_t storedSize = 0; + long long storedMtime = 0; + std::getline(sf, storedPath); + sf >> storedSize >> storedMtime; + if (sf.good() || sf.eof()) { + // Sanity: folder must still contain at least one non-empty file + // (defends against a sidecar that outlived its content, e.g. a + // user manually wiping model files but leaving the sidecar). + bool hasNonEmpty = false; + size_t numFiles = 0; + for (const auto& e : std::filesystem::directory_iterator(outputFolder)) { + if (!e.is_regular_file()) continue; + if (e.path().filename() == ".ans_extract_info") continue; + ++numFiles; + std::error_code ec; + if (e.file_size(ec) > 0 && !ec) { hasNonEmpty = true; break; } } - const auto ft = std::filesystem::last_write_time(e.path(), ec); - if (ec || ft < zipTime) { - allFresh = false; - staleFile = e.path().filename().string() + " (older than zip)"; - break; + const bool pathOk = (storedPath == zipFileName); + const bool sizeOk = (storedSize == curZipSize); + const bool mtimeOk = (storedMtime == curZipMtime); + if (pathOk && sizeOk && mtimeOk && hasNonEmpty) { + ANS_DBG("Extract", + "ExtractProtectedZipFile: SKIP re-extract — sidecar match (size=%llu mtime=%lld, %zu payload file(s))", + (unsigned long long)curZipSize, + (long long)curZipMtime, numFiles); + return true; } + ANS_DBG("Extract", + "ExtractProtectedZipFile: full extract needed — sidecar mismatch (path:%d size:%d mtime:%d nonEmpty:%d)", + pathOk ? 0 : 1, sizeOk ? 0 : 1, mtimeOk ? 0 : 1, + hasNonEmpty ? 1 : 0); + } else { + ANS_DBG("Extract", + "ExtractProtectedZipFile: sidecar unreadable, re-extracting"); } - if (anyFile && allFresh) { - ANS_DBG("Extract", "ExtractProtectedZipFile: SKIP re-extract — %zu file(s) already fresh in %s", - numFiles, outputFolder.c_str()); - return true; // already extracted and up-to-date - } + } else if (zipStatOk) { ANS_DBG("Extract", - "ExtractProtectedZipFile: full extract needed — anyFile=%d stale=%s", - anyFile ? 1 : 0, - staleFile.empty() ? "(empty folder)" : staleFile.c_str()); - } else { - ANS_DBG("Extract", "ExtractProtectedZipFile: folder absent, full extract"); + "ExtractProtectedZipFile: %s, full extract", + std::filesystem::exists(outputFolder) ? "no sidecar yet" + : "folder absent"); } } catch (const std::exception& ex) { - // Any filesystem hiccup: fall through to full extraction. - ANS_DBG("Extract", "ExtractProtectedZipFile: freshness check threw, extracting: %s", + // Any filesystem hiccup: fall through to full extraction (safe). + ANS_DBG("Extract", + "ExtractProtectedZipFile: freshness check threw, extracting: %s", ex.what()); } @@ -977,6 +1025,35 @@ bool ExtractProtectedZipFile(const std::string& zipFileName, const std::string& return false; } zip_close(archive); + + // Extract succeeded — write the identity sidecar so the next call on this + // folder can take the fast-path. We re-read zip stats here (rather than + // trust the pre-extract snapshot) in case the zip was touched in between. + try { + std::uintmax_t finalSize = std::filesystem::file_size(zipFileName); + long long finalMtime = std::filesystem::last_write_time(zipFileName) + .time_since_epoch().count(); + std::ofstream sf(sidecarPath, std::ios::binary | std::ios::trunc); + if (sf.is_open()) { + sf << zipFileName << '\n' << finalSize << '\n' << finalMtime << '\n'; + ANS_DBG("Extract", + "ExtractProtectedZipFile: sidecar written (size=%llu mtime=%lld) at %s", + (unsigned long long)finalSize, (long long)finalMtime, + sidecarPath.string().c_str()); + } else { + ANS_DBG("Extract", + "ExtractProtectedZipFile: could not open sidecar for write: %s", + sidecarPath.string().c_str()); + } + } + catch (const std::exception& ex) { + // Non-fatal — extract already succeeded. Next call will just re-extract + // once more until the sidecar can be written. + ANS_DBG("Extract", + "ExtractProtectedZipFile: sidecar write threw (non-fatal): %s", + ex.what()); + } + return true; } diff --git a/core/ANSLicensingSystem/Utility.h b/core/ANSLicensingSystem/Utility.h index 4c78cd2..7ad6b09 100644 --- a/core/ANSLicensingSystem/Utility.h +++ b/core/ANSLicensingSystem/Utility.h @@ -99,4 +99,106 @@ namespace fs = std::filesystem; // Returns std::timed_mutex so callers can bound their wait and avoid a hang // if a peer thread deadlocks inside extraction or ORT session creation. ANSLICENSE_API std::shared_ptr GetModelFolderLock(const std::string& folderPath); + +// ============================================================================ +// ModelFolderLockGuard +// +// RAII guard that serializes "open files in an extracted model folder" against +// re-entries into ExtractProtectedZipFile on the SAME folder. Without this, +// two threads creating handles for the same model zip can race so that thread +// A opens a model file (via ORT / TRT / OpenVINO) while thread B truncates it +// via std::ofstream inside the extractor — Windows surfaces this as "system +// error number 13" (EACCES) on the reader. +// +// Backed by GetModelFolderLock() above which returns a process-wide +// std::timed_mutex keyed on the folder path. The extractor takes the same +// lock, so extract ↔ open is mutually exclusive. +// +// Acquisition is bounded by `timeout` (default 120 s) so a deadlocked peer +// cannot hang the caller thread forever. On timeout, .acquired() is false and +// the caller must fail the load. +// +// Lives in Utility.h (rather than a per-module header) so every ANSCORE +// module — ANSODEngine, ANSOCR, ANSLPR, ANSFR, etc. — can use it without +// pulling in ANSODEngine headers. +// +// Usage: +// +// bool MyEngine::LoadModelFromFolder(...) { +// bool result = MyBase::LoadModelFromFolder(...); +// if (!result) return false; +// // ── serialize derived-class init against concurrent extracts ── +// ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, +// "MyEngine::LoadModelFromFolder"); +// if (!_flg.acquired()) { +// _logger.LogError("MyEngine::LoadModelFromFolder", +// "Timed out waiting for model-folder lock: " + _modelFolder, +// __FILE__, __LINE__); +// return false; +// } +// // ... existing body: Init(...) / buildLoadNetwork(...) / etc. ... +// } +// +// Notes: +// • Placement — insert AFTER the base's XXX() returns (extractor already +// released its own lock by then) and BEFORE any file open in _modelFolder. +// Wrapping the base call would deadlock — it takes the same lock itself. +// • RAII — destructor auto-releases on every return path within the scope. +// • Timing — entry/acquire/timeout are traced via ANS_DBG("EngineLoad"), +// filter on [EngineLoad] in DebugView to diagnose stalls. +// ============================================================================ +namespace ANSCENTER { + class ModelFolderLockGuard { + public: + explicit ModelFolderLockGuard(const std::string& folderPath, + const char* caller, + std::chrono::seconds timeout = std::chrono::seconds(120)) + : _caller(caller ? caller : "(?)"), _folder(folderPath) + { + if (folderPath.empty()) { + // Nothing to serialize — no extracted folder yet. Treat as + // acquired so caller's existing init runs unchanged (e.g. + // custom-path engines that never go through the zip extractor). + _ok = true; + ANS_DBG("EngineLoad", "%s: empty folder path, skipping lock", + _caller); + return; + } + auto lock = GetModelFolderLock(folderPath); + _guard = std::unique_lock(*lock, std::defer_lock); + ANS_DBG("EngineLoad", + "%s: waiting on folder lock (%llds): %s", + _caller, (long long)timeout.count(), folderPath.c_str()); + const auto t0 = std::chrono::steady_clock::now(); + if (_guard.try_lock_for(timeout)) { + const auto ms = std::chrono::duration_cast( + std::chrono::steady_clock::now() - t0).count(); + _ok = true; + ANS_DBG("EngineLoad", "%s: folder lock acquired in %lldms", + _caller, (long long)ms); + } else { + const auto ms = std::chrono::duration_cast( + std::chrono::steady_clock::now() - t0).count(); + _ok = false; + ANS_DBG("EngineLoad", + "%s: TIMEOUT on folder lock after %lldms: %s", + _caller, (long long)ms, folderPath.c_str()); + } + } + + // Non-copyable, non-movable: lock lifetime is tied to this scope. + ModelFolderLockGuard(const ModelFolderLockGuard&) = delete; + ModelFolderLockGuard& operator=(const ModelFolderLockGuard&) = delete; + + bool acquired() const noexcept { return _ok; } + explicit operator bool() const noexcept { return _ok; } + + private: + const char* _caller; + std::string _folder; + std::unique_lock _guard; + bool _ok = false; + }; +} // namespace ANSCENTER + #endif \ No newline at end of file diff --git a/modules/ANSFR/ANSFaceRecognizer.cpp b/modules/ANSFR/ANSFaceRecognizer.cpp index fc255e0..4efeeb9 100644 --- a/modules/ANSFR/ANSFaceRecognizer.cpp +++ b/modules/ANSFR/ANSFaceRecognizer.cpp @@ -55,6 +55,15 @@ namespace ANSCENTER { ANS_DBG("FaceRecognizer", "ANSFRBase::Initialize FAILED"); return false; } + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSFR::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSFR::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } #ifdef CPU_MODE engineType = EngineType::CPU; ANS_DBG("FaceRecognizer", "CPU_MODE forced: engineType=CPU"); @@ -199,6 +208,15 @@ namespace ANSCENTER { try { bool result = ANSFRBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSFaceRecognizer::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSFaceRecognizer::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } if (engineType == EngineType::NVIDIA_GPU) { std::string onnxfile = CreateFilePath(_modelFolder, "ansfacerecognizer.onnx"); diff --git a/modules/ANSFR/ARCFaceRT.cpp b/modules/ANSFR/ARCFaceRT.cpp index ba66d2d..92f9ad5 100644 --- a/modules/ANSFR/ARCFaceRT.cpp +++ b/modules/ANSFR/ARCFaceRT.cpp @@ -9,6 +9,15 @@ namespace ANSCENTER { std::string& labelMap) { bool result = ANSFRBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ArcFace::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ArcFace::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } try { _modelConfig = modelConfig; @@ -71,6 +80,15 @@ namespace ANSCENTER { try { bool result = ANSFRBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ArcFace::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ArcFace::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string onnxfile50 = CreateFilePath(_modelFolder, "ansfacerecognizer50.onnx"); if (std::filesystem::exists(onnxfile50)) { diff --git a/modules/ANSFR/FaceNet.cpp b/modules/ANSFR/FaceNet.cpp index 3c5d517..dd16c75 100644 --- a/modules/ANSFR/FaceNet.cpp +++ b/modules/ANSFR/FaceNet.cpp @@ -20,6 +20,15 @@ namespace ANSCENTER { { bool result = ANSFRBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSFaceNet::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSFaceNet::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } try { _modelConfig = modelConfig; _modelConfig.modelType = ModelType::FACERECOGNIZE; @@ -65,6 +74,15 @@ namespace ANSCENTER { // We need to get the _modelFolder bool result = ANSFRBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSFaceNet::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSFaceNet::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // We need to get the modelfolder from here std::string faceidModel = CreateFilePath(_modelFolder, "ansfacenet.xml"); if (std::filesystem::exists(faceidModel)) { diff --git a/modules/ANSLPR/ANSLPR.cpp b/modules/ANSLPR/ANSLPR.cpp index cdfb43f..971cbf3 100644 --- a/modules/ANSLPR/ANSLPR.cpp +++ b/modules/ANSLPR/ANSLPR.cpp @@ -518,6 +518,15 @@ namespace ANSCENTER { this->_logger.LogError("ANSFDBase::Initialize. Output model folder is not exist", _modelFolder, __FILE__, __LINE__); return false; // That means the model file is not exist or the password is not correct } + // Serialize init against concurrent extract re-entries on the same + // folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSALPR::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSALPR::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } return true; } catch (std::exception& e) { diff --git a/modules/ANSLPR/ANSLPR_CPU.cpp b/modules/ANSLPR/ANSLPR_CPU.cpp index e7faa14..cc9907e 100644 --- a/modules/ANSLPR/ANSLPR_CPU.cpp +++ b/modules/ANSLPR/ANSLPR_CPU.cpp @@ -304,6 +304,15 @@ namespace ANSCENTER { this->_logger.LogError("ANSALPR_CPU::Initialize. Output model folder is not exist", _modelFolder, __FILE__, __LINE__); return false; // That means the model file is not exist or the password is not correct } + // Serialize init against concurrent extract re-entries on the same + // folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSALPR_CPU::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSALPR_CPU::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // 3. Load LD model alprChecker.Init(MAX_ALPR_FRAME); @@ -317,6 +326,15 @@ namespace ANSCENTER { bool ANSALPR_CPU::LoadEngine() { std::lock_guard lock(_mutex); try { + // Serialize init against concurrent extract re-entries on the same + // folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSALPR_CPU::LoadEngine"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSALPR_CPU::LoadEngine", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // 1. Load license plate detection model (using CPU OpenVINO) if (_lprDetector) _lprDetector.reset(); std::string lprModel = CreateFilePath(_modelFolder, "lprModel.xml"); diff --git a/modules/ANSLPR/ANSLPR_OCR.cpp b/modules/ANSLPR/ANSLPR_OCR.cpp index d4b53ea..12f438f 100644 --- a/modules/ANSLPR/ANSLPR_OCR.cpp +++ b/modules/ANSLPR/ANSLPR_OCR.cpp @@ -177,6 +177,15 @@ namespace ANSCENTER this->_logger.LogError("ANSALPR_OCR::Initialize", "Output model folder does not exist: " + _modelFolder, __FILE__, __LINE__); return false; } + // Serialize init against concurrent extract re-entries on the same + // folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSALPR_OCR::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSALPR_OCR::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Check country from country.txt std::string countryFile = CreateFilePath(_modelFolder, "country.txt"); @@ -216,6 +225,15 @@ namespace ANSCENTER bool ANSALPR_OCR::LoadEngine() { std::lock_guard lock(_mutex); try { + // Serialize init against concurrent extract re-entries on the same + // folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSALPR_OCR::LoadEngine"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSALPR_OCR::LoadEngine", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } WriteEventLog("ANSALPR_OCR::LoadEngine: Step 1 - Starting engine load"); this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 1: Starting engine load", __FILE__, __LINE__); diff --git a/modules/ANSLPR/ANSLPR_OD.cpp b/modules/ANSLPR/ANSLPR_OD.cpp index 0bfb586..a2f2aa4 100644 --- a/modules/ANSLPR/ANSLPR_OD.cpp +++ b/modules/ANSLPR/ANSLPR_OD.cpp @@ -431,6 +431,15 @@ namespace ANSCENTER { this->_logger.LogError("ANSALPR_OD::Initialize. Output model folder is not exist", _modelFolder, __FILE__, __LINE__); return false; // That means the model file is not exist or the password is not correct } + // Serialize init against concurrent extract re-entries on the same + // folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSALPR_OD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSALPR_OD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Check country std::string countryFile = CreateFilePath(_modelFolder, "country.txt"); @@ -509,6 +518,15 @@ namespace ANSCENTER { bool ANSALPR_OD::LoadEngine() { std::lock_guard lock(_mutex); try { + // Serialize init against concurrent extract re-entries on the same + // folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSALPR_OD::LoadEngine"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSALPR_OD::LoadEngine", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } WriteEventLog("ANSALPR_OD::LoadEngine: Step 1 - Starting engine load"); this->_logger.LogInfo("ANSALPR_OD::LoadEngine", "Step 1: Starting engine load", __FILE__, __LINE__); diff --git a/modules/ANSOCR/ANSCpuOCR.cpp b/modules/ANSOCR/ANSCpuOCR.cpp index 2bb99b3..366d253 100644 --- a/modules/ANSOCR/ANSCpuOCR.cpp +++ b/modules/ANSOCR/ANSCpuOCR.cpp @@ -13,6 +13,15 @@ namespace ANSCENTER { { bool result = ANSOCRBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, engineMode); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSCPUOCR::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSCPUOCR::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } //Override the paddleocrv3 for openvino only switch (_modelConfig.ocrLanguage) { diff --git a/modules/ANSOCR/ANSOCR.cpp b/modules/ANSOCR/ANSOCR.cpp index 6f4317b..64d994a 100644 --- a/modules/ANSOCR/ANSOCR.cpp +++ b/modules/ANSOCR/ANSOCR.cpp @@ -9,6 +9,15 @@ namespace ANSCENTER { { bool result = ANSOCRBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, engineMode); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSOCR::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOCR::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } auto option = fastdeploy::RuntimeOption(); // Add default values to modelConfig if required. _modelConfig.precisionType = "fp32"; diff --git a/modules/ANSOCR/ANSOCRBase.cpp b/modules/ANSOCR/ANSOCRBase.cpp index 9a7b26e..411c4ad 100644 --- a/modules/ANSOCR/ANSOCRBase.cpp +++ b/modules/ANSOCR/ANSOCRBase.cpp @@ -96,6 +96,15 @@ namespace ANSCENTER { this->_logger.LogError("ANSOCRBase::Initialize. Output model folder is not exist", modelName, __FILE__, __LINE__); return false; // That means the model file is not exist or the password is not correct } + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSOCRBase::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOCRBase::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } return true; } @@ -149,6 +158,15 @@ namespace ANSCENTER { this->_logger.LogError("ANSOCRBase::Initialize. Output model folder is not exist", modelName, __FILE__, __LINE__); return false; // That means the model file is not exist or the password is not correct } + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSOCRBase::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOCRBase::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // 3. Check if the model has the configuration file std::string modelConfigName = "model_config.json"; _modelConfigFile = CreateFilePath(_modelFolder, modelConfigName); diff --git a/modules/ANSOCR/ANSOnnxOCR.cpp b/modules/ANSOCR/ANSOnnxOCR.cpp index 763aed6..cd1297d 100644 --- a/modules/ANSOCR/ANSOnnxOCR.cpp +++ b/modules/ANSOCR/ANSOnnxOCR.cpp @@ -9,6 +9,15 @@ bool ANSONNXOCR::Initialize(const std::string& licenseKey, OCRModelConfig modelC try { bool result = ANSOCRBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, engineMode); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSONNXOCR::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXOCR::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Validate detection model if (!FileExist(_modelConfig.detectionModelFile)) { diff --git a/modules/ANSOCR/ANSRtOCR.cpp b/modules/ANSOCR/ANSRtOCR.cpp index e5e1d02..4f7f461 100644 --- a/modules/ANSOCR/ANSRtOCR.cpp +++ b/modules/ANSOCR/ANSRtOCR.cpp @@ -9,6 +9,15 @@ bool ANSRTOCR::Initialize(const std::string& licenseKey, OCRModelConfig modelCon try { bool result = ANSOCRBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, engineMode); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in Utility.h. + ANSCENTER::ModelFolderLockGuard _flg(_modelFolder, "ANSRTOCR::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSRTOCR::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Validate detection model if (!FileExist(_modelConfig.detectionModelFile)) { diff --git a/modules/ANSODEngine/ANSANOMALIB.cpp b/modules/ANSODEngine/ANSANOMALIB.cpp index 34928e6..bbc129e 100644 --- a/modules/ANSODEngine/ANSANOMALIB.cpp +++ b/modules/ANSODEngine/ANSANOMALIB.cpp @@ -33,6 +33,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSANOMALIB::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSANOMALIB::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _device = "AUTO:GPU,CPU"; _openvinoPreprocess = true; _efficientAd = false; @@ -91,6 +100,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSANOMALIB::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSANOMALIB::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "model"; @@ -167,6 +185,15 @@ namespace ANSCENTER { //this->_logger.LogDebug("ANSANOMALIB::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__); bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSANOMALIB::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSANOMALIB::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for ABNORMAL only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::SEGMENTATION; diff --git a/modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp b/modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp index 2cf29eb..6855940 100644 --- a/modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp +++ b/modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp @@ -38,6 +38,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSCUSTOMDETECTOR::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSCUSTOMDETECTOR::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string labelMap; CreateCustomDetector(); //_customDetector->SetLoadEngineOnCreate(this->_loadEngineOnCreation); @@ -248,6 +257,15 @@ namespace ANSCENTER try { bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSCUSTOMDETECTOR::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSCUSTOMDETECTOR::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig = modelConfig; if (_modelConfig.modelMNSThreshold < 0.2) _modelConfig.modelMNSThreshold = 0.5; diff --git a/modules/ANSODEngine/ANSCUSTOMPY.cpp b/modules/ANSODEngine/ANSCUSTOMPY.cpp index 0575ad5..672acee 100644 --- a/modules/ANSODEngine/ANSCUSTOMPY.cpp +++ b/modules/ANSODEngine/ANSCUSTOMPY.cpp @@ -343,6 +343,15 @@ if sys.stderr is None or not hasattr(sys.stderr, "write"): // Step 1: Base model init bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSCUSTOMPY::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSCUSTOMPY::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig = modelConfig; _modelConfig.inpHeight = 640; diff --git a/modules/ANSODEngine/ANSEngineCommon.h b/modules/ANSODEngine/ANSEngineCommon.h index 327b0b3..666f64a 100644 --- a/modules/ANSODEngine/ANSEngineCommon.h +++ b/modules/ANSODEngine/ANSEngineCommon.h @@ -26,6 +26,12 @@ #define DEBUG_PRINT(x) std::cout << x << std::endl; //#define DEBUGENGINE //#define USE_TV_MODEL // Use model to detect if person is on TV screen or not + +// NOTE: ANSCENTER::ModelFolderLockGuard has been moved to Utility.h so that +// non-ANSODEngine modules (ANSOCR, ANSLPR, ANSFR, ...) can use it without +// pulling in ANSODEngine headers. It remains available here transitively +// because this file #includes "Utility.h" above. + const int MAX_HISTORY_FACE = 5; const int MAX_MISSING_FACE = 30; const int MAX_TRACKS = 200; diff --git a/modules/ANSODEngine/ANSFaceDetectorEngine.cpp b/modules/ANSODEngine/ANSFaceDetectorEngine.cpp index ca5d320..19033dc 100644 --- a/modules/ANSODEngine/ANSFaceDetectorEngine.cpp +++ b/modules/ANSODEngine/ANSFaceDetectorEngine.cpp @@ -62,13 +62,22 @@ namespace ANSCENTER size_t vectorSize = passwordArray.size(); for (size_t i = 0; i < vectorSize; i++) { if (ExtractPasswordProtectedZip(modelZipFilePath, passwordArray[i], modelName, _modelFolder, false)) - break; // Break the loop when the condition is met. + break; // Break the loop when the condition is met. } // 2. Check if the outputFolder exist if (!std::filesystem::exists(_modelFolder)) { this->_logger.LogError("ANSFDBase::LoadModel. Output model folder is not exist", _modelFolder, __FILE__, __LINE__); return false; // That means the model file is not exist or the password is not correct } + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSFDBase::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSFDBase::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // 3. Check if the model has the configuration file std::string modelConfigName = "model_config.json"; _modelConfigFile = CreateFilePath(_modelFolder, modelConfigName); @@ -160,6 +169,15 @@ namespace ANSCENTER this->_logger.LogError("ANSFDBase::Initialize. Output model folder does not exist", _modelFolder, __FILE__, __LINE__); return false; } + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSFDBase::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSFDBase::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfigFile = CreateFilePath(_modelFolder, "model_config.json"); // 4. Load the image processing model diff --git a/modules/ANSODEngine/ANSFaceRecognizerEngine.cpp b/modules/ANSODEngine/ANSFaceRecognizerEngine.cpp index 6468f8a..f54982d 100644 --- a/modules/ANSODEngine/ANSFaceRecognizerEngine.cpp +++ b/modules/ANSODEngine/ANSFaceRecognizerEngine.cpp @@ -57,13 +57,22 @@ namespace ANSCENTER size_t vectorSize = passwordArray.size(); for (size_t i = 0; i < vectorSize; i++) { if (ExtractPasswordProtectedZip(modelZipFilePath, passwordArray[i], modelName, _modelFolder, false)) - break; // Break the loop when the condition is met. + break; // Break the loop when the condition is met. } // 2. Check if the outputFolder exist if (!std::filesystem::exists(_modelFolder)) { this->_logger.LogError("ANSFRBase::LoadModel. Output model folder is not exist", _modelFolder, __FILE__, __LINE__); return false; // That means the model file is not exist or the password is not correct } + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSFRBase::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSFRBase::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // 3. Check if the model has the configuration file std::string modelConfigName = "model_config.json"; _modelConfigFile = CreateFilePath(_modelFolder, modelConfigName); @@ -105,13 +114,22 @@ namespace ANSCENTER size_t vectorSize = passwordArray.size(); for (size_t i = 0; i < vectorSize; i++) { if (ExtractPasswordProtectedZip(modelZipFilePath, passwordArray[i], modelName, _modelFolder, false)) - break; // Break the loop when the condition is met. + break; // Break the loop when the condition is met. } // 2. Check if the outputFolder exist if (!std::filesystem::exists(_modelFolder)) { this->_logger.LogError("ANSFRBase::Initialize. Output model folder is not exist", _modelFolder, __FILE__, __LINE__); return false; // That means the model file is not exist or the password is not correct } + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSFRBase::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSFRBase::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // 3. Check if the model has the configuration file std::string modelConfigName = "model_config.json"; _modelConfigFile = CreateFilePath(_modelFolder, modelConfigName); diff --git a/modules/ANSODEngine/ANSMotionDetector.cpp b/modules/ANSODEngine/ANSMotionDetector.cpp index 3b20009..063c770 100644 --- a/modules/ANSODEngine/ANSMotionDetector.cpp +++ b/modules/ANSODEngine/ANSMotionDetector.cpp @@ -1953,6 +1953,15 @@ namespace ANSCENTER { bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSMOTIONDETECTOR::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSMOTIONDETECTOR::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _isInitialized = true; //_modelConfig.detectionScoreThreshold = 0.5; labelMap = "Movement"; @@ -1968,6 +1977,15 @@ namespace ANSCENTER { bool ANSMOTIONDETECTOR::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSMOTIONDETECTOR::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSMOTIONDETECTOR::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _isInitialized = true; labelMap = "Movement"; return true; diff --git a/modules/ANSODEngine/ANSODHUB.cpp b/modules/ANSODEngine/ANSODHUB.cpp index 7440da4..55fa526 100644 --- a/modules/ANSODEngine/ANSODHUB.cpp +++ b/modules/ANSODEngine/ANSODHUB.cpp @@ -25,6 +25,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ODHUBAPI::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ODHUBAPI::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // 0. Check weigth file std::string weightfile = CreateFilePath(_modelFolder, "train_last.weights"); if (FileExist(weightfile)) { @@ -82,6 +91,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ODHUBAPI::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ODHUBAPI::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; @@ -154,6 +172,15 @@ namespace ANSCENTER bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ODHUBAPI::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ODHUBAPI::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; diff --git a/modules/ANSODEngine/ANSONNXCL.cpp b/modules/ANSODEngine/ANSONNXCL.cpp index 7276dff..bad4e5c 100644 --- a/modules/ANSODEngine/ANSONNXCL.cpp +++ b/modules/ANSODEngine/ANSONNXCL.cpp @@ -882,6 +882,15 @@ namespace ANSCENTER _modelLoadValid = false; bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXCL::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXCL::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::CLASSIFICATION; @@ -943,6 +952,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXCL::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXCL::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::CLASSIFICATION; _modelConfig.modelType = ModelType::TENSORRT; _modelConfig.inpHeight = 224; @@ -999,6 +1017,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXCL::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXCL::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; diff --git a/modules/ANSODEngine/ANSONNXOBB.cpp b/modules/ANSODEngine/ANSONNXOBB.cpp index 9b79e05..e9fa659 100644 --- a/modules/ANSODEngine/ANSONNXOBB.cpp +++ b/modules/ANSODEngine/ANSONNXOBB.cpp @@ -1377,6 +1377,15 @@ namespace ANSCENTER { _modelLoadValid = false; bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXOBB::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXOBB::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; @@ -1438,6 +1447,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXOBB::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXOBB::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::CLASSIFICATION; _modelConfig.modelType = ModelType::TENSORRT; _modelConfig.inpHeight = 640; @@ -1494,6 +1512,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXOBB::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXOBB::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; diff --git a/modules/ANSODEngine/ANSONNXPOSE.cpp b/modules/ANSODEngine/ANSONNXPOSE.cpp index 5f2cbf3..9167844 100644 --- a/modules/ANSODEngine/ANSONNXPOSE.cpp +++ b/modules/ANSODEngine/ANSONNXPOSE.cpp @@ -1267,6 +1267,15 @@ namespace ANSCENTER { _modelLoadValid = false; bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXPOSE::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXPOSE::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; @@ -1329,6 +1338,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXPOSE::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXPOSE::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::CLASSIFICATION; _modelConfig.modelType = ModelType::TENSORRT; _modelConfig.inpHeight = 640; @@ -1386,6 +1404,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXPOSE::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXPOSE::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; diff --git a/modules/ANSODEngine/ANSONNXSAM3.cpp b/modules/ANSODEngine/ANSONNXSAM3.cpp index 6f5eda4..e7b3b5f 100644 --- a/modules/ANSODEngine/ANSONNXSAM3.cpp +++ b/modules/ANSODEngine/ANSONNXSAM3.cpp @@ -42,6 +42,15 @@ namespace ANSCENTER bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXSAM3::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXSAM3::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = DetectionType::SEGMENTATION; if (_modelConfig.modelConfThreshold < 0.1f) @@ -89,6 +98,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXSAM3::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXSAM3::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = DetectionType::SEGMENTATION; if (_modelConfig.modelConfThreshold < 0.1f) @@ -138,6 +156,15 @@ namespace ANSCENTER bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXSAM3::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXSAM3::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig = modelConfig; _modelConfig.detectionType = DetectionType::SEGMENTATION; diff --git a/modules/ANSODEngine/ANSONNXSEG.cpp b/modules/ANSODEngine/ANSONNXSEG.cpp index d1fce36..516f099 100644 --- a/modules/ANSODEngine/ANSONNXSEG.cpp +++ b/modules/ANSODEngine/ANSONNXSEG.cpp @@ -1158,6 +1158,15 @@ namespace ANSCENTER { _modelLoadValid = false; bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXSEG::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXSEG::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::SEGMENTATION; @@ -1220,6 +1229,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXSEG::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXSEG::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::SEGMENTATION; _modelConfig.modelType = ModelType::ONNXSEG; _modelConfig.inpHeight = 640; @@ -1277,6 +1295,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXSEG::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSONNXSEG::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; diff --git a/modules/ANSODEngine/ANSONNXYOLO.cpp b/modules/ANSODEngine/ANSONNXYOLO.cpp index d7ba175..3734fb0 100644 --- a/modules/ANSODEngine/ANSONNXYOLO.cpp +++ b/modules/ANSODEngine/ANSONNXYOLO.cpp @@ -1775,53 +1775,21 @@ namespace ANSCENTER { labelMap = VectorToCommaSeparatedString(_classes); if (this->_loadEngineOnCreation) { - // Hold the model-folder lock across session creation so a - // concurrent CreateANSODHandle on the same model cannot - // re-enter ExtractProtectedZipFile and truncate the .onnx - // file while ORT is opening it (which would surface as - // "system error number 13" EACCES from the ORT loader). - // - // Timed wait — 120s ceiling for extract + ORT session - // creation (GPU EP compile can take ~30s on large models). - // If we hit the timeout, the peer thread is deadlocked or - // wedged; fail the load instead of hanging the caller. - auto _folderLock = GetModelFolderLock(_modelFolder); - std::unique_lock _folderGuard( - *_folderLock, std::defer_lock); - ANS_DBG("ONNXYOLO", "Initialize: waiting on folder lock (120s): %s", - _modelFolder.c_str()); - auto _lockT0 = std::chrono::steady_clock::now(); - if (!_folderGuard.try_lock_for(std::chrono::seconds(120))) { - auto waitedMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _lockT0).count(); - ANS_DBG("ONNXYOLO", - "Initialize: TIMEOUT on folder lock after %lldms: %s", - (long long)waitedMs, _modelFolder.c_str()); + // Serialize session creation against concurrent extract re-entries + // on the same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXYOLO::Initialize"); + if (!_flg.acquired()) { _logger.LogError("ANSONNXYOLO::Initialize", "Timed out waiting for model-folder lock: " + _modelFolder, __FILE__, __LINE__); return false; } - auto waitedMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _lockT0).count(); - ANS_DBG("ONNXYOLO", "Initialize: folder lock acquired in %lldms, calling InitOrtEngine", - (long long)waitedMs); - auto _initT0 = std::chrono::steady_clock::now(); if (!InitOrtEngine()) { - auto initMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _initT0).count(); - ANS_DBG("ONNXYOLO", - "Initialize: InitOrtEngine FAILED after %lldms, model=%s", - (long long)initMs, _modelFilePath.c_str()); _logger.LogError("ANSONNXYOLO::Initialize", "Failed to create ONNX Runtime engine: " + _modelFilePath, __FILE__, __LINE__); return false; } - auto initMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _initT0).count(); - ANS_DBG("ONNXYOLO", "Initialize: InitOrtEngine OK in %lldms", - (long long)initMs); } // Fix input resolution for dynamic-shape models. @@ -1886,45 +1854,16 @@ namespace ANSCENTER { } if (this->_loadEngineOnCreation) { - // See ANSONNXYOLO::Initialize — hold folder lock so a sibling - // extraction cannot truncate train_last.onnx mid-load. Timed - // wait so a stuck peer cannot hang this thread forever. - auto _folderLock = GetModelFolderLock(_modelFolder); - std::unique_lock _folderGuard( - *_folderLock, std::defer_lock); - ANS_DBG("ONNXYOLO", "LoadModel: waiting on folder lock (120s): %s", - _modelFolder.c_str()); - auto _lockT0 = std::chrono::steady_clock::now(); - if (!_folderGuard.try_lock_for(std::chrono::seconds(120))) { - auto waitedMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _lockT0).count(); - ANS_DBG("ONNXYOLO", - "LoadModel: TIMEOUT on folder lock after %lldms: %s", - (long long)waitedMs, _modelFolder.c_str()); + // See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXYOLO::LoadModel"); + if (!_flg.acquired()) { _logger.LogError("ANSONNXYOLO::LoadModel", "Timed out waiting for model-folder lock: " + _modelFolder, __FILE__, __LINE__); _modelLoadValid = false; return false; } - auto waitedMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _lockT0).count(); - ANS_DBG("ONNXYOLO", "LoadModel: folder lock acquired in %lldms, calling InitOrtEngine", - (long long)waitedMs); - auto _initT0 = std::chrono::steady_clock::now(); - if (!InitOrtEngine()) { - auto initMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _initT0).count(); - ANS_DBG("ONNXYOLO", - "LoadModel: InitOrtEngine FAILED after %lldms, model=%s", - (long long)initMs, _modelFilePath.c_str()); - _modelLoadValid = false; - return false; - } - auto initMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _initT0).count(); - ANS_DBG("ONNXYOLO", "LoadModel: InitOrtEngine OK in %lldms", - (long long)initMs); + if (!InitOrtEngine()) { _modelLoadValid = false; return false; } } // Fix input resolution for dynamic-shape models (same as primary Initialize) @@ -1999,45 +1938,16 @@ namespace ANSCENTER { labelMap = VectorToCommaSeparatedString(_classes); if (this->_loadEngineOnCreation) { - // See ANSONNXYOLO::Initialize — hold folder lock so a sibling - // extraction cannot truncate the model file mid-load. Timed - // wait so a stuck peer cannot hang this thread forever. - auto _folderLock = GetModelFolderLock(_modelFolder); - std::unique_lock _folderGuard( - *_folderLock, std::defer_lock); - ANS_DBG("ONNXYOLO", "LoadModelFromFolder: waiting on folder lock (120s): %s", - _modelFolder.c_str()); - auto _lockT0 = std::chrono::steady_clock::now(); - if (!_folderGuard.try_lock_for(std::chrono::seconds(120))) { - auto waitedMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _lockT0).count(); - ANS_DBG("ONNXYOLO", - "LoadModelFromFolder: TIMEOUT on folder lock after %lldms: %s", - (long long)waitedMs, _modelFolder.c_str()); + // See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSONNXYOLO::LoadModelFromFolder"); + if (!_flg.acquired()) { _logger.LogError("ANSONNXYOLO::LoadModelFromFolder", "Timed out waiting for model-folder lock: " + _modelFolder, __FILE__, __LINE__); _modelLoadValid = false; return false; } - auto waitedMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _lockT0).count(); - ANS_DBG("ONNXYOLO", "LoadModelFromFolder: folder lock acquired in %lldms, calling InitOrtEngine", - (long long)waitedMs); - auto _initT0 = std::chrono::steady_clock::now(); - if (!InitOrtEngine()) { - auto initMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _initT0).count(); - ANS_DBG("ONNXYOLO", - "LoadModelFromFolder: InitOrtEngine FAILED after %lldms, model=%s", - (long long)initMs, _modelFilePath.c_str()); - _modelLoadValid = false; - return false; - } - auto initMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - _initT0).count(); - ANS_DBG("ONNXYOLO", "LoadModelFromFolder: InitOrtEngine OK in %lldms", - (long long)initMs); + if (!InitOrtEngine()) { _modelLoadValid = false; return false; } } // Fix input resolution for dynamic-shape models (same as primary Initialize) diff --git a/modules/ANSODEngine/ANSOPENVINOCL.cpp b/modules/ANSODEngine/ANSOPENVINOCL.cpp index a491f9f..84b481e 100644 --- a/modules/ANSODEngine/ANSOPENVINOCL.cpp +++ b/modules/ANSODEngine/ANSOPENVINOCL.cpp @@ -36,6 +36,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "OPENVINOCL::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("OPENVINOCL::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // 0. Check if the configuration file exist if (FileExist(_modelConfigFile)) { ModelType modelType; @@ -84,6 +93,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "OPENVINOCL::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("OPENVINOCL::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; @@ -182,6 +200,15 @@ namespace ANSCENTER //this->_logger.LogDebug("OPENVINOCL::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__); bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "OPENVINOCL::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("OPENVINOCL::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::CLASSIFICATION; diff --git a/modules/ANSODEngine/ANSOPENVINOOD.cpp b/modules/ANSODEngine/ANSOPENVINOOD.cpp index c2b4000..d778947 100644 --- a/modules/ANSODEngine/ANSOPENVINOOD.cpp +++ b/modules/ANSODEngine/ANSOPENVINOOD.cpp @@ -36,6 +36,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "OPENVINOOD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("OPENVINOOD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // 0. Check if the configuration file exist if (FileExist(_modelConfigFile)) { ModelType modelType; @@ -85,6 +94,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "OPENVINOOD::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("OPENVINOOD::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; @@ -187,6 +205,15 @@ namespace ANSCENTER try { bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "OPENVINOOD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("OPENVINOOD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; diff --git a/modules/ANSODEngine/ANSOVFBFaceDetector.cpp b/modules/ANSODEngine/ANSOVFBFaceDetector.cpp index 09e4ce1..4fefd39 100644 --- a/modules/ANSODEngine/ANSOVFBFaceDetector.cpp +++ b/modules/ANSODEngine/ANSOVFBFaceDetector.cpp @@ -7,8 +7,17 @@ namespace ANSCENTER { bool ANSOVFBFD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) { bool result = ANSFDBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOVFBFD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOVFBFD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } labelMap = "Face"; - // We do not need to check for the license + // We do not need to check for the license _licenseValid = true; if (!_licenseValid) return false; try { @@ -70,6 +79,15 @@ namespace ANSCENTER { // We need to get the _modelFolder bool result = ANSFDBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOVFBFD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOVFBFD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // We need to get the modelfolder from here std::string xmlfile = CreateFilePath(_modelFolder, "ansovfb.xml"); if (std::filesystem::exists(xmlfile)) { diff --git a/modules/ANSODEngine/ANSOVFaceDetector.cpp b/modules/ANSODEngine/ANSOVFaceDetector.cpp index d43190c..f5e1843 100644 --- a/modules/ANSODEngine/ANSOVFaceDetector.cpp +++ b/modules/ANSODEngine/ANSOVFaceDetector.cpp @@ -11,6 +11,15 @@ namespace ANSCENTER { bool ANSOVFD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) { bool result = ANSFDBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOVFD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOVFD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } labelMap = "Face"; _licenseValid = true; std::vector labels{ labelMap }; @@ -47,6 +56,15 @@ namespace ANSCENTER { // We need to get the _modelFolder bool result = ANSFDBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOVFD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOVFD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string onnxModel = CreateFilePath(_modelFolder, "scrfd.onnx"); //this->_face_detector = std::make_unique(onnxModel); _isInitialized = true; @@ -62,6 +80,15 @@ namespace ANSCENTER { try { bool result = ANSFDBase::LoadModelFromFolder(licenseKey, modelConfig,modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOVFD::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOVFD::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "scrfd"; diff --git a/modules/ANSODEngine/ANSOVSEG.cpp b/modules/ANSODEngine/ANSOVSEG.cpp index 969e473..3465524 100644 --- a/modules/ANSODEngine/ANSOVSEG.cpp +++ b/modules/ANSODEngine/ANSOVSEG.cpp @@ -34,6 +34,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOVSEG::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOVSEG::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // 0. Check if the configuration file exist if (FileExist(_modelConfigFile)) { ModelType modelType; @@ -83,6 +92,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOVSEG::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOVSEG::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; @@ -152,6 +170,15 @@ namespace ANSCENTER { this->_logger.LogDebug("ANSOVSEG::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__); bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOVSEG::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOVSEG::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::SEGMENTATION; diff --git a/modules/ANSODEngine/ANSPOSE.cpp b/modules/ANSODEngine/ANSPOSE.cpp index 05a3c5a..aeef2bd 100644 --- a/modules/ANSODEngine/ANSPOSE.cpp +++ b/modules/ANSODEngine/ANSPOSE.cpp @@ -37,6 +37,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSPOSE::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSPOSE::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _device = GetOpenVINODevice(_core); // 0. Check if the configuration file exist if (FileExist(_modelConfigFile)) { @@ -81,6 +90,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSPOSE::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSPOSE::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "ansposesetimation"; @@ -145,6 +163,15 @@ namespace ANSCENTER { this->_logger.LogDebug("ANSPOSE::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__); bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSPOSE::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSPOSE::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for ABNORMAL only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::KEYPOINT; diff --git a/modules/ANSODEngine/ANSRTYOLO.cpp b/modules/ANSODEngine/ANSRTYOLO.cpp index 7ccb552..85b5084 100644 --- a/modules/ANSODEngine/ANSRTYOLO.cpp +++ b/modules/ANSODEngine/ANSRTYOLO.cpp @@ -63,6 +63,15 @@ namespace ANSCENTER { _isFixedBatch = false; bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSRTYOLO::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSRTYOLO::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.modelType = ModelType::TENSORRT; if (_modelConfig.inpHeight <= 0) _modelConfig.inpHeight = 640; @@ -155,6 +164,15 @@ namespace ANSCENTER { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSRTYOLO::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSRTYOLO::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig = modelConfig; _modelConfig.modelType = ModelType::TENSORRT; @@ -260,6 +278,15 @@ namespace ANSCENTER { bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSRTYOLO::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSRTYOLO::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig = modelConfig; _modelConfig.modelType = ModelType::TENSORRT; diff --git a/modules/ANSODEngine/ANSSAM.cpp b/modules/ANSODEngine/ANSSAM.cpp index e69a2cb..57489dd 100644 --- a/modules/ANSODEngine/ANSSAM.cpp +++ b/modules/ANSODEngine/ANSSAM.cpp @@ -39,6 +39,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSSAM::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSSAM::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string xmlfile = CreateFilePath(_modelFolder, "anssam.xml"); std::string binaryfile = CreateFilePath(_modelFolder, "anssam.bin"); if (std::filesystem::exists(xmlfile)) { @@ -72,6 +81,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSSAM::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSSAM::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "anssam"; @@ -114,6 +132,15 @@ namespace ANSCENTER { _modelConfig = modelConfig; bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSSAM::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSSAM::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string xmlfile = CreateFilePath(_modelFolder, "anssam.xml"); std::string binaryfile = CreateFilePath(_modelFolder, "anssam.bin"); if (std::filesystem::exists(xmlfile)) { diff --git a/modules/ANSODEngine/ANSSAM3.cpp b/modules/ANSODEngine/ANSSAM3.cpp index 1a75980..38898e2 100644 --- a/modules/ANSODEngine/ANSSAM3.cpp +++ b/modules/ANSODEngine/ANSSAM3.cpp @@ -691,6 +691,15 @@ namespace ANSCENTER try { bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSSAM3::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSSAM3::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = DetectionType::SEGMENTATION; if (_modelConfig.modelConfThreshold < 0.1f) @@ -751,6 +760,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSSAM3::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSSAM3::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = DetectionType::SEGMENTATION; if (_modelConfig.modelConfThreshold < 0.1f) @@ -809,6 +827,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSSAM3::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSSAM3::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig = modelConfig; _modelConfig.detectionType = DetectionType::SEGMENTATION; diff --git a/modules/ANSODEngine/ANSTENSORRTCL.cpp b/modules/ANSODEngine/ANSTENSORRTCL.cpp index 7c725cf..582b4de 100644 --- a/modules/ANSODEngine/ANSTENSORRTCL.cpp +++ b/modules/ANSODEngine/ANSTENSORRTCL.cpp @@ -62,6 +62,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "TENSORRTCL::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("TENSORRTCL::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::CLASSIFICATION; _modelConfig.modelType = ModelType::TENSORRT; _modelConfig.inpHeight = 224; @@ -157,6 +166,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "TENSORRTCL::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("TENSORRTCL::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; @@ -263,6 +281,15 @@ namespace ANSCENTER try { bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "TENSORRTCL::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("TENSORRTCL::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::CLASSIFICATION; diff --git a/modules/ANSODEngine/ANSTENSORRTPOSE.cpp b/modules/ANSODEngine/ANSTENSORRTPOSE.cpp index 1aab86f..7f86336 100644 --- a/modules/ANSODEngine/ANSTENSORRTPOSE.cpp +++ b/modules/ANSODEngine/ANSTENSORRTPOSE.cpp @@ -59,6 +59,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSTENSORRTPOSE::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSTENSORRTPOSE::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; _modelConfig.modelType = ModelType::TENSORRT; _modelConfig.inpHeight = 640; @@ -150,6 +159,15 @@ namespace ANSCENTER { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSTENSORRTPOSE::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSTENSORRTPOSE::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; _modelConfig.modelType = ModelType::RTPOSE; @@ -253,6 +271,15 @@ namespace ANSCENTER _modelLoadValid = false; bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSTENSORRTPOSE::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSTENSORRTPOSE::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; diff --git a/modules/ANSODEngine/ANSTENSORRTSEG.cpp b/modules/ANSODEngine/ANSTENSORRTSEG.cpp index dd4b3a6..31a424b 100644 --- a/modules/ANSODEngine/ANSTENSORRTSEG.cpp +++ b/modules/ANSODEngine/ANSTENSORRTSEG.cpp @@ -59,6 +59,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "TENSORRTSEG::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("TENSORRTSEG::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::SEGMENTATION; _modelConfig.modelType = ModelType::RTSEG; _modelConfig.inpHeight = 640; @@ -150,6 +159,15 @@ namespace ANSCENTER { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "TENSORRTSEG::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("TENSORRTSEG::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::SEGMENTATION; _modelConfig.modelType = ModelType::RTSEG; @@ -253,6 +271,15 @@ namespace ANSCENTER _modelLoadValid = false; bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "TENSORRTSEG::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("TENSORRTSEG::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::SEGMENTATION; diff --git a/modules/ANSODEngine/ANSTENSORTRTOD.cpp b/modules/ANSODEngine/ANSTENSORTRTOD.cpp index ae248e3..1ddb354 100644 --- a/modules/ANSODEngine/ANSTENSORTRTOD.cpp +++ b/modules/ANSODEngine/ANSTENSORTRTOD.cpp @@ -63,6 +63,15 @@ namespace ANSCENTER _isFixedBatch = false; bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "TENSORRTOD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("TENSORRTOD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; _modelConfig.modelType = ModelType::TENSORRT; _modelConfig.inpHeight = 640; @@ -158,6 +167,15 @@ namespace ANSCENTER _isFixedBatch = false; bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "TENSORRTOD::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("TENSORRTOD::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; _modelConfig.modelType = ModelType::TENSORRT; @@ -265,6 +283,15 @@ namespace ANSCENTER _isFixedBatch = false; bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "TENSORRTOD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("TENSORRTOD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; diff --git a/modules/ANSODEngine/ANSYOLO12OD.cpp b/modules/ANSODEngine/ANSYOLO12OD.cpp index e9e7829..f73ac18 100644 --- a/modules/ANSODEngine/ANSYOLO12OD.cpp +++ b/modules/ANSODEngine/ANSYOLO12OD.cpp @@ -28,6 +28,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "YOLO12OD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("YOLO12OD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; _modelConfig.inpHeight = 640; _modelConfig.inpWidth = 640; @@ -87,6 +96,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className,modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "YOLO12OD::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("YOLO12OD::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; @@ -160,6 +178,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "YOLO12OD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("YOLO12OD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; diff --git a/modules/ANSODEngine/ANSYOLOOD.cpp b/modules/ANSODEngine/ANSYOLOOD.cpp index bcb502d..d51dd57 100644 --- a/modules/ANSODEngine/ANSYOLOOD.cpp +++ b/modules/ANSODEngine/ANSYOLOOD.cpp @@ -949,6 +949,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "YOLOOD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("YOLOOD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; _modelConfig.inpHeight = 640; _modelConfig.inpWidth = 640; @@ -1042,6 +1051,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "YOLOOD::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("YOLOOD::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; @@ -1165,6 +1183,15 @@ namespace ANSCENTER try { bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "YOLOOD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("YOLOOD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; diff --git a/modules/ANSODEngine/ANSYOLOV10OVOD.cpp b/modules/ANSODEngine/ANSYOLOV10OVOD.cpp index ec06b80..0c82f4f 100644 --- a/modules/ANSODEngine/ANSYOLOV10OVOD.cpp +++ b/modules/ANSODEngine/ANSYOLOV10OVOD.cpp @@ -37,6 +37,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOYOLOV10OVOD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOYOLOV10OVOD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; _modelConfig.modelType = ModelType::OPENVINO; _modelConfig.inpHeight = 640; @@ -93,6 +102,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,modelName, className,modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOYOLOV10OVOD::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOYOLOV10OVOD::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; @@ -166,6 +184,15 @@ namespace ANSCENTER //this->_logger.LogDebug("ANSOYOLOV10OVOD::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__); bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOYOLOV10OVOD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOYOLOV10OVOD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; diff --git a/modules/ANSODEngine/ANSYOLOV10RTOD.cpp b/modules/ANSODEngine/ANSYOLOV10RTOD.cpp index b474e97..05fc0f0 100644 --- a/modules/ANSODEngine/ANSYOLOV10RTOD.cpp +++ b/modules/ANSODEngine/ANSYOLOV10RTOD.cpp @@ -60,6 +60,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSYOLOV10RTOD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSYOLOV10RTOD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; _modelConfig.modelType = ModelType::TENSORRT; _modelConfig.inpHeight = 640; @@ -159,6 +168,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSYOLOV10RTOD::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSYOLOV10RTOD::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; @@ -268,6 +286,15 @@ namespace ANSCENTER _modelLoadValid = false; bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSYOLOV10RTOD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSYOLOV10RTOD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; diff --git a/modules/ANSODEngine/ANSYOLOV12RTOD.cpp b/modules/ANSODEngine/ANSYOLOV12RTOD.cpp index 012f864..ab300a9 100644 --- a/modules/ANSODEngine/ANSYOLOV12RTOD.cpp +++ b/modules/ANSODEngine/ANSYOLOV12RTOD.cpp @@ -59,6 +59,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSYOLOV12RTOD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSYOLOV12RTOD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; _modelConfig.modelType = ModelType::TENSORRT; _modelConfig.inpHeight = 640; @@ -152,6 +161,15 @@ namespace ANSCENTER try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,modelName, className,modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSYOLOV12RTOD::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSYOLOV12RTOD::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "train_last"; @@ -256,6 +274,15 @@ namespace ANSCENTER _modelLoadValid = false; bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSYOLOV12RTOD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSYOLOV12RTOD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // Parsing for YOLO only here _modelConfig = modelConfig; _modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION; diff --git a/modules/ANSODEngine/Movienet.cpp b/modules/ANSODEngine/Movienet.cpp index eb4a554..b5cd008 100644 --- a/modules/ANSODEngine/Movienet.cpp +++ b/modules/ANSODEngine/Movienet.cpp @@ -114,6 +114,15 @@ namespace ANSCENTER { bool ANSMOVIENET::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) { bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSMOVIENET::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSMOVIENET::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } labelMap = "Face"; _licenseValid = true; std::vector labels{ labelMap }; @@ -152,6 +161,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSMOVIENET::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSMOVIENET::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } int detectedW = 0, detectedH = 0; std::string onnxModel = ResolveMovinetModel(_modelFolder, detectedW, detectedH); @@ -174,6 +192,15 @@ namespace ANSCENTER { try { bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSMOVIENET::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSMOVIENET::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } _modelConfig = modelConfig; _modelConfig.modelType = ModelType::MOVIENET; diff --git a/modules/ANSODEngine/RetinaFaceDetector.cpp b/modules/ANSODEngine/RetinaFaceDetector.cpp index 3dadc15..af1ec04 100644 --- a/modules/ANSODEngine/RetinaFaceDetector.cpp +++ b/modules/ANSODEngine/RetinaFaceDetector.cpp @@ -3,7 +3,16 @@ namespace ANSCENTER { bool ANSRETINAFD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) { bool result = ANSFDBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); - // We do not need to check for the license + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSRETINAFD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSRETINAFD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } + // We do not need to check for the license _licenseValid = true; if (!_licenseValid) return false; try { @@ -61,6 +70,15 @@ namespace ANSCENTER { // We need to get the _modelFolder bool result = ANSFDBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSRETINAFD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSRETINAFD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // We need to get the modelfolder from here std::string onnxfile = CreateFilePath(_modelFolder, "retinaface.onnx"); diff --git a/modules/ANSODEngine/SCRFDFaceDetector.cpp b/modules/ANSODEngine/SCRFDFaceDetector.cpp index 53617ed..5c36041 100644 --- a/modules/ANSODEngine/SCRFDFaceDetector.cpp +++ b/modules/ANSODEngine/SCRFDFaceDetector.cpp @@ -14,6 +14,15 @@ namespace ANSCENTER { // Call base class Initialize bool result = ANSFDBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSSCRFDFD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSSCRFDFD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } labelMap = "Face"; _licenseValid = true; try { @@ -75,6 +84,15 @@ namespace ANSCENTER { // We need to get the _modelFolder bool result = ANSFDBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSSCRFDFD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSSCRFDFD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } const bool engineAlreadyLoaded = _isInitialized && m_trtEngine != nullptr; _modelConfig.modelType = ModelType::FACEDETECT; _modelConfig.detectionType = DetectionType::FACEDETECTOR; @@ -133,6 +151,15 @@ namespace ANSCENTER { // We need to get the _modelFolder bool result = ANSFDBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSSCRFDFD::LoadModelFromFolder"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSSCRFDFD::LoadModelFromFolder", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } std::string _modelName = modelName; if (_modelName.empty()) { _modelName = "scrfdface"; diff --git a/modules/ANSODEngine/SCRFDOVFaceDetector.cpp b/modules/ANSODEngine/SCRFDOVFaceDetector.cpp index 7480bb7..737302e 100644 --- a/modules/ANSODEngine/SCRFDOVFaceDetector.cpp +++ b/modules/ANSODEngine/SCRFDOVFaceDetector.cpp @@ -5,8 +5,17 @@ namespace ANSCENTER { bool ANSOVSCRFDFD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) { bool result = ANSFDBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOVSCRFDFD::Initialize"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOVSCRFDFD::Initialize", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } labelMap = "Face"; - // We do not need to check for the license + // We do not need to check for the license _licenseValid = true; if (!_licenseValid) return false; try { @@ -101,6 +110,15 @@ namespace ANSCENTER { // We need to get the _modelFolder bool result = ANSFDBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; + // Serialize derived init against concurrent extract re-entries on the + // same folder. See ModelFolderLockGuard in ANSEngineCommon.h. + ModelFolderLockGuard _flg(_modelFolder, "ANSOVSCRFDFD::LoadModel"); + if (!_flg.acquired()) { + this->_logger.LogError("ANSOVSCRFDFD::LoadModel", + "Timed out waiting for model-folder lock: " + _modelFolder, + __FILE__, __LINE__); + return false; + } // We need to get the modelfolder from here std::string xmlfile = CreateFilePath(_modelFolder, "scrfdface.xml");