| #ifndef PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_CALLBACK_MANAGER_H_ |
| #define PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_CALLBACK_MANAGER_H_ |
| |
| #include <list> |
| |
| #include "absl/base/nullability.h" |
| #include "absl/base/thread_annotations.h" |
| #include "absl/functional/any_invocable.h" |
| #include "absl/synchronization/mutex.h" |
| |
| namespace safepower_agent { |
| |
| class CallbackManager { |
| struct PrivateToken {}; |
| |
| public: |
| using Callback = absl::AnyInvocable<void() &&>; |
| |
| CallbackManager() = default; |
| CallbackManager(const CallbackManager&) = delete; |
| CallbackManager& operator=(const CallbackManager&) = delete; |
| CallbackManager(CallbackManager&&) = delete; |
| CallbackManager& operator=(CallbackManager&&) = delete; |
| |
| ~CallbackManager(); |
| |
| class [[nodiscard]] Handle { |
| public: |
| Handle() = default; |
| Handle(PrivateToken, CallbackManager& manager, |
| std::list<Callback>::iterator it); |
| Handle(Handle&& other); |
| Handle& operator=(Handle&& other); |
| ~Handle(); |
| |
| bool pending() const; |
| bool TryCancel(); |
| |
| private: |
| CallbackManager* manager_ = nullptr; |
| std::list<Callback>::iterator it_; |
| }; |
| |
| Handle RunFirst(Callback callback) |
| ABSL_LOCKS_EXCLUDED(mutex_); |
| Handle RunLast(Callback callback) |
| ABSL_LOCKS_EXCLUDED(mutex_); |
| void RunCallbacks() ABSL_LOCKS_EXCLUDED(mutex_); |
| |
| private: |
| friend class Handle; |
| absl::Mutex mutex_; |
| std::list<Callback> callbacks_ ABSL_GUARDED_BY(mutex_); |
| absl::Mutex running_mutex_ ABSL_ACQUIRED_BEFORE(mutex_); |
| }; |
| |
| } // namespace safepower_agent |
| |
| #endif // PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_CALLBACK_MANAGER_H_ |