Avoid waking all threads when only one is required.
This commit is contained in:
parent
e96a7bbdc1
commit
9d0b7d146d
@ -29,16 +29,32 @@ namespace asio {
|
||||
namespace detail {
|
||||
|
||||
win_event::win_event()
|
||||
: event_(::CreateEvent(0, true, false, 0)),
|
||||
state_(0)
|
||||
: state_(0)
|
||||
{
|
||||
if (!event_)
|
||||
events_[0] = ::CreateEvent(0, true, false, 0);
|
||||
if (!events_[0])
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::get_system_category());
|
||||
asio::detail::throw_error(ec, "event");
|
||||
}
|
||||
|
||||
events_[1] = ::CreateEvent(0, false, false, 0);
|
||||
if (!events_[1])
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
::CloseHandle(events_[0]);
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::get_system_category());
|
||||
asio::detail::throw_error(ec, "event");
|
||||
}
|
||||
}
|
||||
|
||||
win_event::~win_event()
|
||||
{
|
||||
::CloseHandle(events_[0]);
|
||||
::CloseHandle(events_[1]);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
@ -36,10 +36,7 @@ public:
|
||||
ASIO_DECL win_event();
|
||||
|
||||
// Destructor.
|
||||
~win_event()
|
||||
{
|
||||
::CloseHandle(event_);
|
||||
}
|
||||
ASIO_DECL ~win_event();
|
||||
|
||||
// Signal all waiters.
|
||||
template <typename Lock>
|
||||
@ -48,7 +45,7 @@ public:
|
||||
ASIO_ASSERT(lock.locked());
|
||||
(void)lock;
|
||||
state_ |= 1;
|
||||
::SetEvent(event_);
|
||||
::SetEvent(events_[0]);
|
||||
}
|
||||
|
||||
// Unlock the mutex and signal one waiter.
|
||||
@ -60,7 +57,7 @@ public:
|
||||
bool have_waiters = (state_ > 1);
|
||||
lock.unlock();
|
||||
if (have_waiters)
|
||||
::SetEvent(event_);
|
||||
::SetEvent(events_[1]);
|
||||
}
|
||||
|
||||
// If there's a waiter, unlock the mutex and signal it.
|
||||
@ -72,7 +69,7 @@ public:
|
||||
if (state_ > 1)
|
||||
{
|
||||
lock.unlock();
|
||||
::SetEvent(event_);
|
||||
::SetEvent(events_[1]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -84,7 +81,7 @@ public:
|
||||
{
|
||||
ASIO_ASSERT(lock.locked());
|
||||
(void)lock;
|
||||
::ResetEvent(event_);
|
||||
::ResetEvent(events_[0]);
|
||||
state_ &= ~std::size_t(1);
|
||||
}
|
||||
|
||||
@ -97,14 +94,14 @@ public:
|
||||
{
|
||||
state_ += 2;
|
||||
lock.unlock();
|
||||
::WaitForSingleObject(event_, INFINITE);
|
||||
::WaitForMultipleObjects(2, events_, false, INFINITE);
|
||||
lock.lock();
|
||||
state_ -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE event_;
|
||||
HANDLE events_[2];
|
||||
std::size_t state_;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user