From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- dom/media/webrtc/transport/runnable_utils.h | 222 ++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 dom/media/webrtc/transport/runnable_utils.h (limited to 'dom/media/webrtc/transport/runnable_utils.h') diff --git a/dom/media/webrtc/transport/runnable_utils.h b/dom/media/webrtc/transport/runnable_utils.h new file mode 100644 index 0000000000..c7248f4f55 --- /dev/null +++ b/dom/media/webrtc/transport/runnable_utils.h @@ -0,0 +1,222 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Original author: ekr@rtfm.com + +#ifndef runnable_utils_h__ +#define runnable_utils_h__ + +#include + +#include "mozilla/RefPtr.h" +#include "nsThreadUtils.h" +#include +#include +#include + +// Abstract base class for all of our templates +namespace mozilla { + +namespace detail { + +enum RunnableResult { NoResult, ReturnsResult }; + +static inline nsresult RunOnThreadInternal(nsIEventTarget* thread, + nsIRunnable* runnable, + uint32_t flags) { + return thread->Dispatch(runnable, flags); +} + +template +class runnable_args_base : public Runnable { + public: + runnable_args_base() : Runnable("media-runnable_args_base") {} + + NS_IMETHOD Run() final { + MOZ_ASSERT(!mHasRun, "Can only be run once"); + + RunInternal(); +#ifdef DEBUG + mHasRun = true; +#endif + + return NS_OK; + } + + protected: + virtual void RunInternal() = 0; +#ifdef DEBUG + bool mHasRun = false; +#endif +}; + +} // namespace detail + +template +class runnable_args_func : public detail::runnable_args_base { + public: + // |explicit| to pacify static analysis when there are no |args|. + template + explicit runnable_args_func(FunType f, Arguments&&... args) + : mFunc(f), mArgs(std::forward(args)...) {} + + protected: + void RunInternal() override { + std::apply(std::move(mFunc), std::move(mArgs)); + } + + private: + FunType mFunc; + std::tuple mArgs; +}; + +template +runnable_args_func...>* WrapRunnableNM( + FunType f, Args&&... args) { + return new runnable_args_func...>( + f, std::forward(args)...); +} + +template +class runnable_args_func_ret + : public detail::runnable_args_base { + public: + template + runnable_args_func_ret(Ret* ret, FunType f, Arguments&&... args) + : mReturn(ret), mFunc(f), mArgs(std::forward(args)...) {} + + protected: + void RunInternal() override { + *mReturn = std::apply(std::move(mFunc), std::move(mArgs)); + } + + private: + Ret* mReturn; + FunType mFunc; + std::tuple mArgs; +}; + +template +runnable_args_func_ret...>* WrapRunnableNMRet( + R* ret, FunType f, Args&&... args) { + return new runnable_args_func_ret...>( + ret, f, std::forward(args)...); +} + +template +class runnable_args_memfn + : public detail::runnable_args_base { + public: + template + runnable_args_memfn(Class&& obj, M method, Arguments&&... args) + : mObj(std::forward(obj)), + mMethod(method), + mArgs(std::forward(args)...) {} + + protected: + void RunInternal() override { + std::apply(std::mem_fn(mMethod), + std::tuple_cat(std::tie(mObj), std::move(mArgs))); + } + + private: + // For holders such as RefPtr and UniquePtr make sure concrete copy is held + // rather than a potential dangling reference. + std::decay_t mObj; + M mMethod; + std::tuple mArgs; +}; + +template +runnable_args_memfn...>* WrapRunnable( + Class&& obj, M method, Args&&... args) { + return new runnable_args_memfn...>( + std::forward(obj), method, std::forward(args)...); +} + +template +class runnable_args_memfn_ret + : public detail::runnable_args_base { + public: + template + runnable_args_memfn_ret(Ret* ret, Class&& obj, M method, Arguments... args) + : mReturn(ret), + mObj(std::forward(obj)), + mMethod(method), + mArgs(std::forward(args)...) {} + + protected: + void RunInternal() override { + *mReturn = std::apply(std::mem_fn(mMethod), + std::tuple_cat(std::tie(mObj), std::move(mArgs))); + } + + private: + Ret* mReturn; + // For holders such as RefPtr and UniquePtr make sure concrete copy is held + // rather than a potential dangling reference. + std::decay_t mObj; + M mMethod; + std::tuple mArgs; +}; + +template +runnable_args_memfn_ret...>* WrapRunnableRet( + R* ret, Class&& obj, M method, Args&&... args) { + return new runnable_args_memfn_ret...>( + ret, std::forward(obj), method, std::forward(args)...); +} + +static inline nsresult RUN_ON_THREAD( + nsIEventTarget* thread, + detail::runnable_args_base* runnable, uint32_t flags) { + return detail::RunOnThreadInternal( + thread, static_cast(runnable), flags); +} + +static inline nsresult RUN_ON_THREAD( + nsIEventTarget* thread, + detail::runnable_args_base* runnable) { + return NS_DispatchAndSpinEventLoopUntilComplete( + "webrtc RUN_ON_THREAD"_ns, thread, + do_AddRef(static_cast(runnable))); +} + +#ifdef DEBUG +# define ASSERT_ON_THREAD(t) \ + do { \ + if (t) { \ + bool on; \ + nsresult rv; \ + rv = t->IsOnCurrentThread(&on); \ + MOZ_ASSERT(NS_SUCCEEDED(rv)); \ + MOZ_ASSERT(on); \ + } \ + } while (0) +#else +# define ASSERT_ON_THREAD(t) +#endif + +template +class DispatchedRelease : public detail::runnable_args_base { + public: + explicit DispatchedRelease(already_AddRefed& ref) : ref_(ref) {} + + protected: + void RunInternal() override { ref_ = nullptr; } + + private: + RefPtr ref_; +}; + +template +DispatchedRelease* WrapRelease(already_AddRefed&& ref) { + return new DispatchedRelease(ref); +} + +} /* namespace mozilla */ + +#endif -- cgit v1.2.3