File: bind_post_task.h

package info (click to toggle)
chromium 139.0.7258.138-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,120,676 kB
  • sloc: cpp: 35,100,869; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (116 lines) | stat: -rw-r--r-- 4,375 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_BIND_POST_TASK_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_BIND_POST_TASK_H_

#include <memory>
#include <utility>

#include "base/functional/callback.h"
#include "base/location.h"
#include "base/task/sequenced_task_runner.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_std.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"

// See base::BindPostTask() for docs, this is the WTF cross-thread version.

namespace WTF {

namespace internal {

// Based on base::internal::BindPostTaskTrampoline with modifications for
// CrossThreadFunction/CrossThreadOnceFunction. CrossThreadOnceFunction works
// identically to the base version, but CrossThreadFunction is not copyable or
// convertible to a CrossThreadOnceFunction, so a task must be posted to run it
// instead of directly passing it to `task_runner`. Safety is guaranteed by
// ensuring CrossThreadBindPostTaskTrampoline is destructed on `task_runner`.
template <typename CallbackType>
class CrossThreadBindPostTaskTrampoline {
 public:
  CrossThreadBindPostTaskTrampoline(
      scoped_refptr<base::SequencedTaskRunner> task_runner,
      const base::Location& location,
      CallbackType callback)
      : task_runner_(std::move(task_runner)),
        location_(location),
        callback_(std::move(callback)) {
    DCHECK(task_runner_);
    CHECK(callback_);
  }
  ~CrossThreadBindPostTaskTrampoline() {
    DCHECK(task_runner_->RunsTasksInCurrentSequence());
  }

  CrossThreadBindPostTaskTrampoline(
      const CrossThreadBindPostTaskTrampoline& other) = delete;
  CrossThreadBindPostTaskTrampoline& operator=(
      const CrossThreadBindPostTaskTrampoline& other) = delete;

  template <typename... Args>
  void RunOnce(Args... args) {
    task_runner_->PostTask(
        location_, ConvertToBaseOnceCallback(CrossThreadBindOnce(
                       std::move(callback_), std::forward<Args>(args)...)));
  }

  template <typename... Args>
  void RunRepeating(Args... args) {
    // Safe since the destruction of `this` is posted to `task_runner_`.
    task_runner_->PostTask(
        location_,
        ConvertToBaseOnceCallback(CrossThreadBindOnce(
            &RunOnTaskRunner<Args...>, CrossThreadUnretained(&callback_),
            std::forward<Args>(args)...)));
  }

 private:
  template <typename... Args>
  static void RunOnTaskRunner(CallbackType* callback, Args... args) {
    callback->Run(std::forward<Args>(args)...);
  }

  const scoped_refptr<base::SequencedTaskRunner> task_runner_;
  const base::Location location_;
  CallbackType callback_;
};

}  // namespace internal

template <typename ReturnType, typename... Args>
  requires std::is_void_v<ReturnType>
CrossThreadOnceFunction<void(Args...)> BindPostTask(
    scoped_refptr<base::SequencedTaskRunner> task_runner,
    CrossThreadOnceFunction<ReturnType(Args...)> callback,
    const base::Location& location = FROM_HERE) {
  using Helper = internal::CrossThreadBindPostTaskTrampoline<
      CrossThreadOnceFunction<void(Args...)>>;

  std::unique_ptr<Helper, base::OnTaskRunnerDeleter> helper(
      new Helper(task_runner, location, std::move(callback)),
      base::OnTaskRunnerDeleter(task_runner));
  return CrossThreadBindOnce(&Helper::template RunOnce<Args...>,
                             std::move(helper));
}

template <typename ReturnType, typename... Args>
  requires std::is_void_v<ReturnType>
CrossThreadFunction<void(Args...)> BindPostTask(
    scoped_refptr<base::SequencedTaskRunner> task_runner,
    CrossThreadFunction<ReturnType(Args...)> callback,
    const base::Location& location = FROM_HERE) {
  using Helper = internal::CrossThreadBindPostTaskTrampoline<
      CrossThreadFunction<void(Args...)>>;

  std::unique_ptr<Helper, base::OnTaskRunnerDeleter> helper(
      new Helper(task_runner, location, std::move(callback)),
      base::OnTaskRunnerDeleter(task_runner));
  return CrossThreadBindRepeating(&Helper::template RunRepeating<Args...>,
                                  std::move(helper));
}

}  // namespace WTF

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_BIND_POST_TASK_H_