| Index: media/base/run_on_destruction.h
|
| diff --git a/media/base/run_on_destruction.h b/media/base/run_on_destruction.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..646a4dafeb114901b6352004ce14d5a69410fc80
|
| --- /dev/null
|
| +++ b/media/base/run_on_destruction.h
|
| @@ -0,0 +1,92 @@
|
| +// Copyright 2015 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 MEDIA_BASE_RUN_ON_DESTRUCTION_H_
|
| +#define MEDIA_BASE_RUN_ON_DESTRUCTION_H_
|
| +
|
| +#include <memory>
|
| +
|
| +#include "base/callback_forward.h"
|
| +#include "base/bind.h"
|
| +#include "base/tuple.h"
|
| +#include "base/memory/ptr_util.h"
|
| +
|
| +// This is a helper utility to wrap a base::Callback such that if the
|
| +// callback is destructed before it has a chance to run (e.g. the callback is
|
| +// bound into a task in a task runner and the task is dropped), it will be run
|
| +// with a set of parameters passed into RunOnDestruction.
|
| +//
|
| +// Typical usage:
|
| +// foo->DoWorkAndReturnResult(
|
| +// media::RunOnDestruction(base::Bind(&Foo::OnResult, this), false));
|
| +//
|
| +// If the callback is destructed without running, it'll be called with "false".
|
| +
|
| +// TODO(xhwang): This class really only makes sense for base::OnceCallback.
|
| +// However, mojo uses base::Callback in generated interfaces.
|
| +
|
| +
|
| +namespace media {
|
| +namespace internal {
|
| +
|
| +template <typename CallbackType, typename Tuple, size_t... Ns>
|
| +inline void DispatchToCallbackImpl(CallbackType callback,
|
| + Tuple&& args,
|
| + base::IndexSequence<Ns...>) {
|
| + std::move(callback).Run(base::get<Ns>(std::forward<Tuple>(args))...);
|
| +}
|
| +
|
| +template <typename CallbackType, typename Tuple>
|
| +inline void DispatchToCallback(CallbackType callback, Tuple&& args) {
|
| + DispatchToCallbackImpl(std::move(callback), std::forward<Tuple>(args),
|
| + base::MakeIndexSequenceForTuple<Tuple>());
|
| +}
|
| +
|
| +// First, tell the compiler RunOnDestructionHelper is a struct template with one
|
| +// type parameter. Then define specializations where the type is a function
|
| +// returning void and taking zero or more arguments.
|
| +template <typename Signature>
|
| +class RunOnDestructionHelper;
|
| +
|
| +template <typename... Args>
|
| +class RunOnDestructionHelper<void(Args...)> {
|
| + public:
|
| + using CallbackType = base::Callback<void(Args...)>;
|
| +
|
| + RunOnDestructionHelper(CallbackType callback, Args... args)
|
| + : callback_(std::move(callback)),
|
| + args_(std::make_tuple(args...)) {
|
| + DCHECK(callback_);
|
| + }
|
| +
|
| + inline void Run(Args... args);
|
| +
|
| + ~RunOnDestructionHelper() {
|
| + if (callback_)
|
| + DispatchToCallback(std::move(callback_), args_);
|
| + }
|
| +
|
| + private:
|
| + CallbackType callback_;
|
| + std::tuple<Args...> args_;
|
| +};
|
| +
|
| +template <typename... Args>
|
| +inline void RunOnDestructionHelper<void(Args...)>::Run(Args... args) {
|
| + std::move(callback_).Run(args...);
|
| +}
|
| +
|
| +} // namespace internal
|
| +
|
| +template <typename T, typename... Args>
|
| +inline base::Callback<T> RunOnDestruction(base::Callback<T> cb, Args... args) {
|
| + return base::Bind(
|
| + &internal::RunOnDestructionHelper<T>::Run,
|
| + base::MakeUnique<internal::RunOnDestructionHelper<T>>(
|
| + std::move(cb), args...));
|
| +}
|
| +
|
| +} // namespace media
|
| +
|
| +#endif // MEDIA_BASE_RUN_ON_DESTRUCTION_H_
|
|
|