summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authordkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-06 21:53:52 +0000
committerdkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-06 21:53:52 +0000
commitba92eb1ab796901064dd76c895a75faa552581d3 (patch)
treeffa0a25e4a970ae3b4aedabf16c79c85dbbdf8ff /base
parent22eb9681c29d15336d3579b84f417c462d4e8667 (diff)
downloadchromium_src-ba92eb1ab796901064dd76c895a75faa552581d3.zip
chromium_src-ba92eb1ab796901064dd76c895a75faa552581d3.tar.gz
chromium_src-ba92eb1ab796901064dd76c895a75faa552581d3.tar.bz2
Cancel unused timeout events. Without this change they can
accumulate for a while, wasting memory and causing unneeded wakeups. BUG=25641 TEST=green valgrind or heapchecker on net_unittests Previously reviewed as http://codereview.chromium.org/370005/ TBR=timurrrr Review URL: http://codereview.chromium.org/372033 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31306 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/message_pump_libevent.cc15
1 files changed, 14 insertions, 1 deletions
diff --git a/base/message_pump_libevent.cc b/base/message_pump_libevent.cc
index ddb2a2d..eae77f4 100644
--- a/base/message_pump_libevent.cc
+++ b/base/message_pump_libevent.cc
@@ -215,6 +215,12 @@ void MessagePumpLibevent::OnLibeventNotification(int fd, short flags,
}
}
+// Tell libevent to break out of inner loop.
+static void timer_callback(int fd, short events, void *context)
+{
+ event_base_loopbreak((struct event_base *)context);
+}
+
// Reentrant!
void MessagePumpLibevent::Run(Delegate* delegate) {
DCHECK(keep_running_) << "Quit must have been called outside of Run!";
@@ -222,6 +228,10 @@ void MessagePumpLibevent::Run(Delegate* delegate) {
bool old_in_run = in_run_;
in_run_ = true;
+ // event_base_loopexit() + EVLOOP_ONCE is leaky, see http://crbug.com/25641.
+ // Instead, make our own timer and reuse it on each call to event_base_loop().
+ scoped_ptr<event> timer_event(new event);
+
for (;;) {
ScopedNSAutoreleasePool autorelease_pool;
@@ -253,8 +263,11 @@ void MessagePumpLibevent::Run(Delegate* delegate) {
struct timeval poll_tv;
poll_tv.tv_sec = delay.InSeconds();
poll_tv.tv_usec = delay.InMicroseconds() % Time::kMicrosecondsPerSecond;
- event_base_loopexit(event_base_, &poll_tv);
+ event_set(timer_event.get(), -1, 0, timer_callback, event_base_);
+ event_base_set(event_base_, timer_event.get());
+ event_add(timer_event.get(), &poll_tv);
event_base_loop(event_base_, EVLOOP_ONCE);
+ event_del(timer_event.get());
} else {
// It looks like delayed_work_time_ indicates a time in the past, so we
// need to call DoDelayedWork now.