Fix unregister issue
This commit is contained in:
@@ -28,8 +28,12 @@ std::atomic<bool> g_forceNoPool{false};
|
||||
|
||||
// Handle registry with refcount — prevents use-after-free when
|
||||
// ReleaseANSRFHandle is called while inference is still running.
|
||||
static std::unordered_map<ANSCENTER::ANSFacialRecognition*, int>& FRHandleRegistry() {
|
||||
static std::unordered_map<ANSCENTER::ANSFacialRecognition*, int> s;
|
||||
// destructionStarted: set by the first Unregister caller; blocks new Acquires
|
||||
// and makes subsequent Unregister calls return false without deleting.
|
||||
// Prevents double-free when Release is raced on the same handle.
|
||||
struct FREntry { int refcount; bool destructionStarted; };
|
||||
static std::unordered_map<ANSCENTER::ANSFacialRecognition*, FREntry>& FRHandleRegistry() {
|
||||
static std::unordered_map<ANSCENTER::ANSFacialRecognition*, FREntry> s;
|
||||
return s;
|
||||
}
|
||||
static std::mutex& FRHandleRegistryMutex() {
|
||||
@@ -43,14 +47,15 @@ static std::condition_variable& FRHandleRegistryCV() {
|
||||
|
||||
static void RegisterFRHandle(ANSCENTER::ANSFacialRecognition* h) {
|
||||
std::lock_guard<std::mutex> lk(FRHandleRegistryMutex());
|
||||
FRHandleRegistry()[h] = 1;
|
||||
FRHandleRegistry()[h] = { 1, false };
|
||||
}
|
||||
|
||||
static ANSCENTER::ANSFacialRecognition* AcquireFRHandle(ANSCENTER::ANSFacialRecognition* h) {
|
||||
std::lock_guard<std::mutex> lk(FRHandleRegistryMutex());
|
||||
auto it = FRHandleRegistry().find(h);
|
||||
if (it == FRHandleRegistry().end()) return nullptr;
|
||||
it->second++;
|
||||
if (it->second.destructionStarted) return nullptr;
|
||||
it->second.refcount++;
|
||||
return h;
|
||||
}
|
||||
|
||||
@@ -58,23 +63,25 @@ static bool ReleaseFRHandleRef(ANSCENTER::ANSFacialRecognition* h) {
|
||||
std::lock_guard<std::mutex> lk(FRHandleRegistryMutex());
|
||||
auto it = FRHandleRegistry().find(h);
|
||||
if (it == FRHandleRegistry().end()) return false;
|
||||
it->second--;
|
||||
if (it->second <= 0) {
|
||||
FRHandleRegistry().erase(it);
|
||||
it->second.refcount--;
|
||||
if (it->second.refcount <= 0) {
|
||||
FRHandleRegistryCV().notify_all();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return false; // Only Unregister deletes.
|
||||
}
|
||||
|
||||
static bool UnregisterFRHandle(ANSCENTER::ANSFacialRecognition* h) {
|
||||
std::unique_lock<std::mutex> lk(FRHandleRegistryMutex());
|
||||
auto it = FRHandleRegistry().find(h);
|
||||
if (it == FRHandleRegistry().end()) return false;
|
||||
it->second--;
|
||||
if (it->second.destructionStarted) {
|
||||
return false; // Another thread already owns the delete.
|
||||
}
|
||||
it->second.destructionStarted = true;
|
||||
it->second.refcount--;
|
||||
bool ok = FRHandleRegistryCV().wait_for(lk, std::chrono::seconds(30), [&]() {
|
||||
auto it2 = FRHandleRegistry().find(h);
|
||||
return it2 == FRHandleRegistry().end() || it2->second <= 0;
|
||||
return it2 == FRHandleRegistry().end() || it2->second.refcount <= 0;
|
||||
});
|
||||
if (!ok) {
|
||||
OutputDebugStringA("WARNING: UnregisterFRHandle timed out waiting for in-flight inference\n");
|
||||
|
||||
Reference in New Issue
Block a user