1 #include "MailBox.h"
2 #if defined(_WIN32)
3 #include "win32/Win32Defs.h"
4 #endif
5 
IsPending() const6 bool CMailBox::IsPending() const
7 {
8 	return m_calls.size() != 0;
9 }
10 
WaitForCall()11 void CMailBox::WaitForCall()
12 {
13 	std::unique_lock<std::mutex> callLock(m_callMutex);
14 	while(!IsPending())
15 	{
16 		m_waitCondition.wait(callLock);
17 	}
18 }
19 
WaitForCall(unsigned int timeOut)20 void CMailBox::WaitForCall(unsigned int timeOut)
21 {
22 	std::unique_lock<std::mutex> callLock(m_callMutex);
23 	if(IsPending()) return;
24 	m_waitCondition.wait_for(callLock, std::chrono::milliseconds(timeOut));
25 }
26 
FlushCalls()27 void CMailBox::FlushCalls()
28 {
29 	SendCall([]() {}, true);
30 }
31 
SendCall(const FunctionType & function,bool waitForCompletion)32 void CMailBox::SendCall(const FunctionType& function, bool waitForCompletion)
33 {
34 	std::unique_lock<std::mutex> callLock(m_callMutex);
35 
36 	{
37 		MESSAGE message;
38 		message.function = function;
39 		message.sync = waitForCompletion;
40 		m_calls.push_back(std::move(message));
41 	}
42 
43 	m_waitCondition.notify_all();
44 
45 	if(waitForCompletion)
46 	{
47 		m_callDone = false;
48 		while(!m_callDone)
49 		{
50 			m_callFinished.wait(callLock);
51 		}
52 	}
53 }
54 
SendCall(FunctionType && function)55 void CMailBox::SendCall(FunctionType&& function)
56 {
57 	std::lock_guard<std::mutex> callLock(m_callMutex);
58 
59 	{
60 		MESSAGE message;
61 		message.function = std::move(function);
62 		message.sync = false;
63 		m_calls.push_back(std::move(message));
64 	}
65 
66 	m_waitCondition.notify_all();
67 }
68 
ReceiveCall()69 void CMailBox::ReceiveCall()
70 {
71 	MESSAGE message;
72 	{
73 		std::lock_guard<std::mutex> waitLock(m_callMutex);
74 		if(!IsPending()) return;
75 		message = std::move(m_calls.front());
76 		m_calls.pop_front();
77 	}
78 	message.function();
79 	if(message.sync)
80 	{
81 		std::lock_guard<std::mutex> waitLock(m_callMutex);
82 		m_callDone = true;
83 		m_callFinished.notify_all();
84 	}
85 }
86