Bug 1772053 - Enable dynamic code disable mitigations only on Windows 10 1703+ r...
[gecko.git] / dom / media / systemservices / MediaUtils.cpp
blobfc72b0699a2ab70724932381f4fc162aa37355e2
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et ft=cpp : */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "MediaUtils.h"
8 #include "mozilla/Services.h"
10 namespace mozilla::media {
12 nsCOMPtr<nsIAsyncShutdownClient> GetShutdownBarrier() {
13 nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdownService();
14 if (!svc) {
15 // We can fail to get the shutdown service if we're already shutting down.
16 return nullptr;
19 nsCOMPtr<nsIAsyncShutdownClient> barrier;
20 nsresult rv = svc->GetProfileBeforeChange(getter_AddRefs(barrier));
21 if (!barrier) {
22 // We are probably in a content process. We need to do cleanup at
23 // XPCOM shutdown in leakchecking builds.
24 rv = svc->GetXpcomWillShutdown(getter_AddRefs(barrier));
26 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
27 MOZ_RELEASE_ASSERT(barrier);
28 return barrier;
31 nsCOMPtr<nsIAsyncShutdownClient> MustGetShutdownBarrier() {
32 nsCOMPtr<nsIAsyncShutdownClient> barrier = GetShutdownBarrier();
33 MOZ_RELEASE_ASSERT(barrier);
34 return barrier;
37 NS_IMPL_ISUPPORTS(ShutdownBlocker, nsIAsyncShutdownBlocker)
39 namespace {
40 class MediaEventBlocker : public ShutdownBlocker {
41 public:
42 explicit MediaEventBlocker(nsString aName)
43 : ShutdownBlocker(std::move(aName)) {}
45 NS_IMETHOD
46 BlockShutdown(nsIAsyncShutdownClient* aProfileBeforeChange) override {
47 mShutdownEvent.Notify();
48 return NS_OK;
51 MediaEventSource<void>& ShutdownEvent() { return mShutdownEvent; }
53 private:
54 MediaEventProducer<void> mShutdownEvent;
57 class RefCountedTicket {
58 RefPtr<MediaEventBlocker> mBlocker;
59 MediaEventForwarder<void> mShutdownEventForwarder;
61 public:
62 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedTicket)
64 RefCountedTicket()
65 : mShutdownEventForwarder(GetMainThreadSerialEventTarget()) {}
67 void AddBlocker(const nsString& aName, const nsString& aFileName,
68 int32_t aLineNr) {
69 MOZ_ASSERT(NS_IsMainThread());
70 MOZ_ASSERT(!mBlocker);
71 mBlocker = MakeAndAddRef<MediaEventBlocker>(aName);
72 mShutdownEventForwarder.Forward(mBlocker->ShutdownEvent());
73 GetShutdownBarrier()->AddBlocker(mBlocker.get(), aFileName, aLineNr, aName);
76 MediaEventSource<void>& ShutdownEvent() { return mShutdownEventForwarder; }
78 protected:
79 virtual ~RefCountedTicket() {
80 MOZ_ASSERT(NS_IsMainThread());
81 MOZ_ASSERT(mBlocker);
82 GetShutdownBarrier()->RemoveBlocker(mBlocker.get());
83 mShutdownEventForwarder.DisconnectAll();
87 class ShutdownBlockingTicketImpl : public ShutdownBlockingTicket {
88 private:
89 RefPtr<RefCountedTicket> mTicket;
91 public:
92 ShutdownBlockingTicketImpl(nsString aName, nsString aFileName,
93 int32_t aLineNr)
94 : mTicket(MakeAndAddRef<RefCountedTicket>()) {
95 aName.AppendPrintf(" - %p", this);
96 NS_DispatchToMainThread(NS_NewRunnableFunction(
97 __func__, [ticket = mTicket, name = std::move(aName),
98 fileName = std::move(aFileName), lineNr = aLineNr] {
99 ticket->AddBlocker(name, fileName, lineNr);
100 }));
103 ~ShutdownBlockingTicketImpl() {
104 NS_ReleaseOnMainThread(__func__, mTicket.forget(), true);
107 MediaEventSource<void>& ShutdownEvent() override {
108 return mTicket->ShutdownEvent();
111 } // namespace
113 UniquePtr<ShutdownBlockingTicket> ShutdownBlockingTicket::Create(
114 nsString aName, nsString aFileName, int32_t aLineNr) {
115 return WrapUnique(new ShutdownBlockingTicketImpl(
116 std::move(aName), std::move(aFileName), aLineNr));
119 } // namespace mozilla::media