summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-20 16:28:48 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-20 16:28:48 +0000
commitfec91f427124ff5d863895f1d0b2b89fb6fc2e13 (patch)
tree0c325897dfb8ce5249165ef905612cb6daa2268d /base
parent4a6193ae832eb741bcd3bd4db4285f3c57e7ad3a (diff)
downloadchromium_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.cc46
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) {