Avoid waking all threads when only one is required.

This commit is contained in:
Christopher Kohlhoff 2014-05-03 14:53:01 +10:00
parent e96a7bbdc1
commit 9d0b7d146d
2 changed files with 26 additions and 13 deletions

View File

@ -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

View File

@ -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_;
};