- Remove ALPR_OD Tracker and voting system.
- Disable debugview
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
#include <mutex>
|
||||
#include <cstdint>
|
||||
|
||||
// DebugView: filter on "[ANSMOT]" — gated by ANSCORE_DEBUGVIEW in ANSLicense.h.
|
||||
|
||||
// Handle registry with refcount — prevents use-after-free when
|
||||
// ReleaseANSMOTHandle is called while an operation is still running.
|
||||
// destructionStarted: set by the first Unregister caller; blocks new Acquires
|
||||
@@ -33,14 +35,30 @@ static std::condition_variable& MOTHandleRegistryCV() {
|
||||
static void RegisterMOTHandle(ANSCENTER::ANSMOT* h) {
|
||||
std::lock_guard<std::mutex> lk(MOTHandleRegistryMutex());
|
||||
MOTHandleRegistry()[h] = { 1, false };
|
||||
ANS_DBG("ANSMOT","Register: handle=%p (uint=%llu) registrySize=%zu",
|
||||
(void*)h, (unsigned long long)(uintptr_t)h, MOTHandleRegistry().size());
|
||||
}
|
||||
|
||||
static ANSCENTER::ANSMOT* AcquireMOTHandle(ANSCENTER::ANSMOT* h) {
|
||||
std::lock_guard<std::mutex> lk(MOTHandleRegistryMutex());
|
||||
auto it = MOTHandleRegistry().find(h);
|
||||
if (it == MOTHandleRegistry().end()) return nullptr;
|
||||
if (it->second.destructionStarted) return nullptr;
|
||||
if (it == MOTHandleRegistry().end()) {
|
||||
ANS_DBG("ANSMOT","Acquire FAIL: handle=%p (uint=%llu) NOT in registry. registrySize=%zu",
|
||||
(void*)h, (unsigned long long)(uintptr_t)h, MOTHandleRegistry().size());
|
||||
size_t i = 0;
|
||||
for (auto& kv : MOTHandleRegistry()) {
|
||||
ANS_DBG("ANSMOT"," registry[%zu] = %p (uint=%llu) refcount=%d destructionStarted=%d",
|
||||
i++, (void*)kv.first, (unsigned long long)(uintptr_t)kv.first,
|
||||
kv.second.refcount, kv.second.destructionStarted ? 1 : 0);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
if (it->second.destructionStarted) {
|
||||
ANS_DBG("ANSMOT","Acquire FAIL: handle=%p is being destroyed (destructionStarted=true)", (void*)h);
|
||||
return nullptr;
|
||||
}
|
||||
it->second.refcount++;
|
||||
ANS_DBG("ANSMOT","Acquire OK: handle=%p refcount=%d", (void*)h, it->second.refcount);
|
||||
return h;
|
||||
}
|
||||
|
||||
@@ -58,10 +76,15 @@ static bool ReleaseMOTHandleRef(ANSCENTER::ANSMOT* h) {
|
||||
static bool UnregisterMOTHandle(ANSCENTER::ANSMOT* h) {
|
||||
std::unique_lock<std::mutex> lk(MOTHandleRegistryMutex());
|
||||
auto it = MOTHandleRegistry().find(h);
|
||||
if (it == MOTHandleRegistry().end()) return false;
|
||||
if (it == MOTHandleRegistry().end()) {
|
||||
ANS_DBG("ANSMOT","Unregister: handle=%p NOT in registry (already gone)", (void*)h);
|
||||
return false;
|
||||
}
|
||||
if (it->second.destructionStarted) {
|
||||
ANS_DBG("ANSMOT","Unregister: handle=%p already being destroyed by another thread, returning false", (void*)h);
|
||||
return false; // Another thread already owns the delete.
|
||||
}
|
||||
ANS_DBG("ANSMOT","Unregister: handle=%p starting (refcount before=%d)", (void*)h, it->second.refcount);
|
||||
it->second.destructionStarted = true;
|
||||
it->second.refcount--;
|
||||
bool ok = MOTHandleRegistryCV().wait_for(lk, std::chrono::seconds(30), [&]() {
|
||||
@@ -69,6 +92,7 @@ static bool UnregisterMOTHandle(ANSCENTER::ANSMOT* h) {
|
||||
return it2 == MOTHandleRegistry().end() || it2->second.refcount <= 0;
|
||||
});
|
||||
if (!ok) {
|
||||
ANS_DBG("ANSMOT","WARNING: Unregister timed out waiting for in-flight operations on handle=%p", (void*)h);
|
||||
OutputDebugStringA("WARNING: UnregisterMOTHandle timed out waiting for in-flight operations\n");
|
||||
}
|
||||
MOTHandleRegistry().erase(h);
|
||||
@@ -111,7 +135,9 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
};
|
||||
*/
|
||||
extern "C" __declspec(dllexport) int __cdecl CreateANSMOTHandle(ANSCENTER::ANSMOT **Handle, int motType) {
|
||||
if (Handle == nullptr) return 0;
|
||||
ANS_DBG("ANSMOT","CreateANSMOTHandle: HandlePtr=%p, *Handle(in)=%p, motType=%d",
|
||||
(void*)Handle, (void*)(Handle ? *Handle : nullptr), motType);
|
||||
if (Handle == nullptr) { ANS_DBG("ANSMOT","Create FAIL: Handle is null"); return 0; }
|
||||
try {
|
||||
// Pure constructor: ignore *Handle(in). LabVIEW's CLF Node marshalling
|
||||
// reuses the same temp buffer per call site, so *Handle(in) often holds
|
||||
@@ -144,49 +170,70 @@ extern "C" __declspec(dllexport) int __cdecl CreateANSMOTHandle(ANSCENTER::
|
||||
break;
|
||||
}
|
||||
if (*Handle == nullptr) {
|
||||
ANS_DBG("ANSMOT","Create FAIL: new returned null");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
ANS_DBG("ANSMOT","Create: allocated handle=%p (uint=%llu), calling Register...",
|
||||
(void*)*Handle, (unsigned long long)(uintptr_t)*Handle);
|
||||
RegisterMOTHandle(*Handle);
|
||||
ANS_DBG("ANSMOT","Create OK: handle=%p (uint=%llu)", (void*)*Handle, (unsigned long long)(uintptr_t)*Handle);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
ANS_DBG("ANSMOT","Create EXCEPTION (std::exception): %s", e.what());
|
||||
return 0;
|
||||
}
|
||||
catch (...) {
|
||||
ANS_DBG("ANSMOT","Create EXCEPTION (unknown)");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static int ReleaseANSMOTHandle_Impl(ANSCENTER::ANSMOT** Handle) {
|
||||
try {
|
||||
if (!Handle || !*Handle) return 1;
|
||||
if (!UnregisterMOTHandle(*Handle)) {
|
||||
if (!Handle || !*Handle) {
|
||||
ANS_DBG("ANSMOT","Release: HandlePtr or *Handle is null, no-op");
|
||||
return 1;
|
||||
}
|
||||
ANSCENTER::ANSMOT* h = *Handle;
|
||||
ANS_DBG("ANSMOT","Release called: handle=%p (uint=%llu)", (void*)h, (unsigned long long)(uintptr_t)h);
|
||||
if (!UnregisterMOTHandle(h)) {
|
||||
ANS_DBG("ANSMOT","Release: Unregister returned false (already gone or being destroyed by another thread), handle=%p", (void*)h);
|
||||
*Handle = nullptr;
|
||||
return 1;
|
||||
}
|
||||
(*Handle)->Destroy();
|
||||
delete *Handle;
|
||||
h->Destroy();
|
||||
delete h;
|
||||
*Handle = nullptr;
|
||||
ANS_DBG("ANSMOT","Release OK: handle=%p deleted, registry now has %zu entries",
|
||||
(void*)h, MOTHandleRegistry().size());
|
||||
return 1;
|
||||
}
|
||||
catch (...) {
|
||||
ANS_DBG("ANSMOT","Release EXCEPTION (unknown)");
|
||||
if (Handle) *Handle = nullptr;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) int __cdecl ReleaseANSMOTHandle(ANSCENTER::ANSMOT **Handle) {
|
||||
ANS_DBG("ANSMOT","ReleaseANSMOTHandle: HandlePtr=%p, *Handle=%p",
|
||||
(void*)Handle, (void*)(Handle ? *Handle : nullptr));
|
||||
__try {
|
||||
return ReleaseANSMOTHandle_Impl(Handle);
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
ANS_DBG("ANSMOT","ReleaseANSMOTHandle: SEH exception caught");
|
||||
if (Handle) *Handle = nullptr;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) int __cdecl UpdateANSMOTParameters(ANSCENTER::ANSMOT * *Handle, const char* trackerParameter) {
|
||||
ANS_DBG("ANSMOT","UpdateANSMOTParameters: HandlePtr=%p, *Handle=%p, trackerParameter=%s",
|
||||
(void*)Handle, (void*)(Handle ? *Handle : nullptr),
|
||||
trackerParameter ? trackerParameter : "(null)");
|
||||
if (Handle == nullptr || *Handle == nullptr) return -1;
|
||||
MOTHandleGuard guard(AcquireMOTHandle(*Handle));
|
||||
if (!guard) return -1;
|
||||
@@ -204,6 +251,8 @@ extern "C" __declspec(dllexport) int __cdecl UpdateANSMOTParameters(ANSCENTE
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) int __cdecl UpdateANSMOT(ANSCENTER::ANSMOT * *Handle, int modelId, const char* detectionData, std::string & result) {
|
||||
ANS_DBG("ANSMOT","UpdateANSMOT: HandlePtr=%p, *Handle=%p, modelId=%d",
|
||||
(void*)Handle, (void*)(Handle ? *Handle : nullptr), modelId);
|
||||
if (Handle == nullptr || *Handle == nullptr) return -1;
|
||||
MOTHandleGuard guard(AcquireMOTHandle(*Handle));
|
||||
if (!guard) return -1;
|
||||
@@ -220,6 +269,8 @@ extern "C" __declspec(dllexport) int __cdecl UpdateANSMOT(ANSCENTER::ANSMOT * *H
|
||||
}
|
||||
}
|
||||
extern "C" __declspec(dllexport) int __cdecl UpdateANSMOT_LV(ANSCENTER::ANSMOT * *Handle, int modelId, const char* detectionData, LStrHandle trackerResult) {
|
||||
ANS_DBG("ANSMOT","UpdateANSMOT_LV: HandlePtr=%p, *Handle=%p, modelId=%d",
|
||||
(void*)Handle, (void*)(Handle ? *Handle : nullptr), modelId);
|
||||
if (Handle == nullptr || *Handle == nullptr) return -1;
|
||||
MOTHandleGuard guard(AcquireMOTHandle(*Handle));
|
||||
if (!guard) return -1;
|
||||
@@ -246,6 +297,8 @@ extern "C" __declspec(dllexport) int __cdecl UpdateANSMOT_LV(ANSCENTE
|
||||
|
||||
extern "C" __declspec(dllexport) int __cdecl UpdateANSMOTTracker(ANSCENTER::ANSMOT** Handle, int modelId, const std::vector<ANSCENTER::TrackerObject>& detectionObjects, std::vector<ANSCENTER::TrackerObject>& trackedObjects)
|
||||
{
|
||||
ANS_DBG("ANSMOT","UpdateANSMOTTracker: HandlePtr=%p, *Handle=%p, modelId=%d, detectionObjects.size=%zu",
|
||||
(void*)Handle, (void*)(Handle ? *Handle : nullptr), modelId, detectionObjects.size());
|
||||
if (Handle == nullptr || *Handle == nullptr) return -1;
|
||||
MOTHandleGuard guard(AcquireMOTHandle(*Handle));
|
||||
if (!guard) return -1;
|
||||
@@ -271,6 +324,8 @@ extern "C" __declspec(dllexport) int __cdecl UpdateANSMOTTracker(ANSC
|
||||
|
||||
extern "C" __declspec(dllexport) int __cdecl UpdateANSMOT_LV_V2(uint64_t handleVal, int modelId, const char* detectionData, LStrHandle trackerResult) {
|
||||
ANSCENTER::ANSMOT* directHandle = reinterpret_cast<ANSCENTER::ANSMOT*>(handleVal);
|
||||
ANS_DBG("ANSMOT","UpdateANSMOT_LV_V2: handleVal=%llu handle=%p, modelId=%d",
|
||||
(unsigned long long)handleVal, (void*)directHandle, modelId);
|
||||
if (directHandle == nullptr) return -1;
|
||||
MOTHandleGuard guard(AcquireMOTHandle(directHandle));
|
||||
if (!guard) return -1;
|
||||
|
||||
Reference in New Issue
Block a user