diff --git a/include/mp/proxy-io.h b/include/mp/proxy-io.h index 092ea42e..ae008887 100644 --- a/include/mp/proxy-io.h +++ b/include/mp/proxy-io.h @@ -255,7 +255,7 @@ class EventLoop //! Run event loop. Does not return until shutdown. This should only be //! called once from the m_thread_id thread. This will block until - //! the m_num_clients reference count is 0. + //! the m_num_refs reference count is 0. void loop(); //! Run function on event loop thread. Does not return until function completes. @@ -314,9 +314,13 @@ class EventLoop //! Pipe write handle used to wake up the event loop thread. int m_post_fd = -1; - //! Number of clients holding references to ProxyServerBase objects that - //! reference this event loop. - int m_num_clients MP_GUARDED_BY(m_mutex) = 0; + //! Number of EventLoopRef instances referencing this event loop. This is a + //! sum of the number of client and server objects (Connection, ProxyClient, + //! ProxyServer) using the loop, plus temporary references held while + //! posting functions to the loop, plus any references held by external code + //! to keep the loop running. The loop() method exits when this count drops + //! to 0 (and m_async_fns is empty). + int m_num_refs MP_GUARDED_BY(m_mutex) = 0; //! Mutex and condition variable used to post tasks to event loop and async //! thread. diff --git a/include/mp/proxy.h b/include/mp/proxy.h index 4458ee9e..57362f4e 100644 --- a/include/mp/proxy.h +++ b/include/mp/proxy.h @@ -44,7 +44,7 @@ inline void CleanupRun(CleanupList& fns) { } } -//! Event loop smart pointer automatically managing m_num_clients. +//! Event loop smart pointer automatically managing m_num_refs. //! If a lock pointer argument is passed, the specified lock will be used, //! otherwise EventLoop::m_mutex will be locked when needed. class EventLoopRef diff --git a/src/mp/proxy.cpp b/src/mp/proxy.cpp index 963050c3..40cba975 100644 --- a/src/mp/proxy.cpp +++ b/src/mp/proxy.cpp @@ -51,7 +51,7 @@ EventLoopRef::EventLoopRef(EventLoop& loop, Lock* lock) : m_loop(&loop), m_lock( { auto loop_lock{PtrOrValue{m_lock, m_loop->m_mutex}}; loop_lock->assert_locked(m_loop->m_mutex); - m_loop->m_num_clients += 1; + m_loop->m_num_refs += 1; } // Due to the conditionals in this function, MP_NO_TSA is required to avoid @@ -63,8 +63,8 @@ void EventLoopRef::reset(bool relock) MP_NO_TSA m_loop = nullptr; auto loop_lock{PtrOrValue{m_lock, loop->m_mutex}}; loop_lock->assert_locked(loop->m_mutex); - assert(loop->m_num_clients > 0); - loop->m_num_clients -= 1; + assert(loop->m_num_refs > 0); + loop->m_num_refs -= 1; if (loop->done()) { loop->m_cv.notify_all(); int post_fd{loop->m_post_fd}; @@ -218,7 +218,7 @@ EventLoop::~EventLoop() KJ_ASSERT(!m_async_fns); KJ_ASSERT(m_wait_fd == -1); KJ_ASSERT(m_post_fd == -1); - KJ_ASSERT(m_num_clients == 0); + KJ_ASSERT(m_num_refs == 0); // Spin event loop. wait for any promises triggered by RPC shutdown. // auto cleanup = kj::evalLater([]{}); @@ -320,8 +320,8 @@ void EventLoop::startAsyncThread() bool EventLoop::done() const { - assert(m_num_clients >= 0); - return m_num_clients == 0 && m_async_fns->empty(); + assert(m_num_refs >= 0); + return m_num_refs == 0 && m_async_fns->empty(); } std::tuple SetThread(GuardedRef threads, Connection* connection, const std::function& make_thread)