19#include "wpi/util/raw_ostream.hpp"
23template <
typename Callback>
45template <
typename Derived,
typename TUserInfo,
46 typename TListenerData =
48 typename TNotifierData = TUserInfo>
55 CallbackThread(std::function<
void()> on_start, std::function<
void()> on_exit)
60 for (
size_t i = 0; i <
m_pollers.size(); ++i) {
71 std::queue<std::pair<unsigned int, NotifierData>>
m_queue;
94 template <
typename... Args>
95 void SendPoller(
unsigned int poller_uid, Args&&... args) {
104 std::scoped_lock lock(poller->poll_mutex);
105 poller->poll_queue.emplace(std::forward<Args>(args)...);
107 poller->poll_cond.notify_one();
111template <
typename Derived,
typename TUserInfo,
typename TListenerData,
112 typename TNotifierData>
118 std::unique_lock lock(
m_mutex);
131 auto item = std::move(
m_queue.front());
133 if (item.first != UINT_MAX) {
137 static_cast<Derived*
>(
this)->Matches(listener, item.second)) {
138 static_cast<Derived*
>(
this)->SetListener(&item.second, item.first);
139 if (listener.callback) {
141 static_cast<Derived*
>(
this)->DoCallback(listener.callback,
144 }
else if (listener.poller_uid != UINT_MAX) {
145 SendPoller(listener.poller_uid, std::move(item.second));
157 if (!
static_cast<Derived*
>(
this)->Matches(listener, item.second)) {
160 static_cast<Derived*
>(
this)->SetListener(&item.second,
161 static_cast<unsigned>(i));
162 if (listener.callback) {
164 static_cast<Derived*
>(
this)->DoCallback(listener.callback,
167 }
else if (listener.poller_uid != UINT_MAX) {
190template <
typename Derived,
typename Thread>
196 m_on_start = std::move(on_start);
200 m_on_exit = std::move(on_exit);
203 void Stop() { m_owner.Stop(); }
206 auto thr = m_owner.GetThread();
210 thr->m_listeners.erase(listener_uid);
214 static_cast<Derived*
>(
this)->Start();
215 auto thr = m_owner.GetThread();
216 return thr->m_pollers.emplace_back(
217 std::make_shared<typename Thread::Poller>());
221 auto thr = m_owner.GetThread();
227 for (
size_t i = 0; i < thr->m_listeners.size(); ++i) {
228 if (thr->m_listeners[i].poller_uid == poller_uid) {
229 thr->m_listeners.erase(i);
234 if (poller_uid >= thr->m_pollers.size()) {
237 auto poller = thr->m_pollers[poller_uid];
242 thr->m_pollers.erase(poller_uid);
246 auto thr = m_owner.GetThread();
251 auto& lock = thr.GetLock();
252 auto timeout_time = std::chrono::steady_clock::now() +
253 std::chrono::duration<double>(timeout);
254 while (!thr->m_queue.empty()) {
255 if (!thr->m_active) {
262 thr->m_queue_empty.wait(lock);
264 auto cond_timed_out = thr->m_queue_empty.wait_until(lock, timeout_time);
265 if (cond_timed_out == std::cv_status::timeout) {
274 std::vector<typename Thread::UserInfo>
Poll(
unsigned int poller_uid) {
275 bool timed_out =
false;
276 return Poll(poller_uid, -1, &timed_out);
279 std::vector<typename Thread::UserInfo>
Poll(
unsigned int poller_uid,
280 double timeout,
bool* timed_out) {
281 std::vector<typename Thread::UserInfo> infos;
282 std::shared_ptr<typename Thread::Poller> poller;
284 auto thr = m_owner.GetThread();
288 if (poller_uid > thr->m_pollers.size()) {
291 poller = thr->m_pollers[poller_uid];
297 std::unique_lock lock(poller->poll_mutex);
298 auto timeout_time = std::chrono::steady_clock::now() +
299 std::chrono::duration<double>(timeout);
301 while (poller->poll_queue.empty()) {
302 if (poller->terminating) {
305 if (poller->canceling) {
308 poller->canceling =
false;
316 poller->poll_cond.wait(lock);
318 auto cond_timed_out = poller->poll_cond.wait_until(lock, timeout_time);
319 if (cond_timed_out == std::cv_status::timeout) {
326 while (!poller->poll_queue.empty()) {
327 infos.emplace_back(std::move(poller->poll_queue.front()));
328 poller->poll_queue.pop();
334 std::shared_ptr<typename Thread::Poller> poller;
336 auto thr = m_owner.GetThread();
340 if (poller_uid > thr->m_pollers.size()) {
343 poller = thr->m_pollers[poller_uid];
350 std::scoped_lock lock(poller->poll_mutex);
351 poller->canceling =
true;
353 poller->poll_cond.notify_one();
357 template <
typename... Args>
359 m_owner.Start(m_on_start, m_on_exit, std::forward<Args>(args)...);
362 template <
typename... Args>
363 unsigned int DoAdd(Args&&... args) {
364 static_cast<Derived*
>(
this)->Start();
365 auto thr = m_owner.GetThread();
366 return thr->m_listeners.emplace_back(std::forward<Args>(args)...);
369 template <
typename... Args>
370 void Send(
unsigned int only_listener, Args&&... args) {
371 auto thr = m_owner.GetThread();
372 if (!thr || thr->m_listeners.empty()) {
375 thr->m_queue.emplace(std::piecewise_construct,
376 std::make_tuple(only_listener),
377 std::forward_as_tuple(std::forward<Args>(args)...));
378 thr->m_cond.notify_one();
388 std::function<void()> m_on_start;
389 std::function<void()> m_on_exit;
Definition CallbackManager.hpp:24
unsigned int poller_uid
Definition CallbackManager.hpp:34
CallbackListenerData(Callback callback_)
Definition CallbackManager.hpp:27
Callback callback
Definition CallbackManager.hpp:33
CallbackListenerData()=default
CallbackListenerData(unsigned int poller_uid_)
Definition CallbackManager.hpp:28
Definition CallbackManager.hpp:191
std::vector< typename Thread::UserInfo > Poll(unsigned int poller_uid)
Definition CallbackManager.hpp:274
void SetOnStart(std::function< void()> on_start)
Definition CallbackManager.hpp:195
unsigned int CreatePoller()
Definition CallbackManager.hpp:213
void SetOnExit(std::function< void()> on_exit)
Definition CallbackManager.hpp:199
void CancelPoll(unsigned int poller_uid)
Definition CallbackManager.hpp:333
void Stop()
Definition CallbackManager.hpp:203
void DoStart(Args &&... args)
Definition CallbackManager.hpp:358
bool WaitForQueue(double timeout)
Definition CallbackManager.hpp:245
friend class RpcServerTest
Definition CallbackManager.hpp:192
void Remove(unsigned int listener_uid)
Definition CallbackManager.hpp:205
wpi::util::SafeThreadOwner< Thread >::Proxy GetThread() const
Definition CallbackManager.hpp:381
void RemovePoller(unsigned int poller_uid)
Definition CallbackManager.hpp:220
void Send(unsigned int only_listener, Args &&... args)
Definition CallbackManager.hpp:370
std::vector< typename Thread::UserInfo > Poll(unsigned int poller_uid, double timeout, bool *timed_out)
Definition CallbackManager.hpp:279
unsigned int DoAdd(Args &&... args)
Definition CallbackManager.hpp:363
CallbackThread(std::function< void()> on_start, std::function< void()> on_exit)
Definition CallbackManager.hpp:55
TListenerData ListenerData
Definition CallbackManager.hpp:53
wpi::util::UidVector< ListenerData, 64 > m_listeners
Definition CallbackManager.hpp:69
std::function< void()> m_on_start
Definition CallbackManager.hpp:90
wpi::util::condition_variable m_queue_empty
Definition CallbackManager.hpp:72
void Main() override
Definition CallbackManager.hpp:113
std::function< void()> m_on_exit
Definition CallbackManager.hpp:91
wpi::util::UidVector< std::shared_ptr< Poller >, 64 > m_pollers
Definition CallbackManager.hpp:88
void SendPoller(unsigned int poller_uid, Args &&... args)
Definition CallbackManager.hpp:95
std::queue< std::pair< unsigned int, NotifierData > > m_queue
Definition CallbackManager.hpp:71
~CallbackThread() override
Definition CallbackManager.hpp:58
TUserInfo UserInfo
Definition CallbackManager.hpp:51
TNotifierData NotifierData
Definition CallbackManager.hpp:52
wpi::util::mutex m_mutex
Definition SafeThread.hpp:27
std::atomic_bool m_active
Definition SafeThread.hpp:28
Definition SafeThread.hpp:32
wpi::util::condition_variable m_cond
Definition SafeThread.hpp:36
Definition SafeThread.hpp:123
typename detail::SafeThreadProxy< T > Proxy
Definition SafeThread.hpp:131
Proxy GetThread() const
Definition SafeThread.hpp:132
Vector which provides an integrated freelist for removal and reuse of individual elements.
Definition UidVector.hpp:72
Definition StringMap.hpp:773
Definition raw_os_ostream.hpp:19
::std::condition_variable condition_variable
Definition condition_variable.hpp:16
::std::mutex mutex
Definition mutex.hpp:17
Definition CallbackManager.hpp:74
bool terminating
Definition CallbackManager.hpp:85
void Terminate()
Definition CallbackManager.hpp:75
bool canceling
Definition CallbackManager.hpp:86
wpi::util::condition_variable poll_cond
Definition CallbackManager.hpp:84
wpi::util::mutex poll_mutex
Definition CallbackManager.hpp:83
std::queue< NotifierData > poll_queue
Definition CallbackManager.hpp:82