Fix: remove the leak protection entirely
This commit is contained in:
@@ -250,14 +250,15 @@ extern "C" ANSFR_API int CreateANSRFHandle(ANSCENTER::ANSFacialRecognition**
|
|||||||
std::cout << buf;
|
std::cout << buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release existing handle if called twice (prevents leak from LabVIEW)
|
// Pure constructor: ignore *Handle(in). LabVIEW's CLF Node marshalling
|
||||||
if (*Handle) {
|
// reuses the same temp buffer per call site, so *Handle(in) often holds
|
||||||
if (UnregisterFRHandle(*Handle)) {
|
// leftover bytes from the previous Create's output even when the actual
|
||||||
(*Handle)->Destroy();
|
// LabVIEW wire is a different, freshly-allocated instance. Inspecting
|
||||||
delete *Handle;
|
// *Handle(in) and destroying what we "see" tears down legitimate
|
||||||
}
|
// parallel instances. (Same reasoning as CreateANSAWSHandle.)
|
||||||
*Handle = nullptr;
|
// Trade-off: a true double-Create on the same wire leaks the prior
|
||||||
}
|
// handle -- caller's bug; the alternative is far worse.
|
||||||
|
*Handle = nullptr;
|
||||||
|
|
||||||
// std::unique_ptr ensures automatic cleanup if Initialize() throws
|
// std::unique_ptr ensures automatic cleanup if Initialize() throws
|
||||||
auto ptr = std::make_unique<ANSCENTER::ANSFacialRecognition>();
|
auto ptr = std::make_unique<ANSCENTER::ANSFacialRecognition>();
|
||||||
|
|||||||
@@ -107,13 +107,15 @@ static int CopyToLStrHandle(LStrHandle handle, const std::string& str) noexcept
|
|||||||
extern "C" ANSLLM_API int CreateANSLLMHandle(ANSCENTER::ANSLLM** Handle, const char* licenseKey, int localLLM) {
|
extern "C" ANSLLM_API int CreateANSLLMHandle(ANSCENTER::ANSLLM** Handle, const char* licenseKey, int localLLM) {
|
||||||
if (Handle == nullptr || licenseKey == nullptr) return 0;
|
if (Handle == nullptr || licenseKey == nullptr) return 0;
|
||||||
try {
|
try {
|
||||||
// Release existing handle if called twice (prevents leak from LabVIEW)
|
// Pure constructor: ignore *Handle(in). LabVIEW's CLF Node marshalling
|
||||||
if (*Handle) {
|
// reuses the same temp buffer per call site, so *Handle(in) often holds
|
||||||
if (UnregisterLLMHandle(*Handle)) {
|
// leftover bytes from the previous Create's output even when the actual
|
||||||
delete *Handle;
|
// LabVIEW wire is a different, freshly-allocated instance. Inspecting
|
||||||
}
|
// *Handle(in) and destroying what we "see" tears down legitimate
|
||||||
*Handle = nullptr;
|
// parallel instances. (Same reasoning as CreateANSAWSHandle.)
|
||||||
}
|
// Trade-off: a true double-Create on the same wire leaks the prior
|
||||||
|
// handle -- caller's bug; the alternative is far worse.
|
||||||
|
*Handle = nullptr;
|
||||||
|
|
||||||
// std::unique_ptr ensures automatic cleanup on any failure path
|
// std::unique_ptr ensures automatic cleanup on any failure path
|
||||||
auto ptr = std::make_unique<ANSCENTER::ANSLLM>();
|
auto ptr = std::make_unique<ANSCENTER::ANSLLM>();
|
||||||
|
|||||||
@@ -140,14 +140,15 @@ static int CreateANSALPRHandle_Impl(ANSCENTER::ANSALPR** Handle, const char* lic
|
|||||||
// Ensure all shared DLLs (OpenCV, OpenVINO, TRT, ORT) are pre-loaded
|
// Ensure all shared DLLs (OpenCV, OpenVINO, TRT, ORT) are pre-loaded
|
||||||
ANSCENTER::ANSLibsLoader::Initialize();
|
ANSCENTER::ANSLibsLoader::Initialize();
|
||||||
|
|
||||||
// Release existing handle if called twice (prevents leak from LabVIEW)
|
// Pure constructor: ignore *Handle(in). LabVIEW's CLF Node marshalling
|
||||||
if (*Handle) {
|
// reuses the same temp buffer per call site, so *Handle(in) often holds
|
||||||
if (UnregisterALPRHandle(*Handle)) {
|
// leftover bytes from the previous Create's output even when the actual
|
||||||
(*Handle)->Destroy();
|
// LabVIEW wire is a different, freshly-allocated instance. Inspecting
|
||||||
delete *Handle;
|
// *Handle(in) and destroying what we "see" tears down legitimate
|
||||||
}
|
// parallel instances. (Same reasoning as CreateANSAWSHandle.)
|
||||||
*Handle = nullptr;
|
// Trade-off: a true double-Create on the same wire leaks the prior
|
||||||
}
|
// handle -- caller's bug; the alternative is far worse.
|
||||||
|
*Handle = nullptr;
|
||||||
|
|
||||||
if (engineType == 0) {
|
if (engineType == 0) {
|
||||||
(*Handle) = new ANSCENTER::ANSALPR_CPU();// built-in paddle OCR
|
(*Handle) = new ANSCENTER::ANSALPR_CPU();// built-in paddle OCR
|
||||||
|
|||||||
@@ -163,14 +163,15 @@ extern "C" ANSOCR_API int CreateANSOCRHandleEx(ANSCENTER::ANSOCRBase** Handle,
|
|||||||
OutputDebugStringA(buf);
|
OutputDebugStringA(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release existing handle if called twice (prevents leak from LabVIEW)
|
// Pure constructor: ignore *Handle(in). LabVIEW's CLF Node marshalling
|
||||||
if (*Handle) {
|
// reuses the same temp buffer per call site, so *Handle(in) often holds
|
||||||
if (UnregisterOCRHandle(*Handle)) {
|
// leftover bytes from the previous Create's output even when the actual
|
||||||
(*Handle)->Destroy();
|
// LabVIEW wire is a different, freshly-allocated instance. Inspecting
|
||||||
delete *Handle;
|
// *Handle(in) and destroying what we "see" tears down legitimate
|
||||||
}
|
// parallel instances. (Same reasoning as CreateANSAWSHandle.)
|
||||||
*Handle = nullptr;
|
// Trade-off: a true double-Create on the same wire leaks the prior
|
||||||
}
|
// handle -- caller's bug; the alternative is far worse.
|
||||||
|
*Handle = nullptr;
|
||||||
|
|
||||||
// Validate limitSideLen: must be in (0, 20000], default to 960
|
// Validate limitSideLen: must be in (0, 20000], default to 960
|
||||||
if (limitSideLen <= 0 || limitSideLen > 20000)
|
if (limitSideLen <= 0 || limitSideLen > 20000)
|
||||||
|
|||||||
@@ -322,13 +322,15 @@ namespace ANSCENTER
|
|||||||
extern "C" ANSTRE_API int CreateANSTREHandle(ANSCENTER::ANSTRE** Handle, const char* licenseKey, const char* projectDirectory, const char* engineDirectory, const char* modelTemplateDirectory, const char* modelZipPassword, int trainingEngineType, int latestEngine) {
|
extern "C" ANSTRE_API int CreateANSTREHandle(ANSCENTER::ANSTRE** Handle, const char* licenseKey, const char* projectDirectory, const char* engineDirectory, const char* modelTemplateDirectory, const char* modelZipPassword, int trainingEngineType, int latestEngine) {
|
||||||
if (Handle == nullptr) return 0;
|
if (Handle == nullptr) return 0;
|
||||||
if (licenseKey == nullptr || projectDirectory == nullptr || engineDirectory == nullptr || modelTemplateDirectory == nullptr || modelZipPassword == nullptr) return 0;
|
if (licenseKey == nullptr || projectDirectory == nullptr || engineDirectory == nullptr || modelTemplateDirectory == nullptr || modelZipPassword == nullptr) return 0;
|
||||||
// Release existing handle if called twice (prevents leak from LabVIEW)
|
// Pure constructor: ignore *Handle(in). LabVIEW's CLF Node marshalling
|
||||||
if (*Handle) {
|
// reuses the same temp buffer per call site, so *Handle(in) often holds
|
||||||
if (UnregisterTREHandle(*Handle)) {
|
// leftover bytes from the previous Create's output even when the actual
|
||||||
delete *Handle;
|
// LabVIEW wire is a different, freshly-allocated instance. Inspecting
|
||||||
}
|
// *Handle(in) and destroying what we "see" tears down legitimate
|
||||||
*Handle = nullptr;
|
// parallel instances. (Same reasoning as CreateANSAWSHandle.)
|
||||||
}
|
// Trade-off: a true double-Create on the same wire leaks the prior
|
||||||
|
// handle -- caller's bug; the alternative is far worse.
|
||||||
|
*Handle = nullptr;
|
||||||
try {
|
try {
|
||||||
switch (trainingEngineType)
|
switch (trainingEngineType)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -191,14 +191,21 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pure constructor: every call allocates a brand-new ANSUtilities and writes it
|
||||||
|
// to *Handle. *Handle(in) is ignored completely -- LabVIEW's CLF Node marshalling
|
||||||
|
// reuses the same temp buffer per call site, so *Handle(in) often contains
|
||||||
|
// leftover bytes from the previous Create's output even when the actual LabVIEW
|
||||||
|
// wire is a different, freshly-allocated instance. Inspecting *Handle(in) for
|
||||||
|
// "is this live?" detection cannot distinguish that case from a genuine
|
||||||
|
// double-Create-on-same-wire, so we don't try -- we trust the caller.
|
||||||
|
//
|
||||||
|
// Trade-off: if a caller really does call Create twice on the same wire without
|
||||||
|
// Release, the first handle leaks. That is the caller's bug. The alternative
|
||||||
|
// (releasing live objects we "see" in the input) destroys legitimate parallel
|
||||||
|
// instances and is far worse. (Same reasoning as CreateANSAWSHandle.)
|
||||||
extern "C" ANSULT_API int CreateANSUtilityHandle(ANSCENTER::ANSUtilities** Handle, const char* licenseKey) {
|
extern "C" ANSULT_API int CreateANSUtilityHandle(ANSCENTER::ANSUtilities** Handle, const char* licenseKey) {
|
||||||
if (Handle == nullptr || licenseKey == nullptr) return 0;
|
if (Handle == nullptr || licenseKey == nullptr) return 0;
|
||||||
if (*Handle) {
|
*Handle = nullptr;
|
||||||
if (UnregisterUtilHandle(*Handle)) {
|
|
||||||
delete *Handle;
|
|
||||||
}
|
|
||||||
*Handle = nullptr;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
*Handle = new ANSCENTER::ANSUtilities();
|
*Handle = new ANSCENTER::ANSUtilities();
|
||||||
if (*Handle == nullptr) return 0;
|
if (*Handle == nullptr) return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user