event/DeferEvent: use class IntrusiveList instead of boost::intrusive::list

This commit is contained in:
Max Kellermann 2020-12-01 16:56:58 +01:00
parent 774b4313f2
commit 990f2dc1cf
4 changed files with 25 additions and 49 deletions

View File

@ -20,14 +20,11 @@
#include "DeferEvent.hxx" #include "DeferEvent.hxx"
#include "Loop.hxx" #include "Loop.hxx"
void
DeferEvent::Cancel() noexcept
{
loop.RemoveDeferred(*this);
}
void void
DeferEvent::Schedule() noexcept DeferEvent::Schedule() noexcept
{ {
if (!IsPending())
loop.AddDeferred(*this); loop.AddDeferred(*this);
assert(IsPending());
} }

View File

@ -21,8 +21,7 @@
#define MPD_DEFER_EVENT_HXX #define MPD_DEFER_EVENT_HXX
#include "util/BindMethod.hxx" #include "util/BindMethod.hxx"
#include "util/IntrusiveList.hxx"
#include <boost/intrusive/list_hook.hpp>
class EventLoop; class EventLoop;
@ -34,10 +33,10 @@ class EventLoop;
* This class is not thread-safe, all methods must be called from the * This class is not thread-safe, all methods must be called from the
* thread that runs the #EventLoop. * thread that runs the #EventLoop.
*/ */
class DeferEvent final class DeferEvent final : AutoUnlinkIntrusiveListHook
: public boost::intrusive::list_base_hook<>
{ {
friend class EventLoop; friend class EventLoop;
friend class IntrusiveList<DeferEvent>;
EventLoop &loop; EventLoop &loop;
@ -51,23 +50,23 @@ public:
DeferEvent(const DeferEvent &) = delete; DeferEvent(const DeferEvent &) = delete;
DeferEvent &operator=(const DeferEvent &) = delete; DeferEvent &operator=(const DeferEvent &) = delete;
~DeferEvent() noexcept { auto &GetEventLoop() const noexcept {
Cancel();
}
EventLoop &GetEventLoop() const noexcept {
return loop; return loop;
} }
void Schedule() noexcept;
void Cancel() noexcept;
private:
bool IsPending() const noexcept { bool IsPending() const noexcept {
return is_linked(); return is_linked();
} }
void RunDeferred() noexcept { void Schedule() noexcept;
void Cancel() noexcept {
if (IsPending())
unlink();
}
private:
void Run() noexcept {
callback(); callback();
} }
}; };

View File

@ -198,29 +198,17 @@ EventLoop::HandleTimers() noexcept
void void
EventLoop::AddDeferred(DeferEvent &d) noexcept EventLoop::AddDeferred(DeferEvent &d) noexcept
{ {
if (d.IsPending()) defer.push_back(d);
return;
deferred.push_back(d);
again = true; again = true;
} }
void
EventLoop::RemoveDeferred(DeferEvent &d) noexcept
{
if (d.IsPending())
deferred.erase(deferred.iterator_to(d));
}
void void
EventLoop::RunDeferred() noexcept EventLoop::RunDeferred() noexcept
{ {
while (!deferred.empty() && !quit) { while (!defer.empty() && !quit) {
auto &m = deferred.front(); defer.pop_front_and_dispose([](DeferEvent *e){
assert(m.IsPending()); e->Run();
});
deferred.pop_front();
m.RunDeferred();
} }
} }

View File

@ -79,11 +79,9 @@ class EventLoop final
boost::intrusive::constant_time_size<false>>; boost::intrusive::constant_time_size<false>>;
TimerSet timers; TimerSet timers;
using DeferList = using DeferList = IntrusiveList<DeferEvent>;
boost::intrusive::list<DeferEvent,
boost::intrusive::base_hook<boost::intrusive::list_base_hook<>>, DeferList defer;
boost::intrusive::constant_time_size<false>>;
DeferList deferred;
using IdleList = IntrusiveList<IdleEvent>; using IdleList = IntrusiveList<IdleEvent>;
IdleList idle; IdleList idle;
@ -214,12 +212,6 @@ public:
*/ */
void AddDeferred(DeferEvent &d) noexcept; void AddDeferred(DeferEvent &d) noexcept;
/**
* Cancel a pending call to DeferEvent::RunDeferred().
* However after returning, the call may still be running.
*/
void RemoveDeferred(DeferEvent &d) noexcept;
#ifdef HAVE_THREADED_EVENT_LOOP #ifdef HAVE_THREADED_EVENT_LOOP
/** /**
* Schedule a call to the InjectEvent. * Schedule a call to the InjectEvent.