Split out low-level thread handling into SMXThread, and use it in SMXHelperThread.
This isn't used by the SMXManager thread for now. This also separates out SMX::Event for thread event handling.
This commit is contained in:
parent
a7cb6ad51d
commit
d576545266
@ -6,6 +6,7 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace SMX
|
namespace SMX
|
||||||
@ -99,6 +100,42 @@ public:
|
|||||||
private:
|
private:
|
||||||
Mutex &m_Mutex;
|
Mutex &m_Mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Event(Mutex &lock):
|
||||||
|
m_Lock(lock)
|
||||||
|
{
|
||||||
|
m_hEvent = make_shared<AutoCloseHandle>(CreateEvent(NULL, false, false, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set()
|
||||||
|
{
|
||||||
|
SetEvent(m_hEvent->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock m_Lock, wait up to iDelayMilliseconds for the event to be set,
|
||||||
|
// then lock m_Lock. If iDelayMilliseconds is -1, wait forever.
|
||||||
|
void Wait(int iDelayMilliseconds)
|
||||||
|
{
|
||||||
|
if(iDelayMilliseconds == -1)
|
||||||
|
iDelayMilliseconds = INFINITE;
|
||||||
|
|
||||||
|
m_Lock.AssertLockedByCurrentThread();
|
||||||
|
|
||||||
|
m_Lock.Unlock();
|
||||||
|
vector<HANDLE> aHandles = { m_hEvent->value() };
|
||||||
|
WaitForSingleObjectEx(m_hEvent->value(), iDelayMilliseconds, true);
|
||||||
|
m_Lock.Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
shared_ptr<SMX::AutoCloseHandle> m_hEvent;
|
||||||
|
Mutex &m_Lock;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
<ClInclude Include="SMXDeviceSearchThreaded.h" />
|
<ClInclude Include="SMXDeviceSearchThreaded.h" />
|
||||||
<ClInclude Include="SMXHelperThread.h" />
|
<ClInclude Include="SMXHelperThread.h" />
|
||||||
<ClInclude Include="SMXManager.h" />
|
<ClInclude Include="SMXManager.h" />
|
||||||
|
<ClInclude Include="SMXThread.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Helpers.cpp" />
|
<ClCompile Include="Helpers.cpp" />
|
||||||
@ -30,6 +31,7 @@
|
|||||||
<ClCompile Include="SMXDeviceSearchThreaded.cpp" />
|
<ClCompile Include="SMXDeviceSearchThreaded.cpp" />
|
||||||
<ClCompile Include="SMXHelperThread.cpp" />
|
<ClCompile Include="SMXHelperThread.cpp" />
|
||||||
<ClCompile Include="SMXManager.cpp" />
|
<ClCompile Include="SMXManager.cpp" />
|
||||||
|
<ClCompile Include="SMXThread.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{C5FC0823-9896-4B7C-BFE1-B60DB671A462}</ProjectGuid>
|
<ProjectGuid>{C5FC0823-9896-4B7C-BFE1-B60DB671A462}</ProjectGuid>
|
||||||
|
@ -34,6 +34,9 @@
|
|||||||
<ClInclude Include="SMXBuildVersion.h">
|
<ClInclude Include="SMXBuildVersion.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="SMXThread.h">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="SMX.cpp">
|
<ClCompile Include="SMX.cpp">
|
||||||
@ -60,5 +63,8 @@
|
|||||||
<ClCompile Include="Helpers.cpp">
|
<ClCompile Include="Helpers.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="SMXThread.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -1,31 +1,10 @@
|
|||||||
#include "SMXHelperThread.h"
|
#include "SMXHelperThread.h"
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
using namespace SMX;
|
using namespace SMX;
|
||||||
|
|
||||||
SMX::SMXHelperThread::SMXHelperThread(const string &sThreadName)
|
SMX::SMXHelperThread::SMXHelperThread(const string &sThreadName):
|
||||||
|
SMXThread(m_Lock)
|
||||||
{
|
{
|
||||||
m_hEvent = make_shared<AutoCloseHandle>(CreateEvent(NULL, false, false, NULL));
|
Start(sThreadName);
|
||||||
|
|
||||||
// Start the thread.
|
|
||||||
m_hThread = CreateThread(NULL, 0, ThreadMainStart, this, 0, &m_iThreadId);
|
|
||||||
SMX::SetThreadName(m_iThreadId, sThreadName);
|
|
||||||
}
|
|
||||||
|
|
||||||
SMX::SMXHelperThread::~SMXHelperThread()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SMX::SMXHelperThread::SetHighPriority(bool bHighPriority)
|
|
||||||
{
|
|
||||||
SetThreadPriority( m_hThread, THREAD_PRIORITY_HIGHEST );
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI SMX::SMXHelperThread::ThreadMainStart(void *self_)
|
|
||||||
{
|
|
||||||
SMXHelperThread *self = (SMXHelperThread *) self_;
|
|
||||||
self->ThreadMain();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMX::SMXHelperThread::ThreadMain()
|
void SMX::SMXHelperThread::ThreadMain()
|
||||||
@ -44,26 +23,13 @@ void SMX::SMXHelperThread::ThreadMain()
|
|||||||
m_Lock.Unlock();
|
m_Lock.Unlock();
|
||||||
for(auto &func: funcs)
|
for(auto &func: funcs)
|
||||||
func();
|
func();
|
||||||
|
|
||||||
WaitForSingleObjectEx(m_hEvent->value(), 250, true);
|
|
||||||
m_Lock.Lock();
|
m_Lock.Lock();
|
||||||
|
|
||||||
|
m_Event.Wait(250);
|
||||||
}
|
}
|
||||||
m_Lock.Unlock();
|
m_Lock.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMX::SMXHelperThread::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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SMX::SMXHelperThread::RunInThread(function<void()> func)
|
void SMX::SMXHelperThread::RunInThread(function<void()> func)
|
||||||
{
|
{
|
||||||
m_Lock.AssertNotLockedByCurrentThread();
|
m_Lock.AssertNotLockedByCurrentThread();
|
||||||
@ -71,11 +37,6 @@ void SMX::SMXHelperThread::RunInThread(function<void()> func)
|
|||||||
// Add func to the list, and poke the event to wake up the thread if needed.
|
// Add func to the list, and poke the event to wake up the thread if needed.
|
||||||
m_Lock.Lock();
|
m_Lock.Lock();
|
||||||
m_FunctionsToCall.push_back(func);
|
m_FunctionsToCall.push_back(func);
|
||||||
SetEvent(m_hEvent->value());
|
m_Event.Set();
|
||||||
m_Lock.Unlock();
|
m_Lock.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SMX::SMXHelperThread::IsCurrentThread() const
|
|
||||||
{
|
|
||||||
return GetCurrentThreadId() == m_iThreadId;
|
|
||||||
}
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define SMXHelperThread_h
|
#define SMXHelperThread_h
|
||||||
|
|
||||||
#include "Helpers.h"
|
#include "Helpers.h"
|
||||||
|
#include "SMXThread.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -10,34 +11,19 @@ using namespace std;
|
|||||||
|
|
||||||
namespace SMX
|
namespace SMX
|
||||||
{
|
{
|
||||||
class SMXHelperThread
|
class SMXHelperThread: public SMXThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SMXHelperThread(const string &sThreadName);
|
SMXHelperThread(const string &sThreadName);
|
||||||
~SMXHelperThread();
|
|
||||||
|
|
||||||
// Raise the priority of the helper thread.
|
|
||||||
void SetHighPriority(bool bHighPriority);
|
|
||||||
|
|
||||||
// Shut down the thread. Any calls queued by RunInThread will complete before
|
|
||||||
// this returns.
|
|
||||||
void Shutdown();
|
|
||||||
|
|
||||||
// Call func asynchronously from the helper thread.
|
// Call func asynchronously from the helper thread.
|
||||||
void RunInThread(function<void()> func);
|
void RunInThread(function<void()> func);
|
||||||
|
|
||||||
// Return true if this is the calling thread.
|
|
||||||
bool IsCurrentThread() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static DWORD WINAPI ThreadMainStart(void *self_);
|
|
||||||
void ThreadMain();
|
void ThreadMain();
|
||||||
|
|
||||||
DWORD m_iThreadId = 0;
|
// Helper threads use their independent lock.
|
||||||
SMX::Mutex m_Lock;
|
SMX::Mutex m_Lock;
|
||||||
shared_ptr<SMX::AutoCloseHandle> m_hEvent;
|
|
||||||
bool m_bShutdown = false;
|
|
||||||
HANDLE m_hThread = INVALID_HANDLE_VALUE;
|
|
||||||
vector<function<void()>> m_FunctionsToCall;
|
vector<function<void()>> m_FunctionsToCall;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
49
sdk/Windows/SMXThread.cpp
Normal file
49
sdk/Windows/SMXThread.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#include "SMXThread.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace SMX;
|
||||||
|
|
||||||
|
SMXThread::SMXThread(Mutex &lock):
|
||||||
|
m_Lock(lock),
|
||||||
|
m_Event(lock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMX::SMXThread::SetHighPriority(bool bHighPriority)
|
||||||
|
{
|
||||||
|
if(m_hThread == INVALID_HANDLE_VALUE)
|
||||||
|
throw exception("SetHighPriority called while the thread isn't running");
|
||||||
|
|
||||||
|
SetThreadPriority(m_hThread, THREAD_PRIORITY_HIGHEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMX::SMXThread::IsCurrentThread() const
|
||||||
|
{
|
||||||
|
return GetCurrentThreadId() == m_iThreadId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMXThread::Start(string name)
|
||||||
|
{
|
||||||
|
// Start the thread.
|
||||||
|
m_hThread = CreateThread(NULL, 0, ThreadMainStart, this, 0, &m_iThreadId);
|
||||||
|
SMX::SetThreadName(m_iThreadId, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMXThread::Shutdown()
|
||||||
|
{
|
||||||
|
m_Lock.AssertNotLockedByCurrentThread();
|
||||||
|
|
||||||
|
// Shut down the thread and wait for it to exit.
|
||||||
|
m_bShutdown = true;
|
||||||
|
m_Event.Set();
|
||||||
|
|
||||||
|
WaitForSingleObject(m_hThread, INFINITE);
|
||||||
|
m_hThread = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI SMXThread::ThreadMainStart(void *self_)
|
||||||
|
{
|
||||||
|
SMXThread *self = (SMXThread *) self_;
|
||||||
|
self->ThreadMain();
|
||||||
|
return 0;
|
||||||
|
}
|
45
sdk/Windows/SMXThread.h
Normal file
45
sdk/Windows/SMXThread.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#ifndef SMXThread_h
|
||||||
|
#define SMXThread_h
|
||||||
|
|
||||||
|
// A base class for a thread.
|
||||||
|
#include "Helpers.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace SMX
|
||||||
|
{
|
||||||
|
|
||||||
|
class SMXThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SMXThread(SMX::Mutex &lock);
|
||||||
|
|
||||||
|
// Raise the priority of the thread.
|
||||||
|
void SetHighPriority(bool bHighPriority);
|
||||||
|
|
||||||
|
// Start the thread, giving it a name for debugging.
|
||||||
|
void Start(std::string name);
|
||||||
|
|
||||||
|
// Shut down the thread. This function won't return until the thread
|
||||||
|
// has been stopped.
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
// Return true if this is the calling thread.
|
||||||
|
bool IsCurrentThread() const;
|
||||||
|
|
||||||
|
// The derived class implements this.
|
||||||
|
virtual void ThreadMain() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static DWORD WINAPI ThreadMainStart(void *self);
|
||||||
|
|
||||||
|
SMX::Mutex &m_Lock;
|
||||||
|
SMX::Event m_Event;
|
||||||
|
bool m_bShutdown = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE m_hThread = INVALID_HANDLE_VALUE;
|
||||||
|
DWORD m_iThreadId = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user