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 @@
//
// 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");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
......@@ -27,6 +27,8 @@
#include "../../MMDevice/ModuleInterface.h"
#include <algorithm>
#include <chrono>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
const char* g_szCameraName = "XenethCamera";
const char* g_szExposurePropName = "exposure-property";
......@@ -64,6 +66,8 @@ static std::string g_szLogFile
;
static std::recursive_mutex g_hLogMutex;
static std::thread* g_pLogThread(nullptr);
std::list<XenethCamera*> XenethCamera::m_apInstances;
static void LogThreadFunc();
static std::string LogFormat(const char* szFormat, ...);
static void LogLine(const char* szFileInfo, std::string && szLine);
......@@ -74,6 +78,23 @@ static void LogInit();
#define STRINGIFY(x) STRINGIFY2(x)
#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
MODULE_API void InitializeModuleData()
{
......@@ -118,6 +139,9 @@ XenethCamera::XenethCamera() :
m_uRoiH(0)
{
LOG(("XenethCamera::XenethCamera(%p)\n", this));
g_hLogMutex.lock();
m_apInstances.push_back(this);
g_hLogMutex.unlock();
// create a property to select the camera
XenethCreateProperty("device path", m_szCameraPath.c_str(), MM::String, false, &XenethCamera::OnCameraPath, true);
......@@ -164,6 +188,9 @@ XenethCamera::~XenethCamera()
LOG(("XenethCamera::~XenethCamera(%p) m_bInitialized=%d\n", this, m_bInitialized));
if (m_bInitialized)
Shutdown();
g_hLogMutex.lock();
m_apInstances.remove(this);
g_hLogMutex.unlock();
}
int XenethCamera::XenethCreateProperty(const char* szName, const char* szValue, MM::PropertyType eType,
......@@ -679,7 +706,7 @@ int XenethCamera::SnapImage()
LOG(("XenethCamera::SnapImage(%p) frame count=%u\n", this, XC_GetFrameCount(m_hCamera)));
int iResult(ConvertXenethResult(XC_GetFrame(m_hCamera, FT_NATIVE, XGF_Blocking,
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;
LOG(("XenethCamera::SnapImage(%p) size=%u iResult=%d\n", this, m_abyImage.size(), iResult));
......@@ -931,6 +958,16 @@ try_string:
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 dOldValue(dValue);
......
......@@ -63,6 +63,11 @@ public:
unsigned GetNumberOfComponents() const;
const unsigned int* GetImageBufferAsRGB32();
/// <summary>
/// this function is called before the DLL is unloaded to shut down existing devices
/// </summary>
static void DllMainShutdown();
private:
class XenethProperty
{
......@@ -89,6 +94,7 @@ private:
XCHANDLE m_hCamera;
std::vector<XenethProperty> m_aProperties;
long m_lExposurePropertyIndex;
static std::list<XenethCamera*> m_apInstances;
mutable unsigned m_uRoiX;
mutable unsigned m_uRoiY;
......
Supports Markdown
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