12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef REMOTING_BASE_TASK_UTIL_H_
- #define REMOTING_BASE_TASK_UTIL_H_
- #include "base/bind.h"
- #include "base/threading/sequence_bound.h"
- #include "base/threading/sequenced_task_runner_handle.h"
- namespace remoting {
- // Wraps and returns a callback such that it will call the original callback on
- // the thread where this method is called.
- template <typename... Args>
- base::OnceCallback<void(Args...)> WrapCallbackToCurrentSequence(
- const base::Location& from_here,
- base::OnceCallback<void(Args...)> callback) {
- return base::BindOnce(
- [](scoped_refptr<base::SequencedTaskRunner> task_runner,
- const base::Location& from_here,
- base::OnceCallback<void(Args...)> callback, Args... args) {
- base::OnceClosure closure =
- base::BindOnce(std::move(callback), std::forward<Args>(args)...);
- if (task_runner->RunsTasksInCurrentSequence()) {
- std::move(closure).Run();
- return;
- }
- task_runner->PostTask(from_here, std::move(closure));
- },
- base::SequencedTaskRunnerHandle::Get(), from_here, std::move(callback));
- }
- // Similar to base::SequenceBound::Post, but executes the callback (which should
- // be the last method argument) on the sequence where the task is posted from.
- // Say if you want to call this method and make |callback| run on the current
- // sequence:
- //
- // client_.AsyncCall(&DirectoryClient::DeleteHost).WithArgs(host_id,
- // callback);
- //
- // You can just do:
- //
- // PostWithCallback(FROM_HERE, &client_, &DirectoryClient::DeleteHost,
- // callback, host_id);
- //
- // Note that |callback| is moved before other arguments, as type deduction does
- // not work the other way around.
- //
- // Also you should probably bind a WeakPtr in your callback rather than using
- // base::Unretained, since the underlying sequence bound object will generally
- // be deleted after the owning object.
- template <typename SequenceBoundType,
- typename... MethodArgs,
- typename... Args,
- typename... CallbackArgs>
- void PostWithCallback(const base::Location& from_here,
- base::SequenceBound<SequenceBoundType>* client,
- void (SequenceBoundType::*method)(MethodArgs...),
- base::OnceCallback<void(CallbackArgs...)> callback,
- Args&&... args) {
- client->AsyncCall(method, from_here)
- .WithArgs(std::forward<Args>(args)...,
- WrapCallbackToCurrentSequence(from_here, std::move(callback)));
- }
- } // namespace remoting
- #endif // REMOTING_BASE_TASK_UTIL_H_
|