From ba92eb1ab796901064dd76c895a75faa552581d3 Mon Sep 17 00:00:00 2001 From: "dkegel@google.com" Date: Fri, 6 Nov 2009 21:53:52 +0000 Subject: 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 --- base/message_pump_libevent.cc | 15 ++++++++++++++- tools/valgrind/memcheck/suppressions.txt | 8 -------- 2 files changed, 14 insertions(+), 9 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 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. diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt index fcf605f..1a2538d 100644 --- a/tools/valgrind/memcheck/suppressions.txt +++ b/tools/valgrind/memcheck/suppressions.txt @@ -242,14 +242,6 @@ fun:openDatabase } { - libevent does not provide a way to clean up unused oneshot timers at exit - Memcheck:Leak - fun:calloc - fun:event_base_once - fun:event_base_loopexit - fun:_ZN4base19MessagePumpLibevent3RunEPNS_11MessagePump8DelegateE -} -{ # array of weak references freed but not processed? bug_16576 Memcheck:Leak -- cgit v1.1