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/nr_timer.cpp | 256 ++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 dom/media/webrtc/transport/nr_timer.cpp (limited to 'dom/media/webrtc/transport/nr_timer.cpp') diff --git a/dom/media/webrtc/transport/nr_timer.cpp b/dom/media/webrtc/transport/nr_timer.cpp new file mode 100644 index 0000000000..3d5671c7a4 --- /dev/null +++ b/dom/media/webrtc/transport/nr_timer.cpp @@ -0,0 +1,256 @@ +/* -*- 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/. */ + +/* 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 code by: ekr@rtfm.com + +// Implementation of the NR timer interface + +// Some code here copied from nrappkit. The license was. + +/** + Copyright (C) 2004, Network Resonance, Inc. + Copyright (C) 2006, Network Resonance, Inc. + All Rights Reserved + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of Network Resonance, Inc. nor the name of any + contributors to this software may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + + ekr@rtfm.com Sun Feb 22 19:35:24 2004 + */ + +#include + +#include "nsCOMPtr.h" +#include "nsServiceManagerUtils.h" +#include "nsIEventTarget.h" +#include "nsINamed.h" +#include "nsITimer.h" +#include "nsNetCID.h" +#include "runnable_utils.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/UniquePtr.h" + +extern "C" { +#include "async_wait.h" +#include "async_timer.h" +#include "r_errors.h" +#include "r_log.h" +} + +namespace mozilla { + +class nrappkitCallback { + public: + nrappkitCallback(NR_async_cb cb, void* cb_arg, const char* function, int line) + : cb_(cb), cb_arg_(cb_arg), function_(function), line_(line) {} + virtual ~nrappkitCallback() = default; + + virtual void Cancel() = 0; + + protected: + /* additional members */ + NR_async_cb cb_; + void* cb_arg_; + std::string function_; + int line_; +}; + +class nrappkitTimerCallback : public nrappkitCallback, + public nsITimerCallback, + public nsINamed { + public: + // We're going to release ourself in the callback, so we need to be threadsafe + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSITIMERCALLBACK + + nrappkitTimerCallback(NR_async_cb cb, void* cb_arg, const char* function, + int line) + : nrappkitCallback(cb, cb_arg, function, line), timer_(nullptr) {} + + void SetTimer(already_AddRefed&& timer) { timer_ = timer; } + + virtual void Cancel() override { + AddRef(); // Cancelling the timer causes the callback it holds to + // be released. AddRef() keeps us alive. + timer_->Cancel(); + timer_ = nullptr; + Release(); // Will cause deletion of this object. + } + + NS_IMETHOD + GetName(nsACString& aName) override { + aName.AssignLiteral("nrappkitTimerCallback"); + return NS_OK; + } + + private: + nsCOMPtr timer_; + virtual ~nrappkitTimerCallback() = default; +}; + +NS_IMPL_ISUPPORTS(nrappkitTimerCallback, nsITimerCallback, nsINamed) + +NS_IMETHODIMP nrappkitTimerCallback::Notify(nsITimer* timer) { + r_log(LOG_GENERIC, LOG_DEBUG, "Timer callback fired (set in %s:%d)", + function_.c_str(), line_); + MOZ_RELEASE_ASSERT(timer == timer_); + cb_(nullptr, 0, cb_arg_); + + // Allow the timer to go away. + timer_ = nullptr; + return NS_OK; +} + +class nrappkitScheduledCallback : public nrappkitCallback { + public: + nrappkitScheduledCallback(NR_async_cb cb, void* cb_arg, const char* function, + int line) + : nrappkitCallback(cb, cb_arg, function, line) {} + + void Run() { + if (cb_) { + cb_(nullptr, 0, cb_arg_); + } + } + + virtual void Cancel() override { cb_ = nullptr; } + + ~nrappkitScheduledCallback() = default; +}; + +} // namespace mozilla + +using namespace mozilla; + +static nsCOMPtr GetSTSThread() { + nsresult rv; + + nsCOMPtr sts_thread; + + sts_thread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + + return sts_thread; +} + +// These timers must only be used from the STS thread. +// This function is a helper that enforces that. +static void CheckSTSThread() { + DebugOnly> sts_thread = GetSTSThread(); + + ASSERT_ON_THREAD(sts_thread.value); +} + +static int nr_async_timer_set_zero(NR_async_cb cb, void* arg, char* func, int l, + nrappkitCallback** handle) { + nrappkitScheduledCallback* callback( + new nrappkitScheduledCallback(cb, arg, func, l)); + + nsresult rv = GetSTSThread()->Dispatch( + WrapRunnable(UniquePtr(callback), + &nrappkitScheduledCallback::Run), + NS_DISPATCH_NORMAL); + if (NS_FAILED(rv)) return R_FAILED; + + *handle = callback; + + // On exit to this function, the only strong reference to callback is in + // the Runnable. Because we are redispatching to the same thread, + // this is always safe. + return 0; +} + +static int nr_async_timer_set_nonzero(int timeout, NR_async_cb cb, void* arg, + char* func, int l, + nrappkitCallback** handle) { + nsresult rv; + CheckSTSThread(); + + nrappkitTimerCallback* callback = new nrappkitTimerCallback(cb, arg, func, l); + + nsCOMPtr timer; + rv = NS_NewTimerWithCallback(getter_AddRefs(timer), callback, timeout, + nsITimer::TYPE_ONE_SHOT); + if (NS_FAILED(rv)) { + return R_FAILED; + } + + // Move the ownership of the timer to the callback object, which holds the + // timer alive per spec. + callback->SetTimer(timer.forget()); + + *handle = callback; + + return 0; +} + +int NR_async_timer_set(int timeout, NR_async_cb cb, void* arg, char* func, + int l, void** handle) { + CheckSTSThread(); + + nrappkitCallback* callback; + int r; + + if (!timeout) { + r = nr_async_timer_set_zero(cb, arg, func, l, &callback); + } else { + r = nr_async_timer_set_nonzero(timeout, cb, arg, func, l, &callback); + } + + if (r) return r; + + if (handle) *handle = callback; + + return 0; +} + +int NR_async_schedule(NR_async_cb cb, void* arg, char* func, int l) { + // No need to check the thread because we check it next in the + // timer set. + return NR_async_timer_set(0, cb, arg, func, l, nullptr); +} + +int NR_async_timer_cancel(void* handle) { + // Check for the handle being nonzero because sometimes we get + // no-op cancels that aren't on the STS thread. This can be + // non-racy as long as the upper-level code is careful. + if (!handle) return 0; + + CheckSTSThread(); + + nrappkitCallback* callback = static_cast(handle); + callback->Cancel(); + + return 0; +} -- cgit v1.2.3