| Index: base/message_loop/message_pump_win.cc
|
| diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
|
| index 03e2336ec9f14dd48e7e69c4e2b67fe304a5934d..04e76e8b4c0ccb252b4c0b770c49ea105b39fbd6 100644
|
| --- a/base/message_loop/message_pump_win.cc
|
| +++ b/base/message_loop/message_pump_win.cc
|
| @@ -9,7 +9,6 @@
|
|
|
| #include <limits>
|
|
|
| -#include "base/memory/ptr_util.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/strings/stringprintf.h"
|
| @@ -35,9 +34,6 @@
|
| // Message sent to get an additional time slice for pumping (processing) another
|
| // task (a series of such messages creates a continuous task pump).
|
| static const int kMsgHaveWork = WM_USER + 1;
|
| -
|
| -// The application-defined code passed to the hook procedure.
|
| -static const int kMessageFilterCode = 0x5001;
|
|
|
| //-----------------------------------------------------------------------------
|
| // MessagePumpWin public:
|
| @@ -97,7 +93,7 @@
|
| }
|
|
|
| void MessagePumpForUI::ScheduleWork() {
|
| - if (InterlockedExchange(&work_state_, HAVE_WORK) != READY)
|
| + if (InterlockedExchange(&have_work_, 1))
|
| return; // Someone else continued the pumping.
|
|
|
| // Make sure the MessagePump does some work for us.
|
| @@ -114,9 +110,7 @@
|
| // common (queue is full, of about 2000 messages), so we'll do a near-graceful
|
| // recovery. Nested loops are pretty transient (we think), so this will
|
| // probably be recoverable.
|
| -
|
| - // Clarify that we didn't really insert.
|
| - InterlockedExchange(&work_state_, READY);
|
| + InterlockedExchange(&have_work_, 0); // Clarify that we didn't really insert.
|
| UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", MESSAGE_POST_ERROR,
|
| MESSAGE_LOOP_PROBLEM_MAX);
|
| }
|
| @@ -259,7 +253,7 @@
|
| // sort.
|
| if (!state_) {
|
| // Since we handled a kMsgHaveWork message, we must still update this flag.
|
| - InterlockedExchange(&work_state_, READY);
|
| + InterlockedExchange(&have_work_, 0);
|
| return;
|
| }
|
|
|
| @@ -402,8 +396,8 @@
|
| msg.hwnd != message_hwnd_);
|
|
|
| // Since we discarded a kMsgHaveWork message, we must update the flag.
|
| - int old_work_state_ = InterlockedExchange(&work_state_, READY);
|
| - DCHECK_EQ(HAVE_WORK, old_work_state_);
|
| + int old_have_work = InterlockedExchange(&have_work_, 0);
|
| + DCHECK(old_have_work);
|
|
|
| // We don't need a special time slice if we didn't have_message to process.
|
| if (!have_message)
|
| @@ -418,143 +412,6 @@
|
| }
|
|
|
| //-----------------------------------------------------------------------------
|
| -// MessagePumpForGpu public:
|
| -
|
| -MessagePumpForGpu::MessagePumpForGpu() : thread_id_(GetCurrentThreadId()) {
|
| - // Init the message queue.
|
| - MSG msg;
|
| - PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE);
|
| -}
|
| -
|
| -MessagePumpForGpu::~MessagePumpForGpu() {}
|
| -
|
| -// static
|
| -void MessagePumpForGpu::InitFactory() {
|
| - bool init_result = MessageLoop::InitMessagePumpForUIFactory(
|
| - &MessagePumpForGpu::CreateMessagePumpForGpu);
|
| - DCHECK(init_result);
|
| -}
|
| -
|
| -// static
|
| -std::unique_ptr<MessagePump> MessagePumpForGpu::CreateMessagePumpForGpu() {
|
| - return WrapUnique<MessagePump>(new MessagePumpForGpu);
|
| -}
|
| -
|
| -void MessagePumpForGpu::ScheduleWork() {
|
| - if (InterlockedExchange(&work_state_, HAVE_WORK) != READY)
|
| - return; // Someone else continued the pumping.
|
| -
|
| - // Make sure the MessagePump does some work for us.
|
| - BOOL ret = PostThreadMessage(thread_id_, kMsgHaveWork, 0, 0);
|
| - if (ret)
|
| - return; // There was room in the Window Message queue.
|
| -
|
| - // See comment in MessagePumpForUI::ScheduleWork.
|
| - InterlockedExchange(&work_state_, READY);
|
| - UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", MESSAGE_POST_ERROR,
|
| - MESSAGE_LOOP_PROBLEM_MAX);
|
| -}
|
| -
|
| -void MessagePumpForGpu::ScheduleDelayedWork(
|
| - const TimeTicks& delayed_work_time) {
|
| - // We know that we can't be blocked right now since this method can only be
|
| - // called on the same thread as Run, so we only need to update our record of
|
| - // how long to sleep when we do sleep.
|
| - delayed_work_time_ = delayed_work_time;
|
| -}
|
| -
|
| -//-----------------------------------------------------------------------------
|
| -// MessagePumpForGpu private:
|
| -
|
| -void MessagePumpForGpu::DoRunLoop() {
|
| - while (!state_->should_quit) {
|
| - // Indicate that the loop is handling the work.
|
| - // If there is a race condition between switching to WORKING state here and
|
| - // the producer thread setting the HAVE_WORK state after exiting the wait,
|
| - // the event might remain in the signalled state. That might be less than
|
| - // optimal but wouldn't result in failing to handle the work.
|
| - InterlockedExchange(&work_state_, WORKING);
|
| -
|
| - bool more_work_is_plausible = state_->delegate->DoWork();
|
| - if (state_->should_quit)
|
| - break;
|
| -
|
| - more_work_is_plausible |=
|
| - state_->delegate->DoDelayedWork(&delayed_work_time_);
|
| - if (state_->should_quit)
|
| - break;
|
| -
|
| - if (more_work_is_plausible)
|
| - continue;
|
| -
|
| - more_work_is_plausible = state_->delegate->DoIdleWork();
|
| - if (state_->should_quit)
|
| - break;
|
| -
|
| - if (more_work_is_plausible)
|
| - continue;
|
| -
|
| - // Switch that working state to READY to indicate that the loop is
|
| - // waiting for accepting new work if it is still in WORKING state and hasn't
|
| - // been signalled. Otherwise if it is in HAVE_WORK state skip the wait
|
| - // and proceed to handing the work.
|
| - if (InterlockedCompareExchange(&work_state_, READY, WORKING) == HAVE_WORK)
|
| - continue; // Skip wait, more work was requested.
|
| -
|
| - WaitForWork(); // Wait (sleep) until we have work to do again.
|
| - }
|
| -}
|
| -
|
| -void MessagePumpForGpu::WaitForWork() {
|
| - // Wait until a message is available, up to the time needed by the timer
|
| - // manager to fire the next set of timers.
|
| - int delay;
|
| -
|
| - // The while loop handles the situation where on Windows 7 and later versions
|
| - // MsgWaitForMultipleObjectsEx might time out slightly earlier (less than one
|
| - // ms) than the specified |delay|. In that situation it is more optimal to
|
| - // just wait again rather than waste a DoRunLoop cycle.
|
| - while ((delay = GetCurrentDelay()) != 0) {
|
| - if (delay < 0) // Negative value means no timers waiting.
|
| - delay = INFINITE;
|
| -
|
| - DWORD result = MsgWaitForMultipleObjectsEx(0, NULL, delay, QS_ALLINPUT, 0);
|
| - if (result == WAIT_OBJECT_0) {
|
| - // A WM_* message is available.
|
| - if (ProcessMessages())
|
| - return;
|
| - }
|
| -
|
| - DCHECK_NE(WAIT_FAILED, result) << GetLastError();
|
| - }
|
| -}
|
| -
|
| -bool MessagePumpForGpu::ProcessMessages() {
|
| - MSG msg;
|
| - bool have_work = false;
|
| - while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
| - if (msg.message == WM_QUIT) {
|
| - // Repost the QUIT message so that it will be retrieved by the primary
|
| - // GetMessage() loop.
|
| - state_->should_quit = true;
|
| - PostQuitMessage(static_cast<int>(msg.wParam));
|
| - return true;
|
| - }
|
| -
|
| - if (msg.hwnd == nullptr && msg.message == kMsgHaveWork) {
|
| - have_work = true;
|
| - } else {
|
| - if (!CallMsgFilter(const_cast<MSG*>(&msg), kMessageFilterCode)) {
|
| - TranslateMessage(&msg);
|
| - DispatchMessage(&msg);
|
| - }
|
| - }
|
| - }
|
| -
|
| - return have_work;
|
| -}
|
| -
|
| -//-----------------------------------------------------------------------------
|
| // MessagePumpForIO public:
|
|
|
| MessagePumpForIO::MessagePumpForIO() {
|
| @@ -566,7 +423,7 @@
|
| }
|
|
|
| void MessagePumpForIO::ScheduleWork() {
|
| - if (InterlockedExchange(&work_state_, HAVE_WORK) != READY)
|
| + if (InterlockedExchange(&have_work_, 1))
|
| return; // Someone else continued the pumping.
|
|
|
| // Make sure the MessagePump does some work for us.
|
| @@ -577,7 +434,7 @@
|
| return; // Post worked perfectly.
|
|
|
| // See comment in MessagePumpForUI::ScheduleWork() for this error recovery.
|
| - InterlockedExchange(&work_state_, READY); // Clarify that we didn't succeed.
|
| + InterlockedExchange(&have_work_, 0); // Clarify that we didn't succeed.
|
| UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", COMPLETION_POST_ERROR,
|
| MESSAGE_LOOP_PROBLEM_MAX);
|
| }
|
| @@ -722,7 +579,7 @@
|
| reinterpret_cast<void*>(this) == reinterpret_cast<void*>(item.handler)) {
|
| // This is our internal completion.
|
| DCHECK(!item.bytes_transfered);
|
| - InterlockedExchange(&work_state_, READY);
|
| + InterlockedExchange(&have_work_, 0);
|
| return true;
|
| }
|
| return false;
|
|
|