diff options
author | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-20 16:28:48 +0000 |
---|---|---|
committer | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-20 16:28:48 +0000 |
commit | fec91f427124ff5d863895f1d0b2b89fb6fc2e13 (patch) | |
tree | 0c325897dfb8ce5249165ef905612cb6daa2268d /base | |
parent | 4a6193ae832eb741bcd3bd4db4285f3c57e7ad3a (diff) | |
download | chromium_src-fec91f427124ff5d863895f1d0b2b89fb6fc2e13.zip chromium_src-fec91f427124ff5d863895f1d0b2b89fb6fc2e13.tar.gz chromium_src-fec91f427124ff5d863895f1d0b2b89fb6fc2e13.tar.bz2 |
Handle rare conditions, like message queue exhaustion
bug=128734
r=rvargas
Review URL: https://chromiumcodereview.appspot.com/10392163
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138063 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/message_pump_win.cc | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/base/message_pump_win.cc b/base/message_pump_win.cc index fc65d84..88172b3 100644 --- a/base/message_pump_win.cc +++ b/base/message_pump_win.cc @@ -11,6 +11,17 @@ #include "base/process_util.h" #include "base/win/wrapped_window_proc.h" +namespace { + +enum MessageLoopProblems { + MESSAGE_POST_ERROR, + COMPLETION_POST_ERROR, + SET_TIMER_ERROR, + MESSAGE_LOOP_PROBLEM_MAX, +}; + +} // namespace + namespace base { static const wchar_t kWndClass[] = L"Chrome_MessagePumpWindow"; @@ -97,7 +108,22 @@ void MessagePumpForUI::ScheduleWork() { return; // Someone else continued the pumping. // Make sure the MessagePump does some work for us. - PostMessage(message_hwnd_, kMsgHaveWork, reinterpret_cast<WPARAM>(this), 0); + BOOL ret = PostMessage(message_hwnd_, kMsgHaveWork, + reinterpret_cast<WPARAM>(this), 0); + if (ret) + return; // There was room in the Window Message queue. + + // We have failed to insert a have-work message, so there is a chance that we + // will starve tasks/timers while sitting in a nested message loop. Nested + // loops only look at Windows Message queues, and don't look at *our* task + // queues, etc., so we might not get a time slice in such. :-( + // We could abort here, but the fear is that this failure mode is plausibly + // 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. + InterlockedExchange(&have_work_, 0); // Clarify that we didn't really insert. + UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", MESSAGE_POST_ERROR, + MESSAGE_LOOP_PROBLEM_MAX); } void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) { @@ -130,7 +156,15 @@ void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) { // Create a WM_TIMER event that will wake us up to check for any pending // timers (in case we are running within a nested, external sub-pump). - SetTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this), delay_msec, NULL); + BOOL ret = SetTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this), + delay_msec, NULL); + if (ret) + return; + // If we can't set timers, we are in big trouble... but cross our fingers for + // now. + // TODO(jar): If we don't see this error, use a CHECK() here instead. + UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", SET_TIMER_ERROR, + MESSAGE_LOOP_PROBLEM_MAX); } void MessagePumpForUI::PumpOutPendingPaintMessages() { @@ -420,7 +454,13 @@ void MessagePumpForIO::ScheduleWork() { BOOL ret = PostQueuedCompletionStatus(port_, 0, reinterpret_cast<ULONG_PTR>(this), reinterpret_cast<OVERLAPPED*>(this)); - DCHECK(ret); + if (ret) + return; // Post worked perfectly. + + // See comment in MessagePumpForUI::ScheduleWork() for this error recovery. + InterlockedExchange(&have_work_, 0); // Clarify that we didn't succeed. + UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", COMPLETION_POST_ERROR, + MESSAGE_LOOP_PROBLEM_MAX); } void MessagePumpForIO::ScheduleDelayedWork(const TimeTicks& delayed_work_time) { |