#pragma once #include #include #include #include #include #include namespace impl { extern std::atomic NextHandle; } template class DBusEvent { public: using Callback=std::function; using Handle=uint64_t; Handle add(Callback&&cb) { auto handle = impl::NextHandle.fetch_add(1,std::memory_order::acq_rel); { std::lock_guard lock{m}; callbacks[handle] = std::make_shared(std::move(cb)); } return handle; } void remove(Handle h) { std::lock_guard lock{m}; callbacks.erase(h); } void fire(ARG_TYPES...args) { std::vector> cbs; cbs.reserve(callbacks.size()); { std::lock_guard lock{m}; for (const auto &cb: callbacks) { cbs.push_back(cb.second); } } for (auto&cb: cbs) { (*cb)(args...); } { // destruct shared_ptrs with mutex held. std::lock_guard lock{m}; cbs.clear(); } } private: std::map> callbacks; std::mutex m; };