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 <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
namespace SMX
|
||||
@ -99,6 +100,42 @@ public:
|
||||
private:
|
||||
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
|
||||
|
@ -20,6 +20,7 @@
|
||||
<ClInclude Include="SMXDeviceSearchThreaded.h" />
|
||||
<ClInclude Include="SMXHelperThread.h" />
|
||||
<ClInclude Include="SMXManager.h" />
|
||||
<ClInclude Include="SMXThread.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Helpers.cpp" />
|
||||
@ -30,6 +31,7 @@
|
||||
<ClCompile Include="SMXDeviceSearchThreaded.cpp" />
|
||||
<ClCompile Include="SMXHelperThread.cpp" />
|
||||
<ClCompile Include="SMXManager.cpp" />
|
||||
<ClCompile Include="SMXThread.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C5FC0823-9896-4B7C-BFE1-B60DB671A462}</ProjectGuid>
|
||||
|
@ -34,6 +34,9 @@
|
||||
<ClInclude Include="SMXBuildVersion.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SMXThread.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="SMX.cpp">
|
||||
@ -60,5 +63,8 @@
|
||||
<ClCompile Include="Helpers.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SMXThread.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,31 +1,10 @@
|
||||
#include "SMXHelperThread.h"
|
||||
|
||||
#include <windows.h>
|
||||
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 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;
|
||||
Start(sThreadName);
|
||||
}
|
||||
|
||||
void SMX::SMXHelperThread::ThreadMain()
|
||||
@ -44,26 +23,13 @@ void SMX::SMXHelperThread::ThreadMain()
|
||||
m_Lock.Unlock();
|
||||
for(auto &func: funcs)
|
||||
func();
|
||||
|
||||
WaitForSingleObjectEx(m_hEvent->value(), 250, true);
|
||||
m_Lock.Lock();
|
||||
|
||||
m_Event.Wait(250);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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.
|
||||
m_Lock.Lock();
|
||||
m_FunctionsToCall.push_back(func);
|
||||
SetEvent(m_hEvent->value());
|
||||
m_Event.Set();
|
||||
m_Lock.Unlock();
|
||||
}
|
||||
|
||||
bool SMX::SMXHelperThread::IsCurrentThread() const
|
||||
{
|
||||
return GetCurrentThreadId() == m_iThreadId;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define SMXHelperThread_h
|
||||
|
||||
#include "Helpers.h"
|
||||
#include "SMXThread.h"
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
@ -10,34 +11,19 @@ using namespace std;
|
||||
|
||||
namespace SMX
|
||||
{
|
||||
class SMXHelperThread
|
||||
class SMXHelperThread: public SMXThread
|
||||
{
|
||||
public:
|
||||
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.
|
||||
void RunInThread(function<void()> func);
|
||||
|
||||
// Return true if this is the calling thread.
|
||||
bool IsCurrentThread() const;
|
||||
|
||||
private:
|
||||
static DWORD WINAPI ThreadMainStart(void *self_);
|
||||
void ThreadMain();
|
||||
|
||||
DWORD m_iThreadId = 0;
|
||||
// Helper threads use their independent 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;
|
||||
};
|
||||
}
|
||||
|
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