Commit 22ce90b4 authored by Rossa, Lutz's avatar Rossa, Lutz
Browse files

force shutdown on existing device while DLL unload

parent dc3be302
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
// //
// AUTHOR: Lutz Rossa // AUTHOR: Lutz Rossa
// //
// COPYRIGHT: 2020 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH // COPYRIGHT: 2020-2021 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
// LICENSE: Licensed under the Apache License, Version 2.0 (the "License"); // LICENSE: Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include "../../MMDevice/ModuleInterface.h" #include "../../MMDevice/ModuleInterface.h"
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
const char* g_szCameraName = "XenethCamera"; const char* g_szCameraName = "XenethCamera";
const char* g_szExposurePropName = "exposure-property"; const char* g_szExposurePropName = "exposure-property";
...@@ -64,6 +66,8 @@ static std::string g_szLogFile ...@@ -64,6 +66,8 @@ static std::string g_szLogFile
; ;
static std::recursive_mutex g_hLogMutex; static std::recursive_mutex g_hLogMutex;
static std::thread* g_pLogThread(nullptr); static std::thread* g_pLogThread(nullptr);
std::list<XenethCamera*> XenethCamera::m_apInstances;
static void LogThreadFunc(); static void LogThreadFunc();
static std::string LogFormat(const char* szFormat, ...); static std::string LogFormat(const char* szFormat, ...);
static void LogLine(const char* szFileInfo, std::string && szLine); static void LogLine(const char* szFileInfo, std::string && szLine);
...@@ -74,6 +78,23 @@ static void LogInit(); ...@@ -74,6 +78,23 @@ static void LogInit();
#define STRINGIFY(x) STRINGIFY2(x) #define STRINGIFY(x) STRINGIFY2(x)
#define LOG(x) do { LogInit(); std::string szLine(LogFormat x); LogLine(__FILE__ "(" STRINGIFY(__LINE__) "): ", std::move(szLine)); } while (0) #define LOG(x) do { LogInit(); std::string szLine(LogFormat x); LogLine(__FILE__ "(" STRINGIFY(__LINE__) "): ", std::move(szLine)); } while (0)
BOOL APIENTRY DllMain(HANDLE /*hModule*/, DWORD ulReasonForCall, LPVOID /*lpReserved*/)
{
switch (ulReasonForCall)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
XenethCamera::DllMainShutdown();
break;
}
return TRUE;
}
// Exported MMDevice API // Exported MMDevice API
MODULE_API void InitializeModuleData() MODULE_API void InitializeModuleData()
{ {
...@@ -118,6 +139,9 @@ XenethCamera::XenethCamera() : ...@@ -118,6 +139,9 @@ XenethCamera::XenethCamera() :
m_uRoiH(0) m_uRoiH(0)
{ {
LOG(("XenethCamera::XenethCamera(%p)\n", this)); LOG(("XenethCamera::XenethCamera(%p)\n", this));
g_hLogMutex.lock();
m_apInstances.push_back(this);
g_hLogMutex.unlock();
// create a property to select the camera // create a property to select the camera
XenethCreateProperty("device path", m_szCameraPath.c_str(), MM::String, false, &XenethCamera::OnCameraPath, true); XenethCreateProperty("device path", m_szCameraPath.c_str(), MM::String, false, &XenethCamera::OnCameraPath, true);
...@@ -164,6 +188,9 @@ XenethCamera::~XenethCamera() ...@@ -164,6 +188,9 @@ XenethCamera::~XenethCamera()
LOG(("XenethCamera::~XenethCamera(%p) m_bInitialized=%d\n", this, m_bInitialized)); LOG(("XenethCamera::~XenethCamera(%p) m_bInitialized=%d\n", this, m_bInitialized));
if (m_bInitialized) if (m_bInitialized)
Shutdown(); Shutdown();
g_hLogMutex.lock();
m_apInstances.remove(this);
g_hLogMutex.unlock();
} }
int XenethCamera::XenethCreateProperty(const char* szName, const char* szValue, MM::PropertyType eType, int XenethCamera::XenethCreateProperty(const char* szName, const char* szValue, MM::PropertyType eType,
...@@ -679,7 +706,7 @@ int XenethCamera::SnapImage() ...@@ -679,7 +706,7 @@ int XenethCamera::SnapImage()
LOG(("XenethCamera::SnapImage(%p) frame count=%u\n", this, XC_GetFrameCount(m_hCamera))); LOG(("XenethCamera::SnapImage(%p) frame count=%u\n", this, XC_GetFrameCount(m_hCamera)));
int iResult(ConvertXenethResult(XC_GetFrame(m_hCamera, FT_NATIVE, XGF_Blocking, int iResult(ConvertXenethResult(XC_GetFrame(m_hCamera, FT_NATIVE, XGF_Blocking,
static_cast<void*>(m_abyImage.data()), static_cast<int>(m_abyImage.size())))); static_cast<void*>(m_abyImage.data()), static_cast<int>(m_abyImage.size()))));
if (g_iSnapCount < 1000) if (g_iSnapCount < 1000 || iResult != DEVICE_OK)
{ {
++g_iSnapCount; ++g_iSnapCount;
LOG(("XenethCamera::SnapImage(%p) size=%u iResult=%d\n", this, m_abyImage.size(), iResult)); LOG(("XenethCamera::SnapImage(%p) size=%u iResult=%d\n", this, m_abyImage.size(), iResult));
...@@ -931,6 +958,16 @@ try_string: ...@@ -931,6 +958,16 @@ try_string:
return DEVICE_OK; return DEVICE_OK;
} }
void XenethCamera::DllMainShutdown()
{
for (auto it = m_apInstances.begin(); it != m_apInstances.end(); ++it)
{
XenethCamera* p(*it);
if (p->m_bInitialized)
p->Shutdown();
}
}
double XenethCamera::FromMilliseconds(double dValue, const char* szTargetUnit) double XenethCamera::FromMilliseconds(double dValue, const char* szTargetUnit)
{ {
double dOldValue(dValue); double dOldValue(dValue);
......
...@@ -63,6 +63,11 @@ public: ...@@ -63,6 +63,11 @@ public:
unsigned GetNumberOfComponents() const; unsigned GetNumberOfComponents() const;
const unsigned int* GetImageBufferAsRGB32(); const unsigned int* GetImageBufferAsRGB32();
/// <summary>
/// this function is called before the DLL is unloaded to shut down existing devices
/// </summary>
static void DllMainShutdown();
private: private:
class XenethProperty class XenethProperty
{ {
...@@ -81,14 +86,15 @@ private: ...@@ -81,14 +86,15 @@ private:
std::string m_szValue; std::string m_szValue;
}; };
mutable bool m_bInitialized; mutable bool m_bInitialized;
mutable bool m_bInitializing; mutable bool m_bInitializing;
unsigned char m_byPixelSize; unsigned char m_byPixelSize;
std::string m_szCameraPath; std::string m_szCameraPath;
std::string m_szCalibrationFile; std::string m_szCalibrationFile;
XCHANDLE m_hCamera; XCHANDLE m_hCamera;
std::vector<XenethProperty> m_aProperties; std::vector<XenethProperty> m_aProperties;
long m_lExposurePropertyIndex; long m_lExposurePropertyIndex;
static std::list<XenethCamera*> m_apInstances;
mutable unsigned m_uRoiX; mutable unsigned m_uRoiX;
mutable unsigned m_uRoiY; mutable unsigned m_uRoiY;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment