30 #include <boost/assert.hpp>
36 namespace connection {
38 using boost::defer_lock;
40 : m_lock(aac.m_mut, defer_lock), m_lockDone(aac.m_mutDone, defer_lock),
41 m_calledRequest(false), m_nested(false), m_control(aac),
42 m_sharedRts(aac.m_rts), m_sharedDone(aac.m_done),
43 m_mainMessage(aac.m_mainMessage),
44 m_condMainThread(aac.m_condMainThread),
45 m_condAsyncThread(aac.m_condAsyncThread) {}
48 BOOST_ASSERT_MSG(m_lock.owns_lock() == m_lockDone.owns_lock(),
49 "We should own either both locks or neither.");
50 if (m_lock.owns_lock() && m_lockDone.owns_lock()) {
53 m_control.m_currentRequestThread.reset();
56 m_condMainThread.notify_one();
60 BOOST_ASSERT_MSG(m_calledRequest ==
false,
61 "Can only try to request once "
62 "on a single RequestToSend "
67 m_control.m_currentRequestThread ==
68 boost::this_thread::get_id()) {
76 BOOST_ASSERT_MSG(m_sharedRts ==
false,
77 "Shouldn't happen - inconsistent "
78 "state. Can't get in a request when "
82 m_calledRequest =
true;
87 while (m_mainMessage == AsyncAccessControl::MTM_WAIT) {
88 m_condAsyncThread.wait(
96 (m_mainMessage == AsyncAccessControl::MTM_CLEAR_TO_SEND);
99 !m_control.m_currentRequestThread.is_initialized(),
100 "Shouldn't be anyone in except us!");
101 m_control.m_currentRequestThread =
102 boost::this_thread::get_id();
110 : m_rts(false), m_done(false), m_mainMessage(MTM_WAIT) {}
112 bool AsyncAccessControl::mainThreadCTS() {
113 MainLockType lock(m_mut);
114 return m_handleRTS(lock, MTM_CLEAR_TO_SEND);
118 MainLockType lock(m_mut);
119 return m_handleRTS(lock, MTM_DENY_SEND);
123 MainLockType lock(m_mut);
124 bool handled = m_handleRTS(lock, MTM_DENY_SEND, MTM_DENY_SEND);
126 BOOST_ASSERT_MSG(lock.owns_lock(),
127 "if m_handleRTS returns false, "
128 "we're supposed to still own the "
132 m_mainMessage = MTM_DENY_SEND;
138 AsyncAccessControl::m_handleRTS(MainLockType &lock,
139 MainThreadMessages response,
140 MainThreadMessages postCompletionState) {
141 if (!lock.owns_lock() || (lock.mutex() != &m_mut)) {
142 throw std::logic_error(
143 "m_handleRTS requires its caller to pass a lock "
144 "owning the main mutex!");
151 m_mainMessage = response;
153 m_condAsyncThread.notify_one();
155 DoneLockType finishedLock(m_mutDone);
158 m_condMainThread.wait(finishedLock);
161 m_mainMessage = postCompletionState;
~RequestToSend()
Destructor.
bool mainThreadDenyPermanently()
Permanently deny present and future requests.
bool mainThreadDeny()
Check for waiting async thread, and deny it permission to send if found.
Internal class handling the synchronization of an asynchronous thread wishing to communicate that has...
bool request()
Issues a blocking request to send.
RequestToSend(AsyncAccessControl &aac)
Creates an RAII object to manage the request to send - note that it does not immediately request to s...
Internal, configured header file for verbosity macros.
AsyncAccessControl()
Constructor.