#ifndef CHROME_RENDERER_CHROMEOS_DELAYED_CALLBACK_GROUP_H_
#define CHROME_RENDERER_CHROMEOS_DELAYED_CALLBACK_GROUP_H_
#include <functional>
#include <list>
#include <queue>
#include "base/cancelable_callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
namespace base {
class SequencedTaskRunner;
}
class DelayedCallbackGroup
: public base::RefCountedThreadSafe<DelayedCallbackGroup> {
public:
enum class RunReason {
NORMAL,
TIMEOUT
};
using Callback = base::OnceCallback<void(RunReason)>;
DelayedCallbackGroup(
base::TimeDelta expiration_delay,
scoped_refptr<base::SequencedTaskRunner> expiration_task_runner);
DelayedCallbackGroup(const DelayedCallbackGroup&) = delete;
DelayedCallbackGroup& operator=(const DelayedCallbackGroup&) = delete;
void Add(Callback callback);
void RunAll();
private:
friend class base::RefCountedThreadSafe<DelayedCallbackGroup>;
struct CallbackEntry {
CallbackEntry(
Callback callback,
const scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::TimeTicks expiration_time);
~CallbackEntry();
Callback callback_;
const scoped_refptr<base::SequencedTaskRunner> callback_task_runner_;
base::TimeTicks expiration_time_;
};
~DelayedCallbackGroup();
void StartExpirationTimer();
void CancelExpirationTimer();
void OnExpirationTimer();
void ProcessExpiredCallbacks(base::TimeTicks expiration_time);
void ExpireAllCallbacks() EXCLUSIVE_LOCKS_REQUIRED(callbacks_lock_);
std::queue<CallbackEntry, std::list<CallbackEntry>> callbacks_
GUARDED_BY(callbacks_lock_);
base::TimeDelta expiration_delay_ GUARDED_BY(callbacks_lock_);
base::CancelableOnceClosure expiration_timeout_;
mutable base::Lock callbacks_lock_;
scoped_refptr<base::SequencedTaskRunner> expiration_task_runner_;
SEQUENCE_CHECKER(sequence_checker_);
};
#endif