1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "fs/FileSystemShutdownBlocker.h"
9 #include "MainThreadUtils.h"
10 #include "mozilla/Services.h"
11 #include "mozilla/dom/quota/QuotaCommon.h"
12 #include "mozilla/dom/quota/ResultExtensions.h"
13 #include "nsComponentManagerUtils.h"
14 #include "nsIAsyncShutdown.h"
15 #include "nsISupportsImpl.h"
16 #include "nsIWritablePropertyBag2.h"
17 #include "nsStringFwd.h"
19 namespace mozilla::dom::fs
{
23 nsString
CreateBlockerName() {
24 const int32_t blockerIdLength
= 32;
25 nsAutoCString blockerId
;
26 blockerId
.SetLength(blockerIdLength
);
27 NS_MakeRandomString(blockerId
.BeginWriting(), blockerIdLength
);
29 nsString blockerName
= u
"OPFS_"_ns
;
30 blockerName
.Append(NS_ConvertUTF8toUTF16(blockerId
));
35 class FileSystemWritableBlocker
: public FileSystemShutdownBlocker
{
37 FileSystemWritableBlocker() : mName(CreateBlockerName()) {}
39 NS_DECL_ISUPPORTS_INHERITED
40 NS_DECL_NSIASYNCSHUTDOWNBLOCKER
42 NS_IMETHODIMP
Block() override
;
44 NS_IMETHODIMP
Unblock() override
;
47 virtual ~FileSystemWritableBlocker() = default;
49 Result
<already_AddRefed
<nsIAsyncShutdownClient
>, nsresult
> GetBarrier() const;
55 NS_IMPL_ISUPPORTS_INHERITED(FileSystemWritableBlocker
,
56 FileSystemShutdownBlocker
, nsIAsyncShutdownBlocker
)
58 NS_IMETHODIMP
FileSystemWritableBlocker::Block() {
59 MOZ_ASSERT(NS_IsMainThread());
60 QM_TRY_UNWRAP(nsCOMPtr
<nsIAsyncShutdownClient
> barrier
, GetBarrier());
62 QM_TRY(MOZ_TO_RESULT(barrier
->AddBlocker(
63 this, NS_ConvertUTF8toUTF16(nsCString(__FILE__
)), __LINE__
,
64 NS_ConvertUTF8toUTF16(nsCString(__func__
)))));
69 NS_IMETHODIMP
FileSystemWritableBlocker::Unblock() {
70 MOZ_ASSERT(NS_IsMainThread());
71 QM_TRY_UNWRAP(nsCOMPtr
<nsIAsyncShutdownClient
> barrier
, GetBarrier());
73 MOZ_ASSERT(NS_SUCCEEDED(barrier
->RemoveBlocker(this)));
78 Result
<already_AddRefed
<nsIAsyncShutdownClient
>, nsresult
>
79 FileSystemWritableBlocker::GetBarrier() const {
80 nsCOMPtr
<nsIAsyncShutdownService
> svc
= services::GetAsyncShutdownService();
81 QM_TRY(OkIf(svc
), Err(NS_ERROR_FAILURE
));
83 nsCOMPtr
<nsIAsyncShutdownClient
> barrier
;
84 QM_TRY(MOZ_TO_RESULT(svc
->GetXpcomWillShutdown(getter_AddRefs(barrier
))));
86 return barrier
.forget();
90 FileSystemWritableBlocker::GetName(nsAString
& aName
) {
97 FileSystemWritableBlocker::GetState(nsIPropertyBag
** aBagOut
) {
100 nsCOMPtr
<nsIWritablePropertyBag2
> propertyBag
=
101 do_CreateInstance("@mozilla.org/hash-property-bag;1");
103 QM_TRY(OkIf(propertyBag
), NS_ERROR_OUT_OF_MEMORY
)
105 propertyBag
.forget(aBagOut
);
111 FileSystemWritableBlocker::BlockShutdown(
112 nsIAsyncShutdownClient
* /* aBarrier */) {
113 MOZ_ASSERT(NS_IsMainThread());
118 class FileSystemNullBlocker
: public FileSystemShutdownBlocker
{
120 NS_IMETHODIMP
Block() override
{ return NS_OK
; }
122 NS_IMETHODIMP
Unblock() override
{ return NS_OK
; }
125 virtual ~FileSystemNullBlocker() = default;
131 already_AddRefed
<FileSystemShutdownBlocker
>
132 FileSystemShutdownBlocker::CreateForWritable() {
133 // The shutdown blocker watches for xpcom-will-shutdown which is not fired
134 // during content process shutdown in release builds.
136 if (NS_IsMainThread()) {
137 RefPtr
<FileSystemShutdownBlocker
> shutdownBlocker
=
138 new FileSystemWritableBlocker();
140 return shutdownBlocker
.forget();
144 RefPtr
<FileSystemShutdownBlocker
> shutdownBlocker
=
145 new FileSystemNullBlocker();
147 return shutdownBlocker
.forget();
150 NS_IMPL_ISUPPORTS(FileSystemShutdownBlocker
, nsIAsyncShutdownBlocker
)
152 /* nsIAsyncShutdownBlocker methods */
154 FileSystemShutdownBlocker::GetName(nsAString
& /* aName */) { return NS_OK
; }
157 FileSystemShutdownBlocker::GetState(nsIPropertyBag
** /* aBagOut */) {
162 FileSystemShutdownBlocker::BlockShutdown(
163 nsIAsyncShutdownClient
* /* aBarrier */) {
167 } // namespace mozilla::dom::fs