mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2025-02-24 10:53:19 +03:00
106 lines
4.1 KiB
C
106 lines
4.1 KiB
C
|
// Copyright 2013 The Chromium Authors
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#ifndef BASE_ONE_SHOT_EVENT_H_
|
||
|
#define BASE_ONE_SHOT_EVENT_H_
|
||
|
|
||
|
#include <vector>
|
||
|
|
||
|
#include "base/base_export.h"
|
||
|
#include "base/check.h"
|
||
|
#include "base/functional/callback_forward.h"
|
||
|
#include "base/memory/weak_ptr.h"
|
||
|
#include "base/sequence_checker.h"
|
||
|
#include "base/task/sequenced_task_runner.h"
|
||
|
#include "base/task/single_thread_task_runner.h"
|
||
|
|
||
|
namespace base {
|
||
|
|
||
|
class Location;
|
||
|
class TimeDelta;
|
||
|
|
||
|
// This class represents an event that's expected to happen once. It allows
|
||
|
// clients to guarantee that code is run after the `OneShotEvent` is signaled.
|
||
|
// If the `OneShotEvent` is destroyed before it's signaled, the closures are
|
||
|
// destroyed without being run.
|
||
|
//
|
||
|
// This class is similar to a `WaitableEvent` combined with several
|
||
|
// `WaitableEventWatcher`s, but using it is simpler.
|
||
|
//
|
||
|
// This class' methods must be used from a single sequence (although not
|
||
|
// necessarily the one in which it has been constructed).
|
||
|
// However, there are no restrictions on the `TaskRunner`s used - and hence, the
|
||
|
// sequence/thread on which the posted tasks will run. By default they will
|
||
|
// be posted to the current sequence's default task runner.
|
||
|
class BASE_EXPORT OneShotEvent {
|
||
|
public:
|
||
|
OneShotEvent();
|
||
|
// Use the following constructor to create an already signaled event. This is
|
||
|
// useful if you construct the event on a different thread from where it is
|
||
|
// used, in which case it is not possible to call `Signal` just after
|
||
|
// construction.
|
||
|
explicit OneShotEvent(bool signaled);
|
||
|
~OneShotEvent();
|
||
|
|
||
|
// True if `Signal` has been called. This function is mostly for migrating old
|
||
|
// code; usually calling `Post` unconditionally will result in more readable
|
||
|
// code.
|
||
|
bool is_signaled() const {
|
||
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||
|
return signaled_;
|
||
|
}
|
||
|
|
||
|
// Causes `is_signaled` to return true and all tasks to be posted to their
|
||
|
// corresponding task runners in the FIFO order. Note that tasks posted to
|
||
|
// different `TaskRunner`s may still execute in arbitrary order. This
|
||
|
// method must only be called once.
|
||
|
void Signal();
|
||
|
|
||
|
// Schedules `task` to be called on `runner` after `is_signaled` becomes
|
||
|
// `true`. If called with `delay`, then the task will happen (roughly) `delay`
|
||
|
// after `is_signaled`, *not* `delay` after the post. Inside `task`, if this
|
||
|
// `OneShotEvent` is still alive, `CHECK(is_signaled())` will never fail
|
||
|
// (which implies that `OneShotEvent::Reset` doesn't exist).
|
||
|
//
|
||
|
// If `*this` is destroyed before being released, none of these tasks will be
|
||
|
// executed.
|
||
|
//
|
||
|
// Tasks are posted in FIFO order, however, tasks may still execute in an
|
||
|
// arbitrary order (specified by the combination and type of `TaskRunner`s
|
||
|
// used). Tasks will never be called on the current sequence before this
|
||
|
// function returns.
|
||
|
// Beware that there's no simple way to wait for all tasks on a `OneShotEvent`
|
||
|
// to complete, so it's almost never safe to use `base::Unretained` when
|
||
|
// creating one.
|
||
|
void Post(const Location& from_here,
|
||
|
OnceClosure task,
|
||
|
scoped_refptr<TaskRunner> runner =
|
||
|
SequencedTaskRunner::GetCurrentDefault()) const;
|
||
|
void PostDelayed(const Location& from_here,
|
||
|
OnceClosure task,
|
||
|
const TimeDelta& delay,
|
||
|
scoped_refptr<TaskRunner> runner =
|
||
|
SequencedTaskRunner::GetCurrentDefault()) const;
|
||
|
|
||
|
private:
|
||
|
struct TaskInfo;
|
||
|
SEQUENCE_CHECKER(sequence_checker_);
|
||
|
|
||
|
bool signaled_ = false;
|
||
|
|
||
|
// The task list is mutable because it's not part of the logical state of the
|
||
|
// object. This lets us return const references to the `OneShotEvent` to
|
||
|
// clients that just want to run tasks through it without worrying that
|
||
|
// they'll signal the event.
|
||
|
//
|
||
|
// Optimization note: We could reduce the size of this class to a single
|
||
|
// pointer by storing `signaled_` in the low bit of a pointer, and storing the
|
||
|
// size and capacity of the array (if any) on the far end of the pointer.
|
||
|
mutable std::vector<TaskInfo> tasks_;
|
||
|
};
|
||
|
|
||
|
} // namespace base
|
||
|
|
||
|
#endif // BASE_ONE_SHOT_EVENT_H_
|