Thanks to visit codestin.com
Credit goes to chromium.googlesource.com

blob: 25c7d8cad8b1ce8e3d4531ad83fc6d069d26cb7f [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2013 The Chromium Authors
[email protected]4a10006a2013-05-17 23:18:352// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Christopher Lamebb90202019-04-04 03:42:365#include "base/one_shot_event.h"
[email protected]4a10006a2013-05-17 23:18:356
avi2d124c02015-12-23 06:36:427#include <stddef.h>
Luke Klimek965c89d42024-06-14 12:44:478
9#include <algorithm>
Karandeep Bhatia57a637c2020-04-20 23:07:1210#include <utility>
avi2d124c02015-12-23 06:36:4211
Avi Drissman63e1f992023-01-13 18:54:4312#include "base/functional/callback.h"
[email protected]4a10006a2013-05-17 23:18:3513#include "base/location.h"
Luke Klimek965c89d42024-06-14 12:44:4714#include "base/sequence_checker.h"
Patrick Monette643cdf62021-10-15 19:13:4215#include "base/task/task_runner.h"
[email protected]e5f8fffe2014-04-02 00:30:4416#include "base/time/time.h"
[email protected]4a10006a2013-05-17 23:18:3517
Christopher Lamebb90202019-04-04 03:42:3618namespace base {
[email protected]4a10006a2013-05-17 23:18:3519
20struct OneShotEvent::TaskInfo {
Luke Klimek965c89d42024-06-14 12:44:4721 TaskInfo() = default;
Christopher Lamebb90202019-04-04 03:42:3622 TaskInfo(const Location& from_here,
Luke Klimek965c89d42024-06-14 12:44:4723 scoped_refptr<TaskRunner> runner,
Christopher Lamebb90202019-04-04 03:42:3624 OnceClosure task,
25 const TimeDelta& delay)
Mikel Astize05037e2019-03-29 20:44:2426 : from_here(from_here),
Karandeep Bhatia57a637c2020-04-20 23:07:1227 runner(std::move(runner)),
Mikel Astize05037e2019-03-29 20:44:2428 task(std::move(task)),
29 delay(delay) {
Luke Klimek965c89d42024-06-14 12:44:4730 CHECK(this->runner); // Detect mistakes with a decent stack frame.
[email protected]4a10006a2013-05-17 23:18:3531 }
Mikel Astize05037e2019-03-29 20:44:2432 TaskInfo(TaskInfo&&) = default;
Karandeep Bhatia57a637c2020-04-20 23:07:1233 TaskInfo& operator=(TaskInfo&&) = default;
Mikel Astize05037e2019-03-29 20:44:2434
Christopher Lamebb90202019-04-04 03:42:3635 Location from_here;
Luke Klimek965c89d42024-06-14 12:44:4736 scoped_refptr<TaskRunner> runner;
Christopher Lamebb90202019-04-04 03:42:3637 OnceClosure task;
38 TimeDelta delay;
[email protected]4a10006a2013-05-17 23:18:3539};
40
Luke Klimek965c89d42024-06-14 12:44:4741OneShotEvent::OneShotEvent() {
42 // It's acceptable to construct the `OneShotEvent` on one sequence, but
43 // immediately move it to another sequence.
44 DETACH_FROM_SEQUENCE(sequence_checker_);
[email protected]89c44672e2013-05-23 04:32:0945}
[email protected]ebf16b22013-12-19 09:46:0146OneShotEvent::OneShotEvent(bool signaled) : signaled_(signaled) {
Luke Klimek965c89d42024-06-14 12:44:4747 DETACH_FROM_SEQUENCE(sequence_checker_);
[email protected]ebf16b22013-12-19 09:46:0148}
Luke Klimek965c89d42024-06-14 12:44:4749OneShotEvent::~OneShotEvent() = default;
[email protected]4a10006a2013-05-17 23:18:3550
Karandeep Bhatia57a637c2020-04-20 23:07:1251void OneShotEvent::Post(const Location& from_here,
52 OnceClosure task,
Luke Klimek965c89d42024-06-14 12:44:4753 scoped_refptr<TaskRunner> runner) const {
54 PostDelayed(from_here, std::move(task), TimeDelta(), std::move(runner));
[email protected]e5f8fffe2014-04-02 00:30:4455}
[email protected]4a10006a2013-05-17 23:18:3556
Christopher Lamebb90202019-04-04 03:42:3657void OneShotEvent::PostDelayed(const Location& from_here,
58 OnceClosure task,
Luke Klimek965c89d42024-06-14 12:44:4759 const TimeDelta& delay,
60 scoped_refptr<TaskRunner> runner) const {
61 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
62
63 if (is_signaled()) {
64 runner->PostDelayedTask(from_here, std::move(task), delay);
65 } else {
66 tasks_.emplace_back(from_here, std::move(runner), std::move(task), delay);
67 }
[email protected]4a10006a2013-05-17 23:18:3568}
69
70void OneShotEvent::Signal() {
Luke Klimek965c89d42024-06-14 12:44:4771 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]4a10006a2013-05-17 23:18:3572
73 CHECK(!signaled_) << "Only call Signal once.";
74
75 signaled_ = true;
Luke Klimek965c89d42024-06-14 12:44:4776 // After this point, a call to `Post` from one of the queued tasks could
77 // proceed immediately, but the fact that this object is sequence-bound
78 // prevents that from being relevant.
[email protected]4a10006a2013-05-17 23:18:3579
Istiaque Ahmede2ea8642018-06-18 22:00:1280 // Move tasks to a temporary to ensure no new ones are added.
Luke Klimek965c89d42024-06-14 12:44:4781 std::vector<TaskInfo> moved_tasks = std::exchange(tasks_, {});
Istiaque Ahmede2ea8642018-06-18 22:00:1282
83 // We could randomize tasks in debug mode in order to check that
[email protected]4a10006a2013-05-17 23:18:3584 // the order doesn't matter...
Mikel Astize05037e2019-03-29 20:44:2485 for (TaskInfo& task : moved_tasks) {
Luke Klimek965c89d42024-06-14 12:44:4786 task.runner->PostDelayedTask(task.from_here, std::move(task.task),
87 task.delay);
[email protected]e5f8fffe2014-04-02 00:30:4488 }
Istiaque Ahmede2ea8642018-06-18 22:00:1289 DCHECK(tasks_.empty()) << "No new tasks should be added during task running!";
[email protected]e5f8fffe2014-04-02 00:30:4490}
91
Christopher Lamebb90202019-04-04 03:42:3692} // namespace base