spicetools/external/stepmaniax-sdk/sdk/Windows/SMXDeviceSearchThreaded.cpp

98 lines
2.6 KiB
C++

#include "SMXDeviceSearchThreaded.h"
#include "SMXDeviceSearch.h"
#include "SMXDeviceConnection.h"
#include <windows.h>
#include <memory>
using namespace std;
using namespace SMX;
SMX::SMXDeviceSearchThreaded::SMXDeviceSearchThreaded()
{
m_hEvent = make_shared<AutoCloseHandle>(CreateEvent(NULL, false, false, NULL));
m_pDeviceList = make_shared<SMXDeviceSearch>();
// Start the thread.
DWORD id;
m_hThread = CreateThread(NULL, 0, ThreadMainStart, this, 0, &id);
SMX::SetThreadName(id, "SMXDeviceSearch");
}
SMX::SMXDeviceSearchThreaded::~SMXDeviceSearchThreaded()
{
// Shut down the thread, if it's still running.
Shutdown();
}
void SMX::SMXDeviceSearchThreaded::Shutdown()
{
if(m_hThread == INVALID_HANDLE_VALUE)
return;
// Tell the thread to shut down, and wait for it before returning.
m_bShutdown = true;
SetEvent(m_hEvent->value());
WaitForSingleObject(m_hThread, INFINITE);
m_hThread = INVALID_HANDLE_VALUE;
}
DWORD WINAPI SMX::SMXDeviceSearchThreaded::ThreadMainStart(void *self_)
{
SMXDeviceSearchThreaded *self = (SMXDeviceSearchThreaded *) self_;
self->ThreadMain();
return 0;
}
void SMX::SMXDeviceSearchThreaded::UpdateDeviceList()
{
m_Lock.AssertNotLockedByCurrentThread();
// Tell m_pDeviceList about closed devices, so it knows that any device on the
// same path is new.
m_Lock.Lock();
for(auto pDevice: m_apClosedDevices)
m_pDeviceList->DeviceWasClosed(pDevice);
m_apClosedDevices.clear();
m_Lock.Unlock();
// Get the current device list.
wstring sError;
vector<shared_ptr<AutoCloseHandle>> apDevices = m_pDeviceList->GetDevices(sError);
if(!sError.empty())
{
Log(ssprintf("Error listing USB devices: %ls", sError.c_str()));
return;
}
// Update the device list returned by GetDevices.
m_Lock.Lock();
m_apDevices = apDevices;
m_Lock.Unlock();
}
void SMX::SMXDeviceSearchThreaded::ThreadMain()
{
while(!m_bShutdown)
{
UpdateDeviceList();
WaitForSingleObjectEx(m_hEvent->value(), 250, true);
}
}
void SMX::SMXDeviceSearchThreaded::DeviceWasClosed(shared_ptr<AutoCloseHandle> pDevice)
{
// Add pDevice to the list of closed devices. We'll call m_pDeviceList->DeviceWasClosed
// on these from the scanning thread.
m_apClosedDevices.push_back(pDevice);
}
vector<shared_ptr<AutoCloseHandle>> SMX::SMXDeviceSearchThreaded::GetDevices()
{
// Lock to make a copy of the device list.
m_Lock.Lock();
vector<shared_ptr<AutoCloseHandle>> apResult = m_apDevices;
m_Lock.Unlock();
return apResult;
}