event/DeferredMonitor: make fully thread-safe
Instead of creating a new eventfd for each DeferredMonitor instance, reuse EventLoop's eventfd, and add a std::list to EventLoop that manages the list of pending DeferredMonitors. This std::list is protected by the same mutex as the "calls" list. The bottom line is: reduced overhead because the per-instance eventfd was eliminated, slightly added overhead due to Mutex usage (but negligible), and we're thread-safe now. This subsystem is now good enough to replace EventLoop::AddCall().
This commit is contained in:
@@ -25,7 +25,7 @@ void
|
||||
DeferredMonitor::Cancel()
|
||||
{
|
||||
#ifdef USE_INTERNAL_EVENTLOOP
|
||||
pending = false;
|
||||
loop.RemoveDeferred(*this);
|
||||
#endif
|
||||
#ifdef USE_GLIB_EVENTLOOP
|
||||
const auto id = source_id.exchange(0);
|
||||
@@ -38,8 +38,7 @@ void
|
||||
DeferredMonitor::Schedule()
|
||||
{
|
||||
#ifdef USE_INTERNAL_EVENTLOOP
|
||||
if (!pending.exchange(true))
|
||||
fd.Write();
|
||||
loop.AddDeferred(*this);
|
||||
#endif
|
||||
#ifdef USE_GLIB_EVENTLOOP
|
||||
const unsigned id = loop.AddIdle(Callback, this);
|
||||
@@ -49,21 +48,6 @@ DeferredMonitor::Schedule()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_INTERNAL_EVENTLOOP
|
||||
|
||||
bool
|
||||
DeferredMonitor::OnSocketReady(unsigned)
|
||||
{
|
||||
fd.Read();
|
||||
|
||||
if (pending.exchange(false))
|
||||
RunDeferred();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_GLIB_EVENTLOOP
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user