Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/file/ipc/./../../../../dom/file/ipc/RemoteLazyInputStream.cpp
Warning:line 275, column 15
Value stored to 'state' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_dom_file_ipc0.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/file/ipc -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/file/ipc -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/file/ipc -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/file/ipc -I /root/firefox-clang/dom/file -I /root/firefox-clang/dom/ipc -I /root/firefox-clang/xpcom/build -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/toolkit/components/telemetry -I /root/firefox-clang/xpcom/base -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/gtk-3.0/unix-print -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/cloudproviders -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/fribidi -I /usr/include/harfbuzz -I /usr/include/atk-1.0 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ Unified_cpp_dom_file_ipc0.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "RemoteLazyInputStream.h"
6
7#include "RemoteLazyInputStreamChild.h"
8#include "RemoteLazyInputStreamParent.h"
9#include "RemoteLazyInputStreamStorage.h"
10#include "RemoteLazyInputStreamThread.h"
11#include "chrome/common/ipc_message_utils.h"
12#include "mozilla/ErrorNames.h"
13#include "mozilla/Logging.h"
14#include "mozilla/NonBlockingAsyncInputStream.h"
15#include "mozilla/PRemoteLazyInputStream.h"
16#include "mozilla/SlicedInputStream.h"
17#include "mozilla/ipc/Endpoint.h"
18#include "mozilla/ipc/InputStreamParams.h"
19#include "mozilla/ipc/MessageChannel.h"
20#include "mozilla/ipc/ProtocolMessageUtils.h"
21#include "mozilla/net/SocketProcessParent.h"
22#include "nsIAsyncInputStream.h"
23#include "nsIAsyncOutputStream.h"
24#include "nsID.h"
25#include "nsIInputStream.h"
26#include "nsIPipe.h"
27#include "nsNetUtil.h"
28#include "nsStreamUtils.h"
29#include "nsStringStream.h"
30
31namespace mozilla {
32
33mozilla::LazyLogModule gRemoteLazyStreamLog("RemoteLazyStream");
34
35namespace {
36
37class InputStreamCallbackRunnable final : public DiscardableRunnable {
38 public:
39 // Note that the execution can be synchronous in case the event target is
40 // null.
41 static void Execute(already_AddRefed<nsIInputStreamCallback> aCallback,
42 already_AddRefed<nsIEventTarget> aEventTarget,
43 RemoteLazyInputStream* aStream) {
44 RefPtr<InputStreamCallbackRunnable> runnable =
45 new InputStreamCallbackRunnable(std::move(aCallback), aStream);
46
47 nsCOMPtr<nsIEventTarget> target = std::move(aEventTarget);
48 if (target) {
49 target->Dispatch(runnable, NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL);
50 } else {
51 runnable->Run();
52 }
53 }
54
55 NS_IMETHODvirtual nsresult
56 Run() override {
57 mCallback->OnInputStreamReady(mStream);
58 mCallback = nullptr;
59 mStream = nullptr;
60 return NS_OK;
61 }
62
63 private:
64 InputStreamCallbackRunnable(
65 already_AddRefed<nsIInputStreamCallback> aCallback,
66 RemoteLazyInputStream* aStream)
67 : DiscardableRunnable("dom::InputStreamCallbackRunnable"),
68 mCallback(std::move(aCallback)),
69 mStream(aStream) {
70 MOZ_ASSERT(mCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCallback))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mCallback", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 70); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCallback" ")"
); do { MOZ_CrashSequence(__null, 70); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
71 MOZ_ASSERT(mStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mStream))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mStream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 71); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mStream" ")")
; do { MOZ_CrashSequence(__null, 71); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false)
;
72 }
73
74 RefPtr<nsIInputStreamCallback> mCallback;
75 RefPtr<RemoteLazyInputStream> mStream;
76};
77
78class FileMetadataCallbackRunnable final : public DiscardableRunnable {
79 public:
80 static void Execute(nsIFileMetadataCallback* aCallback,
81 nsIEventTarget* aEventTarget,
82 RemoteLazyInputStream* aStream) {
83 MOZ_ASSERT(aCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aCallback))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aCallback", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 83); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aCallback" ")"
); do { MOZ_CrashSequence(__null, 83); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
84 MOZ_ASSERT(aEventTarget)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aEventTarget)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aEventTarget))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aEventTarget", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 84); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aEventTarget"
")"); do { MOZ_CrashSequence(__null, 84); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
85
86 RefPtr<FileMetadataCallbackRunnable> runnable =
87 new FileMetadataCallbackRunnable(aCallback, aStream);
88
89 nsCOMPtr<nsIEventTarget> target = aEventTarget;
90 target->Dispatch(runnable, NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL);
91 }
92
93 NS_IMETHODvirtual nsresult
94 Run() override {
95 mCallback->OnFileMetadataReady(mStream);
96 mCallback = nullptr;
97 mStream = nullptr;
98 return NS_OK;
99 }
100
101 private:
102 FileMetadataCallbackRunnable(nsIFileMetadataCallback* aCallback,
103 RemoteLazyInputStream* aStream)
104 : DiscardableRunnable("dom::FileMetadataCallbackRunnable"),
105 mCallback(aCallback),
106 mStream(aStream) {
107 MOZ_ASSERT(mCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCallback))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mCallback", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 107); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCallback" ")"
); do { MOZ_CrashSequence(__null, 107); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
108 MOZ_ASSERT(mStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mStream))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mStream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 108); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mStream" ")"
); do { MOZ_CrashSequence(__null, 108); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
109 }
110
111 nsCOMPtr<nsIFileMetadataCallback> mCallback;
112 RefPtr<RemoteLazyInputStream> mStream;
113};
114
115} // namespace
116
117NS_IMPL_ADDREF(RemoteLazyInputStream)MozExternalRefCountType RemoteLazyInputStream::AddRef(void) {
static_assert(!std::is_destructible_v<RemoteLazyInputStream
>, "Reference-counted class " "RemoteLazyInputStream" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 117); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 117
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("RemoteLazyInputStream" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("RemoteLazyInputStream" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"RemoteLazyInputStream\" != nullptr"
" (" "Must specify a name" ")", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 117); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"RemoteLazyInputStream\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 117); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("RemoteLazyInputStream" " not thread-safe"); nsrefcnt count =
++mRefCnt; NS_LogAddRef((this), (count), ("RemoteLazyInputStream"
), (uint32_t)(sizeof(*this))); return count; }
;
118NS_IMPL_RELEASE(RemoteLazyInputStream)MozExternalRefCountType RemoteLazyInputStream::Release(void) {
do { static_assert( mozilla::detail::AssertionConditionType<
decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 118); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 118
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("RemoteLazyInputStream" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("RemoteLazyInputStream" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"RemoteLazyInputStream\" != nullptr"
" (" "Must specify a name" ")", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 118); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"RemoteLazyInputStream\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 118); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("RemoteLazyInputStream" " not thread-safe"); const char* const
nametmp = "RemoteLazyInputStream"; nsrefcnt count = --mRefCnt
; NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; }
;
119
120NS_INTERFACE_MAP_BEGIN(RemoteLazyInputStream)nsresult RemoteLazyInputStream::QueryInterface(const nsIID&
aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 120); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
121 NS_INTERFACE_MAP_ENTRY(nsIInputStream)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIInputStream>)) foundInterface =
static_cast<nsIInputStream*>(this); else
122 NS_INTERFACE_MAP_ENTRY(nsIAsyncInputStream)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIAsyncInputStream>)) foundInterface
= static_cast<nsIAsyncInputStream*>(this); else
123 NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIInputStreamCallback>)) foundInterface
= static_cast<nsIInputStreamCallback*>(this); else
124 NS_INTERFACE_MAP_ENTRY(nsICloneableInputStream)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICloneableInputStream>)) foundInterface
= static_cast<nsICloneableInputStream*>(this); else
125 NS_INTERFACE_MAP_ENTRY(nsICloneableInputStreamWithRange)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICloneableInputStreamWithRange>
)) foundInterface = static_cast<nsICloneableInputStreamWithRange
*>(this); else
126 NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableInputStream)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIIPCSerializableInputStream>)) foundInterface
= static_cast<nsIIPCSerializableInputStream*>(this); else
127 NS_INTERFACE_MAP_ENTRY(nsIFileMetadata)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIFileMetadata>)) foundInterface
= static_cast<nsIFileMetadata*>(this); else
128 NS_INTERFACE_MAP_ENTRY(nsIAsyncFileMetadata)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIAsyncFileMetadata>)) foundInterface
= static_cast<nsIAsyncFileMetadata*>(this); else
129 NS_INTERFACE_MAP_ENTRY(nsIInputStreamLength)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIInputStreamLength>)) foundInterface
= static_cast<nsIInputStreamLength*>(this); else
130 NS_INTERFACE_MAP_ENTRY(nsIAsyncInputStreamLength)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIAsyncInputStreamLength>)) foundInterface
= static_cast<nsIAsyncInputStreamLength*>(this); else
131 NS_INTERFACE_MAP_ENTRY(mozIRemoteLazyInputStream)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, mozIRemoteLazyInputStream>)) foundInterface
= static_cast<mozIRemoteLazyInputStream*>(this); else
132 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsIInputStream*>(this)
); else
133NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 133); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 133); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
134
135RemoteLazyInputStream::RemoteLazyInputStream(RemoteLazyInputStreamChild* aActor,
136 uint64_t aStart, uint64_t aLength)
137 : mStart(aStart), mLength(aLength), mState(eInit), mActor(aActor) {
138 MOZ_ASSERT(aActor)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aActor)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(aActor))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aActor", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 138); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aActor" ")")
; do { MOZ_CrashSequence(__null, 138); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
139
140 mActor->StreamCreated();
141
142 auto storage = RemoteLazyInputStreamStorage::Get().unwrapOr(nullptr);
143 if (storage) {
144 nsCOMPtr<nsIInputStream> stream;
145 storage->GetStream(mActor->StreamID(), mStart, mLength,
146 getter_AddRefs(stream));
147 if (stream) {
148 mState = eRunning;
149 mInnerStream = std::move(stream);
150 }
151 }
152}
153
154RemoteLazyInputStream::RemoteLazyInputStream(nsIInputStream* aStream)
155 : mStart(0), mLength(UINT64_MAX(18446744073709551615UL)), mState(eRunning), mInnerStream(aStream) {}
156
157static already_AddRefed<RemoteLazyInputStreamChild> BindChildActor(
158 nsID aId, mozilla::ipc::Endpoint<PRemoteLazyInputStreamChild> aEndpoint) {
159 RefPtr<RemoteLazyInputStreamThread> thread =
160 RemoteLazyInputStreamThread::GetOrCreate();
161 if (NS_WARN_IF(!thread)NS_warn_if_impl(!thread, "!thread", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 161)
) {
162 return nullptr;
163 }
164 auto actor = MakeRefPtr<RemoteLazyInputStreamChild>(aId);
165 thread->Dispatch(
166 NS_NewRunnableFunction("RemoteLazyInputStream::BindChildActor",
167 [actor, childEp = std::move(aEndpoint)]() mutable {
168 bool ok = childEp.Bind(actor);
169 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Binding child actor for %s (%p): %s", nsIDToCString
(actor->StreamID()).get(), actor.get(), ok ? "OK" : "ERROR"
); } } while (0)
170 ("Binding child actor for %s (%p): %s",do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Binding child actor for %s (%p): %s", nsIDToCString
(actor->StreamID()).get(), actor.get(), ok ? "OK" : "ERROR"
); } } while (0)
171 nsIDToCString(actor->StreamID()).get(),do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Binding child actor for %s (%p): %s", nsIDToCString
(actor->StreamID()).get(), actor.get(), ok ? "OK" : "ERROR"
); } } while (0)
172 actor.get(), ok ? "OK" : "ERROR"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Binding child actor for %s (%p): %s", nsIDToCString
(actor->StreamID()).get(), actor.get(), ok ? "OK" : "ERROR"
); } } while (0)
;
173 }));
174
175 return actor.forget();
176}
177
178already_AddRefed<RemoteLazyInputStream> RemoteLazyInputStream::WrapStream(
179 nsIInputStream* aInputStream) {
180 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 180
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 180); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
181 if (nsCOMPtr<mozIRemoteLazyInputStream> lazyStream =
182 do_QueryInterface(aInputStream)) {
183 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Returning already-wrapped stream"); } } while
(0)
184 ("Returning already-wrapped stream"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Returning already-wrapped stream"); } } while
(0)
;
185 return lazyStream.forget().downcast<RemoteLazyInputStream>();
186 }
187
188 // If we have a stream and are in the parent process, create a new actor pair
189 // and transfer ownership of the stream into storage.
190 auto streamStorage = RemoteLazyInputStreamStorage::Get();
191 if (NS_WARN_IF(streamStorage.isErr())NS_warn_if_impl(streamStorage.isErr(), "streamStorage.isErr()"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 191
)
) {
192 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Warning,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "Cannot wrap with no storage!"); } } while
(0)
193 ("Cannot wrap with no storage!"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "Cannot wrap with no storage!"); } } while
(0)
;
194 return nullptr;
195 }
196
197 nsID id = nsID::GenerateUUID();
198 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Wrapping stream %p as %s", aInputStream
, nsIDToCString(id).get()); } } while (0)
199 ("Wrapping stream %p as %s", aInputStream, nsIDToCString(id).get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Wrapping stream %p as %s", aInputStream
, nsIDToCString(id).get()); } } while (0)
;
200 streamStorage.inspect()->AddStream(aInputStream, id);
201
202 mozilla::ipc::Endpoint<PRemoteLazyInputStreamParent> parentEp;
203 mozilla::ipc::Endpoint<PRemoteLazyInputStreamChild> childEp;
204 MOZ_ALWAYS_SUCCEEDS(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &
childEp))), 1)))), 1))) { } else { do { do { } while (false);
MOZ_ReportCrash("" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 205
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
")"); do { MOZ_CrashSequence(__null, 205); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
205 PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &
childEp))), 1)))), 1))) { } else { do { do { } while (false);
MOZ_ReportCrash("" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 205
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
")"); do { MOZ_CrashSequence(__null, 205); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
206
207 // Bind the actor on our background thread.
208 streamStorage.inspect()->TaskQueue()->Dispatch(NS_NewRunnableFunction(
209 "RemoteLazyInputStreamParent::Bind",
210 [parentEp = std::move(parentEp), id]() mutable {
211 auto actor = MakeRefPtr<RemoteLazyInputStreamParent>(id);
212 bool ok = parentEp.Bind(actor);
213 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Binding parent actor for %s (%p): %s", nsIDToCString
(id).get(), actor.get(), ok ? "OK" : "ERROR"); } } while (0)
214 ("Binding parent actor for %s (%p): %s",do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Binding parent actor for %s (%p): %s", nsIDToCString
(id).get(), actor.get(), ok ? "OK" : "ERROR"); } } while (0)
215 nsIDToCString(id).get(), actor.get(), ok ? "OK" : "ERROR"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Binding parent actor for %s (%p): %s", nsIDToCString
(id).get(), actor.get(), ok ? "OK" : "ERROR"); } } while (0)
;
216 }));
217
218 RefPtr<RemoteLazyInputStreamChild> actor =
219 BindChildActor(id, std::move(childEp));
220
221 if (!actor) {
222 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Warning,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "Wrapping stream failed as we are probably late in shutdown!"
); } } while (0)
223 ("Wrapping stream failed as we are probably late in shutdown!"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "Wrapping stream failed as we are probably late in shutdown!"
); } } while (0)
;
224 return do_AddRef(new RemoteLazyInputStream());
225 }
226
227 return do_AddRef(new RemoteLazyInputStream(actor));
228}
229
230NS_IMETHODIMPnsresult RemoteLazyInputStream::TakeInternalStream(
231 nsIInputStream** aStream) {
232 RefPtr<RemoteLazyInputStreamChild> actor;
233 {
234 MutexAutoLock lock(mMutex);
235 if (mState == eInit || mState == ePending) {
236 return NS_BASE_STREAM_WOULD_BLOCK;
237 }
238 if (mState == eClosed) {
239 return NS_BASE_STREAM_CLOSED;
240 }
241 if (mInputStreamCallback) {
242 MOZ_ASSERT_UNREACHABLE(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Do not call TakeInternalStream after calling AsyncWait" ")"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 243
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: "
"Do not call TakeInternalStream after calling AsyncWait" ")"
); do { MOZ_CrashSequence(__null, 243); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
243 "Do not call TakeInternalStream after calling AsyncWait")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Do not call TakeInternalStream after calling AsyncWait" ")"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 243
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") (" "MOZ_ASSERT_UNREACHABLE: "
"Do not call TakeInternalStream after calling AsyncWait" ")"
); do { MOZ_CrashSequence(__null, 243); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
244 return NS_ERROR_UNEXPECTED;
245 }
246
247 // Take the inner stream and return it, then close ourselves.
248 if (mInnerStream) {
249 mInnerStream.forget(aStream);
250 } else if (mAsyncInnerStream) {
251 mAsyncInnerStream.forget(aStream);
252 }
253 mState = eClosed;
254 actor = mActor.forget();
255 }
256 if (actor) {
257 actor->StreamConsumed();
258 }
259 return NS_OK;
260}
261
262NS_IMETHODIMPnsresult RemoteLazyInputStream::GetInternalStreamID(nsID& aID) {
263 MutexAutoLock lock(mMutex);
264 if (!mActor) {
265 return NS_ERROR_NOT_AVAILABLE;
266 }
267
268 aID = mActor->StreamID();
269 return NS_OK;
270}
271
272RemoteLazyInputStream::~RemoteLazyInputStream() { Close(); }
273
274nsCString RemoteLazyInputStream::Describe() {
275 const char* state = "?";
Value stored to 'state' during its initialization is never read
276 switch (mState) {
277 case eInit:
278 state = "i";
279 break;
280 case ePending:
281 state = "p";
282 break;
283 case eRunning:
284 state = "r";
285 break;
286 case eClosed:
287 state = "c";
288 break;
289 }
290 return nsPrintfCString(
291 "[%p, %s, %s, %p%s, %s%s|%s%s]", this, state,
292 mActor ? nsIDToCString(mActor->StreamID()).get() : "<no actor>",
293 mInnerStream ? mInnerStream.get() : mAsyncInnerStream.get(),
294 mAsyncInnerStream ? "(A)" : "", mInputStreamCallback ? "I" : "",
295 mInputStreamCallbackEventTarget ? "+" : "",
296 mFileMetadataCallback ? "F" : "",
297 mFileMetadataCallbackEventTarget ? "+" : "");
298}
299
300// nsIInputStream interface
301
302NS_IMETHODIMPnsresult
303RemoteLazyInputStream::Available(uint64_t* aLength) {
304 nsCOMPtr<nsIAsyncInputStream> stream;
305 {
306 MutexAutoLock lock(mMutex);
307
308 // We don't have a remoteStream yet: let's return 0.
309 if (mState == eInit || mState == ePending) {
310 *aLength = 0;
311 return NS_OK;
312 }
313
314 if (mState == eClosed) {
315 return NS_BASE_STREAM_CLOSED;
316 }
317
318 MOZ_ASSERT(mState == eRunning)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == eRunning)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == eRunning))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mState == eRunning"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 318
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mState == eRunning"
")"); do { MOZ_CrashSequence(__null, 318); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
319 MOZ_ASSERT(mInnerStream || mAsyncInnerStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInnerStream || mAsyncInnerStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInnerStream || mAsyncInnerStream
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mInnerStream || mAsyncInnerStream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 319); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInnerStream || mAsyncInnerStream"
")"); do { MOZ_CrashSequence(__null, 319); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
320
321 nsresult rv = EnsureAsyncRemoteStream();
322 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 322)
) {
323 return rv;
324 }
325
326 stream = mAsyncInnerStream;
327 }
328
329 MOZ_ASSERT(stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(stream)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(stream))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("stream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 329); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stream" ")")
; do { MOZ_CrashSequence(__null, 329); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
330 return stream->Available(aLength);
331}
332
333NS_IMETHODIMPnsresult
334RemoteLazyInputStream::StreamStatus() {
335 nsCOMPtr<nsIAsyncInputStream> stream;
336 {
337 MutexAutoLock lock(mMutex);
338
339 // We don't have a remoteStream yet: let's return 0.
340 if (mState == eInit || mState == ePending) {
341 return NS_OK;
342 }
343
344 if (mState == eClosed) {
345 return NS_BASE_STREAM_CLOSED;
346 }
347
348 MOZ_ASSERT(mState == eRunning)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == eRunning)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == eRunning))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mState == eRunning"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 348
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mState == eRunning"
")"); do { MOZ_CrashSequence(__null, 348); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
349 MOZ_ASSERT(mInnerStream || mAsyncInnerStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInnerStream || mAsyncInnerStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInnerStream || mAsyncInnerStream
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mInnerStream || mAsyncInnerStream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInnerStream || mAsyncInnerStream"
")"); do { MOZ_CrashSequence(__null, 349); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
350
351 nsresult rv = EnsureAsyncRemoteStream();
352 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 352)
) {
353 return rv;
354 }
355
356 stream = mAsyncInnerStream;
357 }
358
359 MOZ_ASSERT(stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(stream)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(stream))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("stream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 359); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stream" ")")
; do { MOZ_CrashSequence(__null, 359); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
360 return stream->StreamStatus();
361}
362
363NS_IMETHODIMPnsresult
364RemoteLazyInputStream::Read(char* aBuffer, uint32_t aCount,
365 uint32_t* aReadCount) {
366 nsCOMPtr<nsIAsyncInputStream> stream;
367 {
368 MutexAutoLock lock(mMutex);
369
370 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Read(%u) %s", aCount, Describe().get())
; } } while (0)
371 ("Read(%u) %s", aCount, Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Read(%u) %s", aCount, Describe().get())
; } } while (0)
;
372
373 // Read is not available is we don't have a remoteStream.
374 if (mState == eInit || mState == ePending) {
375 return NS_BASE_STREAM_WOULD_BLOCK;
376 }
377
378 if (mState == eClosed) {
379 return NS_BASE_STREAM_CLOSED;
380 }
381
382 MOZ_ASSERT(mState == eRunning)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == eRunning)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == eRunning))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mState == eRunning"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 382
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mState == eRunning"
")"); do { MOZ_CrashSequence(__null, 382); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
383 MOZ_ASSERT(mInnerStream || mAsyncInnerStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInnerStream || mAsyncInnerStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInnerStream || mAsyncInnerStream
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mInnerStream || mAsyncInnerStream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 383); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInnerStream || mAsyncInnerStream"
")"); do { MOZ_CrashSequence(__null, 383); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
384
385 nsresult rv = EnsureAsyncRemoteStream();
386 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 386)
) {
387 return rv;
388 }
389
390 stream = mAsyncInnerStream;
391 }
392
393 MOZ_ASSERT(stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(stream)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(stream))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("stream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 393); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stream" ")")
; do { MOZ_CrashSequence(__null, 393); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
394 nsresult rv = stream->Read(aBuffer, aCount, aReadCount);
395 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
396 return rv;
397 }
398
399 // If some data has been read, we mark the stream as consumed.
400 if (*aReadCount > 0) {
401 MarkConsumed();
402 }
403
404 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Read %u/%u bytes", *aReadCount, aCount)
; } } while (0)
405 ("Read %u/%u bytes", *aReadCount, aCount))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Read %u/%u bytes", *aReadCount, aCount)
; } } while (0)
;
406
407 return NS_OK;
408}
409
410NS_IMETHODIMPnsresult
411RemoteLazyInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
412 uint32_t aCount, uint32_t* aResult) {
413 nsCOMPtr<nsIAsyncInputStream> stream;
414 {
415 MutexAutoLock lock(mMutex);
416
417 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "ReadSegments(%u) %s", aCount, Describe(
).get()); } } while (0)
418 ("ReadSegments(%u) %s", aCount, Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "ReadSegments(%u) %s", aCount, Describe(
).get()); } } while (0)
;
419
420 // ReadSegments is not available is we don't have a remoteStream.
421 if (mState == eInit || mState == ePending) {
422 return NS_BASE_STREAM_WOULD_BLOCK;
423 }
424
425 if (mState == eClosed) {
426 return NS_BASE_STREAM_CLOSED;
427 }
428
429 MOZ_ASSERT(mState == eRunning)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == eRunning)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == eRunning))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mState == eRunning"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 429
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mState == eRunning"
")"); do { MOZ_CrashSequence(__null, 429); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
430 MOZ_ASSERT(mInnerStream || mAsyncInnerStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInnerStream || mAsyncInnerStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInnerStream || mAsyncInnerStream
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mInnerStream || mAsyncInnerStream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 430); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mInnerStream || mAsyncInnerStream"
")"); do { MOZ_CrashSequence(__null, 430); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
431
432 nsresult rv = EnsureAsyncRemoteStream();
433 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 433)
) {
434 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Warning,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "EnsureAsyncRemoteStream failed! %s %s",
mozilla::GetStaticErrorName(rv), Describe().get()); } } while
(0)
435 ("EnsureAsyncRemoteStream failed! %s %s",do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "EnsureAsyncRemoteStream failed! %s %s",
mozilla::GetStaticErrorName(rv), Describe().get()); } } while
(0)
436 mozilla::GetStaticErrorName(rv), Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "EnsureAsyncRemoteStream failed! %s %s",
mozilla::GetStaticErrorName(rv), Describe().get()); } } while
(0)
;
437 return rv;
438 }
439
440 stream = mAsyncInnerStream;
441 }
442
443 MOZ_ASSERT(stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(stream)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(stream))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("stream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 443); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stream" ")")
; do { MOZ_CrashSequence(__null, 443); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
444 nsresult rv = stream->ReadSegments(aWriter, aClosure, aCount, aResult);
445 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 445)
) {
446 return rv;
447 }
448
449 // If some data has been read, we mark the stream as consumed.
450 if (*aResult != 0) {
451 MarkConsumed();
452 }
453
454 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "ReadSegments %u/%u bytes", *aResult, aCount
); } } while (0)
455 ("ReadSegments %u/%u bytes", *aResult, aCount))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "ReadSegments %u/%u bytes", *aResult, aCount
); } } while (0)
;
456
457 return NS_OK;
458}
459
460void RemoteLazyInputStream::MarkConsumed() {
461 RefPtr<RemoteLazyInputStreamChild> actor;
462 {
463 MutexAutoLock lock(mMutex);
464 if (mActor) {
465 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "MarkConsumed %s", Describe().get()); } } while
(0)
466 ("MarkConsumed %s", Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "MarkConsumed %s", Describe().get()); } } while
(0)
;
467 }
468
469 actor = mActor.forget();
470 }
471 if (actor) {
472 actor->StreamConsumed();
473 }
474}
475
476NS_IMETHODIMPnsresult
477RemoteLazyInputStream::IsNonBlocking(bool* aNonBlocking) {
478 *aNonBlocking = true;
479 return NS_OK;
480}
481
482NS_IMETHODIMPnsresult
483RemoteLazyInputStream::Close() {
484 RefPtr<RemoteLazyInputStreamChild> actor;
485
486 nsCOMPtr<nsIAsyncInputStream> asyncInnerStream;
487 nsCOMPtr<nsIInputStream> innerStream;
488
489 RefPtr<nsIInputStreamCallback> inputStreamCallback;
490 nsCOMPtr<nsIEventTarget> inputStreamCallbackEventTarget;
491
492 {
493 MutexAutoLock lock(mMutex);
494 if (mState == eClosed) {
495 return NS_OK;
496 }
497
498 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Close %s", Describe().get()); } } while (
0)
499 ("Close %s", Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Close %s", Describe().get()); } } while (
0)
;
500
501 actor = mActor.forget();
502
503 asyncInnerStream = mAsyncInnerStream.forget();
504 innerStream = mInnerStream.forget();
505
506 // TODO(Bug 1737783): Notify to the mFileMetadataCallback that this
507 // lazy input stream has been closed.
508 mFileMetadataCallback = nullptr;
509 mFileMetadataCallbackEventTarget = nullptr;
510
511 inputStreamCallback = mInputStreamCallback.forget();
512 inputStreamCallbackEventTarget = mInputStreamCallbackEventTarget.forget();
513
514 mState = eClosed;
515 }
516
517 if (actor) {
518 actor->StreamConsumed();
519 }
520
521 if (inputStreamCallback) {
522 InputStreamCallbackRunnable::Execute(
523 inputStreamCallback.forget(), inputStreamCallbackEventTarget.forget(),
524 this);
525 }
526
527 if (asyncInnerStream) {
528 asyncInnerStream->CloseWithStatus(NS_BASE_STREAM_CLOSED);
529 }
530
531 if (innerStream) {
532 innerStream->Close();
533 }
534
535 return NS_OK;
536}
537
538// nsICloneableInputStream interface
539
540NS_IMETHODIMPnsresult
541RemoteLazyInputStream::GetCloneable(bool* aCloneable) {
542 *aCloneable = true;
543 return NS_OK;
544}
545
546NS_IMETHODIMPnsresult
547RemoteLazyInputStream::Clone(nsIInputStream** aResult) {
548 return CloneWithRange(0, UINT64_MAX(18446744073709551615UL), aResult);
549}
550
551// nsICloneableInputStreamWithRange interface
552
553NS_IMETHODIMPnsresult
554RemoteLazyInputStream::CloneWithRange(uint64_t aStart, uint64_t aLength,
555 nsIInputStream** aResult) {
556 MutexAutoLock lock(mMutex);
557 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "CloneWithRange %" "l" "u" " %" "l" "u" " %s"
, aStart, aLength, Describe().get()); } } while (0)
558 ("CloneWithRange %" PRIu64 " %" PRIu64 " %s", aStart, aLength,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "CloneWithRange %" "l" "u" " %" "l" "u" " %s"
, aStart, aLength, Describe().get()); } } while (0)
559 Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "CloneWithRange %" "l" "u" " %" "l" "u" " %s"
, aStart, aLength, Describe().get()); } } while (0)
;
560
561 nsresult rv;
562
563 RefPtr<RemoteLazyInputStream> stream;
564 if (mState == eClosed) {
565 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose, ("Cloning closed stream"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Cloning closed stream"); } } while (0)
;
566 stream = new RemoteLazyInputStream();
567 stream.forget(aResult);
568 return NS_OK;
569 }
570
571 uint64_t start = 0;
572 uint64_t length = 0;
573 auto maxLength = CheckedUint64(mLength) - aStart;
574 if (maxLength.isValid()) {
575 start = mStart + aStart;
576 length = std::min(maxLength.value(), aLength);
577 }
578
579 // If the slice would be empty, wrap an empty input stream and return it.
580 if (length == 0) {
581 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose, ("Creating empty stream"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Creating empty stream"); } } while (0)
;
582
583 nsCOMPtr<nsIInputStream> emptyStream;
584 rv = NS_NewCStringInputStream(getter_AddRefs(emptyStream), ""_ns);
585 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 585)
) {
586 return rv;
587 }
588
589 stream = new RemoteLazyInputStream(emptyStream);
590 stream.forget(aResult);
591 return NS_OK;
592 }
593
594 // If we still have a connection to our actor, that means we haven't read any
595 // data yet, and can clone + slice by building a new stream backed by the same
596 // actor.
597 if (mActor) {
598 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Cloning stream with actor"); } } while (
0)
599 ("Cloning stream with actor"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Cloning stream with actor"); } } while (
0)
;
600
601 stream = new RemoteLazyInputStream(mActor, start, length);
602 stream.forget(aResult);
603 return NS_OK;
604 }
605
606 // We no longer have our actor, either because we were constructed without
607 // one, or we've already begun reading. Perform the clone locally on our inner
608 // input stream.
609
610 nsCOMPtr<nsIInputStream> innerStream = mInnerStream;
611 if (mAsyncInnerStream) {
612 innerStream = mAsyncInnerStream;
613 }
614
615 nsCOMPtr<nsIInputStream> replacement;
616 nsCOMPtr<nsICloneableInputStream> cloneable;
617 rv = NS_EnsureInputStreamIsCloneable(innerStream, getter_AddRefs(cloneable),
618 getter_AddRefs(replacement));
619 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 619)
) {
620 return rv;
621 }
622
623 // If we have a replacement stream, record it.
624 if (replacement) {
625 mAsyncInnerStream = do_QueryInterface(replacement);
626 mInnerStream = nullptr;
627
628 MOZ_ASSERT(mAsyncInnerStream, "The replacement stream is always async")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAsyncInnerStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAsyncInnerStream))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mAsyncInnerStream"
" (" "The replacement stream is always async" ")", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 628); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAsyncInnerStream"
") (" "The replacement stream is always async" ")"); do { MOZ_CrashSequence
(__null, 628); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
629
630 // If we have a callback pending, we need to re-call AsyncWait on the inner
631 // stream.
632 if (mInputStreamCallback) {
633 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInputStreamCallbackEventTarget)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInputStreamCallbackEventTarget
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mInputStreamCallbackEventTarget" " (" "We made sure we have an event target in AsyncWait. If we don't, we "
"could be called back synchronously here and deadlock." ")",
"./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 636)
; AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mInputStreamCallbackEventTarget"
") (" "We made sure we have an event target in AsyncWait. If we don't, we "
"could be called back synchronously here and deadlock." ")")
; do { MOZ_CrashSequence(__null, 636); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
634 mInputStreamCallbackEventTarget,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInputStreamCallbackEventTarget)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInputStreamCallbackEventTarget
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mInputStreamCallbackEventTarget" " (" "We made sure we have an event target in AsyncWait. If we don't, we "
"could be called back synchronously here and deadlock." ")",
"./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 636)
; AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mInputStreamCallbackEventTarget"
") (" "We made sure we have an event target in AsyncWait. If we don't, we "
"could be called back synchronously here and deadlock." ")")
; do { MOZ_CrashSequence(__null, 636); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
635 "We made sure we have an event target in AsyncWait. If we don't, we "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInputStreamCallbackEventTarget)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInputStreamCallbackEventTarget
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mInputStreamCallbackEventTarget" " (" "We made sure we have an event target in AsyncWait. If we don't, we "
"could be called back synchronously here and deadlock." ")",
"./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 636)
; AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mInputStreamCallbackEventTarget"
") (" "We made sure we have an event target in AsyncWait. If we don't, we "
"could be called back synchronously here and deadlock." ")")
; do { MOZ_CrashSequence(__null, 636); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
636 "could be called back synchronously here and deadlock.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInputStreamCallbackEventTarget)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInputStreamCallbackEventTarget
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mInputStreamCallbackEventTarget" " (" "We made sure we have an event target in AsyncWait. If we don't, we "
"could be called back synchronously here and deadlock." ")",
"./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 636)
; AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mInputStreamCallbackEventTarget"
") (" "We made sure we have an event target in AsyncWait. If we don't, we "
"could be called back synchronously here and deadlock." ")")
; do { MOZ_CrashSequence(__null, 636); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
637 mAsyncInnerStream->AsyncWait(this, mInputStreamCallbackFlags,
638 mInputStreamCallbackRequestedCount,
639 mInputStreamCallbackEventTarget);
640 }
641 }
642
643 MOZ_ASSERT(cloneable && cloneable->GetCloneable())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(cloneable && cloneable->GetCloneable())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(cloneable && cloneable->GetCloneable())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("cloneable && cloneable->GetCloneable()"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 643
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cloneable && cloneable->GetCloneable()"
")"); do { MOZ_CrashSequence(__null, 643); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
644
645 // Check if we can clone more efficiently with a range.
646 if (length < UINT64_MAX(18446744073709551615UL)) {
647 if (nsCOMPtr<nsICloneableInputStreamWithRange> cloneableWithRange =
648 do_QueryInterface(cloneable)) {
649 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose, ("Cloning with range"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Cloning with range"); } } while (0)
;
650 nsCOMPtr<nsIInputStream> cloned;
651 rv = cloneableWithRange->CloneWithRange(start, length,
652 getter_AddRefs(cloned));
653 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
654 return rv;
655 }
656
657 stream = new RemoteLazyInputStream(cloned);
658 stream.forget(aResult);
659 return NS_OK;
660 }
661 }
662
663 // Directly clone our inner stream, and then slice it if needed.
664 nsCOMPtr<nsIInputStream> cloned;
665 rv = cloneable->Clone(getter_AddRefs(cloned));
666 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
667 return rv;
668 }
669
670 if (length < UINT64_MAX(18446744073709551615UL)) {
671 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Slicing stream with %" "l" "u" " %" "l"
"u", start, length); } } while (0)
672 ("Slicing stream with %" PRIu64 " %" PRIu64, start, length))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Slicing stream with %" "l" "u" " %" "l"
"u", start, length); } } while (0)
;
673 cloned = new SlicedInputStream(cloned.forget(), start, length);
674 }
675
676 stream = new RemoteLazyInputStream(cloned);
677 stream.forget(aResult);
678 return NS_OK;
679}
680
681// nsIAsyncInputStream interface
682
683NS_IMETHODIMPnsresult
684RemoteLazyInputStream::CloseWithStatus(nsresult aStatus) { return Close(); }
685
686NS_IMETHODIMPnsresult
687RemoteLazyInputStream::AsyncWait(nsIInputStreamCallback* aCallback,
688 uint32_t aFlags, uint32_t aRequestedCount,
689 nsIEventTarget* aEventTarget) {
690 // Ensure we always have an event target for AsyncWait callbacks, so that
691 // calls to `AsyncWait` cannot reenter us with `OnInputStreamReady`.
692 nsCOMPtr<nsIEventTarget> eventTarget = aEventTarget;
693 if (aCallback && !eventTarget) {
694 eventTarget = RemoteLazyInputStreamThread::GetOrCreate();
695 if (NS_WARN_IF(!eventTarget)NS_warn_if_impl(!eventTarget, "!eventTarget", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 695)
) {
696 return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
697 }
698 }
699
700 {
701 MutexAutoLock lock(mMutex);
702
703 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "AsyncWait(%p, %u, %u, %p) %s", aCallback
, aFlags, aRequestedCount, aEventTarget, Describe().get()); }
} while (0)
704 ("AsyncWait(%p, %u, %u, %p) %s", aCallback, aFlags, aRequestedCount,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "AsyncWait(%p, %u, %u, %p) %s", aCallback
, aFlags, aRequestedCount, aEventTarget, Describe().get()); }
} while (0)
705 aEventTarget, Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "AsyncWait(%p, %u, %u, %p) %s", aCallback
, aFlags, aRequestedCount, aEventTarget, Describe().get()); }
} while (0)
;
706
707 // See RemoteLazyInputStream.h for more information about this state
708 // machine.
709
710 nsCOMPtr<nsIAsyncInputStream> stream;
711 switch (mState) {
712 // First call, we need to retrieve the stream from the parent actor.
713 case eInit:
714 MOZ_ASSERT(mActor)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mActor)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(mActor))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mActor", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 714); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mActor" ")")
; do { MOZ_CrashSequence(__null, 714); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
715
716 mInputStreamCallback = aCallback;
717 mInputStreamCallbackEventTarget = std::move(eventTarget);
718 mInputStreamCallbackFlags = aFlags;
719 mInputStreamCallbackRequestedCount = aRequestedCount;
720 mState = ePending;
721
722 StreamNeeded();
723 return NS_OK;
724
725 // We are still waiting for the remote inputStream
726 case ePending: {
727 if (NS_WARN_IF(mInputStreamCallback && aCallback &&NS_warn_if_impl(mInputStreamCallback && aCallback &&
mInputStreamCallback != aCallback, "mInputStreamCallback && aCallback && mInputStreamCallback != aCallback"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 728
)
728 mInputStreamCallback != aCallback)NS_warn_if_impl(mInputStreamCallback && aCallback &&
mInputStreamCallback != aCallback, "mInputStreamCallback && aCallback && mInputStreamCallback != aCallback"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 728
)
) {
729 return NS_ERROR_FAILURE;
730 }
731
732 mInputStreamCallback = aCallback;
733 mInputStreamCallbackEventTarget = std::move(eventTarget);
734 mInputStreamCallbackFlags = aFlags;
735 mInputStreamCallbackRequestedCount = aRequestedCount;
736 return NS_OK;
737 }
738
739 // We have the remote inputStream, let's check if we can execute the
740 // callback.
741 case eRunning: {
742 if (NS_WARN_IF(mInputStreamCallback && aCallback &&NS_warn_if_impl(mInputStreamCallback && aCallback &&
mInputStreamCallback != aCallback, "mInputStreamCallback && aCallback && mInputStreamCallback != aCallback"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 743
)
743 mInputStreamCallback != aCallback)NS_warn_if_impl(mInputStreamCallback && aCallback &&
mInputStreamCallback != aCallback, "mInputStreamCallback && aCallback && mInputStreamCallback != aCallback"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 743
)
) {
744 return NS_ERROR_FAILURE;
745 }
746
747 nsresult rv = EnsureAsyncRemoteStream();
748 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 748)
) {
749 return rv;
750 }
751
752 mInputStreamCallback = aCallback;
753 mInputStreamCallbackEventTarget = eventTarget;
754 mInputStreamCallbackFlags = aFlags;
755 mInputStreamCallbackRequestedCount = aRequestedCount;
756
757 stream = mAsyncInnerStream;
758 break;
759 }
760
761 case eClosed:
762 [[fallthrough]];
763 default:
764 MOZ_ASSERT(mState == eClosed)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == eClosed)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == eClosed))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mState == eClosed"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 764
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mState == eClosed"
")"); do { MOZ_CrashSequence(__null, 764); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
765 if (NS_WARN_IF(mInputStreamCallback && aCallback &&NS_warn_if_impl(mInputStreamCallback && aCallback &&
mInputStreamCallback != aCallback, "mInputStreamCallback && aCallback && mInputStreamCallback != aCallback"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 766
)
766 mInputStreamCallback != aCallback)NS_warn_if_impl(mInputStreamCallback && aCallback &&
mInputStreamCallback != aCallback, "mInputStreamCallback && aCallback && mInputStreamCallback != aCallback"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 766
)
) {
767 return NS_ERROR_FAILURE;
768 }
769 break;
770 }
771
772 if (stream) {
773 return stream->AsyncWait(aCallback ? this : nullptr, aFlags,
774 aRequestedCount, eventTarget);
775 }
776 }
777
778 if (aCallback) {
779 // if stream is nullptr here, that probably means the stream has
780 // been closed and the callback can be executed immediately
781 InputStreamCallbackRunnable::Execute(do_AddRef(aCallback),
782 do_AddRef(eventTarget), this);
783 }
784 return NS_OK;
785}
786
787void RemoteLazyInputStream::StreamNeeded() {
788 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "StreamNeeded %s", Describe().get()); } } while
(0)
789 ("StreamNeeded %s", Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "StreamNeeded %s", Describe().get()); } } while
(0)
;
790
791 RefPtr<RemoteLazyInputStreamThread> thread =
792 RemoteLazyInputStreamThread::GetOrCreate();
793 if (NS_WARN_IF(!thread)NS_warn_if_impl(!thread, "!thread", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 793)
) {
794 return;
795 }
796 thread->Dispatch(NS_NewRunnableFunction(
797 "RemoteLazyInputStream::StreamNeeded",
798 [self = RefPtr{this}, actor = mActor, start = mStart, length = mLength] {
799 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Sending StreamNeeded(%" "l" "u" " %" "l" "u"
") %s %d", start, length, nsIDToCString(actor->StreamID()
).get(), actor->CanSend()); } } while (0)
800 gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Sending StreamNeeded(%" "l" "u" " %" "l" "u"
") %s %d", start, length, nsIDToCString(actor->StreamID()
).get(), actor->CanSend()); } } while (0)
801 ("Sending StreamNeeded(%" PRIu64 " %" PRIu64 ") %s %d", start,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Sending StreamNeeded(%" "l" "u" " %" "l" "u"
") %s %d", start, length, nsIDToCString(actor->StreamID()
).get(), actor->CanSend()); } } while (0)
802 length, nsIDToCString(actor->StreamID()).get(), actor->CanSend()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Sending StreamNeeded(%" "l" "u" " %" "l" "u"
") %s %d", start, length, nsIDToCString(actor->StreamID()
).get(), actor->CanSend()); } } while (0)
;
803
804 actor->SendStreamNeeded(
805 start, length,
806 [self](const Maybe<mozilla::ipc::IPCStream>& aStream) {
807 // Try to deserialize the stream from our remote, and close our
808 // stream if it fails.
809 nsCOMPtr<nsIInputStream> stream =
810 mozilla::ipc::DeserializeIPCStream(aStream);
811 if (NS_WARN_IF(!stream)NS_warn_if_impl(!stream, "!stream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 811)
) {
812 NS_WARNING("Failed to deserialize IPC stream")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to deserialize IPC stream"
, nullptr, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 812)
;
813 self->Close();
814 }
815
816 // Lock our mutex to update the inner stream, and collect any
817 // callbacks which we need to invoke.
818 MutexAutoLock lock(self->mMutex);
819
820 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "ResolveStreamNeeded(%p) %s", stream.get()
, self->Describe().get()); } } while (0)
821 ("ResolveStreamNeeded(%p) %s", stream.get(),do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "ResolveStreamNeeded(%p) %s", stream.get()
, self->Describe().get()); } } while (0)
822 self->Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "ResolveStreamNeeded(%p) %s", stream.get()
, self->Describe().get()); } } while (0)
;
823
824 if (self->mState == ePending) {
825 self->mInnerStream = stream.forget();
826 self->mState = eRunning;
827
828 // Notify any listeners that we've now acquired the underlying
829 // stream, so file metadata information will be available.
830 nsCOMPtr<nsIFileMetadataCallback> fileMetadataCallback =
831 self->mFileMetadataCallback.forget();
832 nsCOMPtr<nsIEventTarget> fileMetadataCallbackEventTarget =
833 self->mFileMetadataCallbackEventTarget.forget();
834 if (fileMetadataCallback) {
835 FileMetadataCallbackRunnable::Execute(
836 fileMetadataCallback, fileMetadataCallbackEventTarget,
837 self);
838 }
839
840 // **NOTE** we can re-enter this class here **NOTE**
841 // If we already have an input stream callback, attempt to
842 // register ourselves with AsyncWait on the underlying stream.
843 if (self->mInputStreamCallback) {
844 if (NS_FAILED(self->EnsureAsyncRemoteStream())((bool)(__builtin_expect(!!(NS_FAILED_impl(self->EnsureAsyncRemoteStream
())), 0)))
||
845 NS_FAILED(self->mAsyncInnerStream->AsyncWait(((bool)(__builtin_expect(!!(NS_FAILED_impl(self->mAsyncInnerStream
->AsyncWait( self, self->mInputStreamCallbackFlags, self
->mInputStreamCallbackRequestedCount, self->mInputStreamCallbackEventTarget
))), 0)))
846 self, self->mInputStreamCallbackFlags,((bool)(__builtin_expect(!!(NS_FAILED_impl(self->mAsyncInnerStream
->AsyncWait( self, self->mInputStreamCallbackFlags, self
->mInputStreamCallbackRequestedCount, self->mInputStreamCallbackEventTarget
))), 0)))
847 self->mInputStreamCallbackRequestedCount,((bool)(__builtin_expect(!!(NS_FAILED_impl(self->mAsyncInnerStream
->AsyncWait( self, self->mInputStreamCallbackFlags, self
->mInputStreamCallbackRequestedCount, self->mInputStreamCallbackEventTarget
))), 0)))
848 self->mInputStreamCallbackEventTarget))((bool)(__builtin_expect(!!(NS_FAILED_impl(self->mAsyncInnerStream
->AsyncWait( self, self->mInputStreamCallbackFlags, self
->mInputStreamCallbackRequestedCount, self->mInputStreamCallbackEventTarget
))), 0)))
) {
849 InputStreamCallbackRunnable::Execute(
850 self->mInputStreamCallback.forget(),
851 self->mInputStreamCallbackEventTarget.forget(), self);
852 }
853 }
854 }
855
856 if (stream) {
857 NS_WARNING("Failed to save stream, closing it")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to save stream, closing it"
, nullptr, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 857)
;
858 stream->Close();
859 }
860 },
861 [self](mozilla::ipc::ResponseRejectReason) {
862 NS_WARNING("SendStreamNeeded rejected")NS_DebugBreak(NS_DEBUG_WARNING, "SendStreamNeeded rejected", nullptr
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 862
)
;
863 self->Close();
864 });
865 }));
866}
867
868// nsIInputStreamCallback
869
870NS_IMETHODIMPnsresult
871RemoteLazyInputStream::OnInputStreamReady(nsIAsyncInputStream* aStream) {
872 RefPtr<nsIInputStreamCallback> callback;
873 nsCOMPtr<nsIEventTarget> callbackEventTarget;
874 {
875 MutexAutoLock lock(mMutex);
876 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "OnInputStreamReady %s", Describe().get())
; } } while (0)
877 ("OnInputStreamReady %s", Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "OnInputStreamReady %s", Describe().get())
; } } while (0)
;
878
879 // We have been closed in the meantime.
880 if (mState == eClosed) {
881 return NS_OK;
882 }
883
884 // We got a callback from the wrong stream, likely due to a `CloneWithRange`
885 // call while we were waiting. Ignore this callback.
886 if (mAsyncInnerStream != aStream) {
887 return NS_OK;
888 }
889
890 MOZ_ASSERT(mState == eRunning)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == eRunning)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == eRunning))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mState == eRunning"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 890
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mState == eRunning"
")"); do { MOZ_CrashSequence(__null, 890); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
891
892 // The callback has been canceled in the meantime.
893 if (!mInputStreamCallback) {
894 return NS_OK;
895 }
896
897 callback.swap(mInputStreamCallback);
898 callbackEventTarget.swap(mInputStreamCallbackEventTarget);
899 }
900
901 // This must be the last operation because the execution of the callback can
902 // be synchronous.
903 MOZ_ASSERT(callback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(callback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(callback))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("callback", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 903); AnnotateMozCrashReason("MOZ_ASSERT" "(" "callback" ")"
); do { MOZ_CrashSequence(__null, 903); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
904 InputStreamCallbackRunnable::Execute(callback.forget(),
905 callbackEventTarget.forget(), this);
906 return NS_OK;
907}
908
909// nsIIPCSerializableInputStream
910
911void RemoteLazyInputStream::SerializedComplexity(uint32_t aMaxSize,
912 uint32_t* aSizeUsed,
913 uint32_t* aNewPipes,
914 uint32_t* aTransferables) {
915 *aTransferables = 1;
916}
917
918void RemoteLazyInputStream::Serialize(mozilla::ipc::InputStreamParams& aParams,
919 uint32_t aMaxSize, uint32_t* aSizeUsed) {
920 *aSizeUsed = 0;
921 aParams = mozilla::ipc::RemoteLazyInputStreamParams(WrapNotNull(this));
922}
923
924bool RemoteLazyInputStream::Deserialize(
925 const mozilla::ipc::InputStreamParams& aParams) {
926 MOZ_CRASH("This should never be called.")do { do { } while (false); MOZ_ReportCrash("" "This should never be called."
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 926
); AnnotateMozCrashReason("MOZ_CRASH(" "This should never be called."
")"); do { MOZ_CrashSequence(__null, 926); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
927 return false;
928}
929
930// nsIAsyncFileMetadata
931
932NS_IMETHODIMPnsresult
933RemoteLazyInputStream::AsyncFileMetadataWait(nsIFileMetadataCallback* aCallback,
934 nsIEventTarget* aEventTarget) {
935 MOZ_ASSERT(!!aCallback == !!aEventTarget)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!!aCallback == !!aEventTarget)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!!aCallback == !!aEventTarget
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!!aCallback == !!aEventTarget", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 935); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!!aCallback == !!aEventTarget"
")"); do { MOZ_CrashSequence(__null, 935); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
936
937 // If we have the callback, we must have the event target.
938 if (NS_WARN_IF(!!aCallback != !!aEventTarget)NS_warn_if_impl(!!aCallback != !!aEventTarget, "!!aCallback != !!aEventTarget"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 938
)
) {
939 return NS_ERROR_FAILURE;
940 }
941
942 // See RemoteLazyInputStream.h for more information about this state
943 // machine.
944
945 {
946 MutexAutoLock lock(mMutex);
947 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "AsyncFileMetadataWait(%p, %p) %s", aCallback
, aEventTarget, Describe().get()); } } while (0)
948 ("AsyncFileMetadataWait(%p, %p) %s", aCallback, aEventTarget,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "AsyncFileMetadataWait(%p, %p) %s", aCallback
, aEventTarget, Describe().get()); } } while (0)
949 Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "AsyncFileMetadataWait(%p, %p) %s", aCallback
, aEventTarget, Describe().get()); } } while (0)
;
950
951 switch (mState) {
952 // First call, we need to retrieve the stream from the parent actor.
953 case eInit:
954 MOZ_ASSERT(mActor)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mActor)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(mActor))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mActor", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 954); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mActor" ")")
; do { MOZ_CrashSequence(__null, 954); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
955
956 mFileMetadataCallback = aCallback;
957 mFileMetadataCallbackEventTarget = aEventTarget;
958 mState = ePending;
959
960 StreamNeeded();
961 return NS_OK;
962
963 // We are still waiting for the remote inputStream
964 case ePending:
965 if (mFileMetadataCallback && aCallback) {
966 return NS_ERROR_FAILURE;
967 }
968
969 mFileMetadataCallback = aCallback;
970 mFileMetadataCallbackEventTarget = aEventTarget;
971 return NS_OK;
972
973 // We have the remote inputStream, let's check if we can execute the
974 // callback.
975 case eRunning:
976 break;
977
978 // Stream is closed.
979 default:
980 MOZ_ASSERT(mState == eClosed)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == eClosed)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == eClosed))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mState == eClosed"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 980
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mState == eClosed"
")"); do { MOZ_CrashSequence(__null, 980); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
981 return NS_BASE_STREAM_CLOSED;
982 }
983
984 MOZ_ASSERT(mState == eRunning)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == eRunning)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == eRunning))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mState == eRunning"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 984
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mState == eRunning"
")"); do { MOZ_CrashSequence(__null, 984); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
985 }
986
987 FileMetadataCallbackRunnable::Execute(aCallback, aEventTarget, this);
988 return NS_OK;
989}
990
991// nsIFileMetadata
992
993NS_IMETHODIMPnsresult
994RemoteLazyInputStream::GetSize(int64_t* aRetval) {
995 nsCOMPtr<nsIFileMetadata> fileMetadata;
996 {
997 MutexAutoLock lock(mMutex);
998 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "GetSize %s", Describe().get()); } } while
(0)
999 ("GetSize %s", Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "GetSize %s", Describe().get()); } } while
(0)
;
1000
1001 fileMetadata = do_QueryInterface(mInnerStream);
1002 if (!fileMetadata) {
1003 return mState == eClosed ? NS_BASE_STREAM_CLOSED : NS_ERROR_FAILURE;
1004 }
1005 }
1006
1007 return fileMetadata->GetSize(aRetval);
1008}
1009
1010NS_IMETHODIMPnsresult
1011RemoteLazyInputStream::GetLastModified(int64_t* aRetval) {
1012 nsCOMPtr<nsIFileMetadata> fileMetadata;
1013 {
1014 MutexAutoLock lock(mMutex);
1015 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "GetLastModified %s", Describe().get());
} } while (0)
1016 ("GetLastModified %s", Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "GetLastModified %s", Describe().get());
} } while (0)
;
1017
1018 fileMetadata = do_QueryInterface(mInnerStream);
1019 if (!fileMetadata) {
1020 return mState == eClosed ? NS_BASE_STREAM_CLOSED : NS_ERROR_FAILURE;
1021 }
1022 }
1023
1024 return fileMetadata->GetLastModified(aRetval);
1025}
1026
1027NS_IMETHODIMPnsresult
1028RemoteLazyInputStream::GetFileDescriptor(PRFileDesc** aRetval) {
1029 nsCOMPtr<nsIFileMetadata> fileMetadata;
1030 {
1031 MutexAutoLock lock(mMutex);
1032 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "GetFileDescriptor %s", Describe().get()
); } } while (0)
1033 ("GetFileDescriptor %s", Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "GetFileDescriptor %s", Describe().get()
); } } while (0)
;
1034
1035 fileMetadata = do_QueryInterface(mInnerStream);
1036 if (!fileMetadata) {
1037 return mState == eClosed ? NS_BASE_STREAM_CLOSED : NS_ERROR_FAILURE;
1038 }
1039 }
1040
1041 return fileMetadata->GetFileDescriptor(aRetval);
1042}
1043
1044nsresult RemoteLazyInputStream::EnsureAsyncRemoteStream() {
1045 // We already have an async remote stream.
1046 if (mAsyncInnerStream) {
1047 return NS_OK;
1048 }
1049
1050 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "EnsureAsyncRemoteStream %s", Describe().get
()); } } while (0)
1051 ("EnsureAsyncRemoteStream %s", Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "EnsureAsyncRemoteStream %s", Describe().get
()); } } while (0)
;
1052
1053 if (NS_WARN_IF(!mInnerStream)NS_warn_if_impl(!mInnerStream, "!mInnerStream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1053)
) {
1054 return NS_ERROR_FAILURE;
1055 }
1056
1057 nsCOMPtr<nsIInputStream> stream = mInnerStream;
1058
1059 // Check if the stream is blocking, if it is, we want to make it non-blocking
1060 // using a pipe.
1061 bool nonBlocking = false;
1062 nsresult rv = stream->IsNonBlocking(&nonBlocking);
1063 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1063)
) {
1064 return rv;
1065 }
1066
1067 // We don't return NS_ERROR_NOT_IMPLEMENTED from ReadSegments,
1068 // so it's possible that callers are expecting us to succeed in the future.
1069 // We need to make sure the stream we return here supports ReadSegments,
1070 // so wrap if in a buffered stream if necessary.
1071 //
1072 // We only need to do this if we won't be wrapping the stream in a pipe, which
1073 // will add buffering anyway.
1074 if (nonBlocking && !NS_InputStreamIsBuffered(stream)) {
1075 nsCOMPtr<nsIInputStream> bufferedStream;
1076 nsresult rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
1077 stream.forget(), 4096);
1078 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1078)
) {
1079 return rv;
1080 }
1081
1082 stream = bufferedStream;
1083 }
1084
1085 nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(stream);
1086
1087 // If non-blocking and non-async, let's use NonBlockingAsyncInputStream.
1088 if (nonBlocking && !asyncStream) {
1089 rv = NonBlockingAsyncInputStream::Create(stream.forget(),
1090 getter_AddRefs(asyncStream));
1091 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1091)
) {
1092 return rv;
1093 }
1094
1095 MOZ_ASSERT(asyncStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(asyncStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(asyncStream))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("asyncStream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1095); AnnotateMozCrashReason("MOZ_ASSERT" "(" "asyncStream"
")"); do { MOZ_CrashSequence(__null, 1095); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1096 }
1097
1098 if (!asyncStream) {
1099 // Let's make the stream async using the DOMFile thread.
1100 nsCOMPtr<nsIAsyncInputStream> pipeIn;
1101 nsCOMPtr<nsIAsyncOutputStream> pipeOut;
1102 NS_NewPipe2(getter_AddRefs(pipeIn), getter_AddRefs(pipeOut), true, true);
1103
1104 RefPtr<RemoteLazyInputStreamThread> thread =
1105 RemoteLazyInputStreamThread::GetOrCreate();
1106 if (NS_WARN_IF(!thread)NS_warn_if_impl(!thread, "!thread", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1106)
) {
1107 return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
1108 }
1109
1110 rv = NS_AsyncCopy(stream, pipeOut, thread, NS_ASYNCCOPY_VIA_WRITESEGMENTS);
1111 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1111)
) {
1112 return rv;
1113 }
1114
1115 asyncStream = pipeIn;
1116 }
1117
1118 MOZ_ASSERT(asyncStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(asyncStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(asyncStream))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("asyncStream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1118); AnnotateMozCrashReason("MOZ_ASSERT" "(" "asyncStream"
")"); do { MOZ_CrashSequence(__null, 1118); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1119 mAsyncInnerStream = std::move(asyncStream);
1120 mInnerStream = nullptr;
1121
1122 return NS_OK;
1123}
1124
1125// nsIInputStreamLength
1126
1127NS_IMETHODIMPnsresult
1128RemoteLazyInputStream::Length(int64_t* aLength) {
1129 MutexAutoLock lock(mMutex);
1130
1131 if (mState == eClosed) {
1132 return NS_BASE_STREAM_CLOSED;
1133 }
1134
1135 if (!mActor) {
1136 return NS_ERROR_NOT_AVAILABLE;
1137 }
1138
1139 return NS_BASE_STREAM_WOULD_BLOCK;
1140}
1141
1142namespace {
1143
1144class InputStreamLengthCallbackRunnable final : public DiscardableRunnable {
1145 public:
1146 static void Execute(nsIInputStreamLengthCallback* aCallback,
1147 nsIEventTarget* aEventTarget,
1148 RemoteLazyInputStream* aStream, int64_t aLength) {
1149 MOZ_ASSERT(aCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aCallback))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aCallback", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1149); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aCallback" ")"
); do { MOZ_CrashSequence(__null, 1149); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1150 MOZ_ASSERT(aEventTarget)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aEventTarget)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aEventTarget))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aEventTarget", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1150); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aEventTarget"
")"); do { MOZ_CrashSequence(__null, 1150); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1151
1152 RefPtr<InputStreamLengthCallbackRunnable> runnable =
1153 new InputStreamLengthCallbackRunnable(aCallback, aStream, aLength);
1154
1155 nsCOMPtr<nsIEventTarget> target = aEventTarget;
1156 target->Dispatch(runnable, NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL);
1157 }
1158
1159 NS_IMETHODvirtual nsresult
1160 Run() override {
1161 mCallback->OnInputStreamLengthReady(mStream, mLength);
1162 mCallback = nullptr;
1163 mStream = nullptr;
1164 return NS_OK;
1165 }
1166
1167 private:
1168 InputStreamLengthCallbackRunnable(nsIInputStreamLengthCallback* aCallback,
1169 RemoteLazyInputStream* aStream,
1170 int64_t aLength)
1171 : DiscardableRunnable("dom::InputStreamLengthCallbackRunnable"),
1172 mCallback(aCallback),
1173 mStream(aStream),
1174 mLength(aLength) {
1175 MOZ_ASSERT(mCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCallback))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mCallback", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1175); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCallback" ")"
); do { MOZ_CrashSequence(__null, 1175); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1176 MOZ_ASSERT(mStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mStream))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mStream", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1176); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mStream" ")"
); do { MOZ_CrashSequence(__null, 1176); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1177 }
1178
1179 nsCOMPtr<nsIInputStreamLengthCallback> mCallback;
1180 RefPtr<RemoteLazyInputStream> mStream;
1181 const int64_t mLength;
1182};
1183
1184} // namespace
1185
1186// nsIAsyncInputStreamLength
1187
1188NS_IMETHODIMPnsresult
1189RemoteLazyInputStream::AsyncLengthWait(nsIInputStreamLengthCallback* aCallback,
1190 nsIEventTarget* aEventTarget) {
1191 // If we have the callback, we must have the event target.
1192 if (NS_WARN_IF(!!aCallback != !!aEventTarget)NS_warn_if_impl(!!aCallback != !!aEventTarget, "!!aCallback != !!aEventTarget"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1192
)
) {
1193 return NS_ERROR_FAILURE;
1194 }
1195
1196 {
1197 MutexAutoLock lock(mMutex);
1198
1199 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "AsyncLengthWait(%p, %p) %s", aCallback,
aEventTarget, Describe().get()); } } while (0)
1200 ("AsyncLengthWait(%p, %p) %s", aCallback, aEventTarget,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "AsyncLengthWait(%p, %p) %s", aCallback,
aEventTarget, Describe().get()); } } while (0)
1201 Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "AsyncLengthWait(%p, %p) %s", aCallback,
aEventTarget, Describe().get()); } } while (0)
;
1202
1203 if (mActor) {
1204 if (aCallback) {
1205 RefPtr<RemoteLazyInputStreamThread> thread =
1206 RemoteLazyInputStreamThread::GetOrCreate();
1207 if (NS_WARN_IF(!thread)NS_warn_if_impl(!thread, "!thread", "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp"
, 1207)
) {
1208 return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
1209 }
1210 thread->Dispatch(NS_NewRunnableFunction(
1211 "RemoteLazyInputStream::AsyncLengthWait",
1212 [self = RefPtr{this}, actor = mActor,
1213 callback = nsCOMPtr{aCallback},
1214 eventTarget = nsCOMPtr{aEventTarget}] {
1215 actor->SendLengthNeeded(
1216 [self, callback, eventTarget](int64_t aLength) {
1217 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "AsyncLengthWait resolve %" "l" "d", aLength
); } } while (0)
1218 ("AsyncLengthWait resolve %" PRId64, aLength))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "AsyncLengthWait resolve %" "l" "d", aLength
); } } while (0)
;
1219 int64_t length = -1;
1220 if (aLength > 0) {
1221 uint64_t sourceLength =
1222 aLength - std::min<uint64_t>(aLength, self->mStart);
1223 length = int64_t(
1224 std::min<uint64_t>(sourceLength, self->mLength));
1225 }
1226 InputStreamLengthCallbackRunnable::Execute(
1227 callback, eventTarget, self, length);
1228 },
1229 [self, callback,
1230 eventTarget](mozilla::ipc::ResponseRejectReason) {
1231 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Warning,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "AsyncLengthWait reject"); } } while (0)
1232 ("AsyncLengthWait reject"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "AsyncLengthWait reject"); } } while (0)
;
1233 InputStreamLengthCallbackRunnable::Execute(
1234 callback, eventTarget, self, -1);
1235 });
1236 }));
1237 }
1238
1239 return NS_OK;
1240 }
1241 }
1242
1243 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "AsyncLengthWait immediate"); } } while (
0)
1244 ("AsyncLengthWait immediate"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "AsyncLengthWait immediate"); } } while (
0)
;
1245
1246 // If execution has reached here, it means the stream is either closed or
1247 // consumed, and therefore the callback can be executed immediately
1248 InputStreamLengthCallbackRunnable::Execute(aCallback, aEventTarget, this, -1);
1249 return NS_OK;
1250}
1251
1252void RemoteLazyInputStream::IPCWrite(IPC::MessageWriter* aWriter) {
1253 // If we have an actor still, serialize efficiently by cloning our actor to
1254 // maintain a reference to the parent side.
1255 RefPtr<RemoteLazyInputStreamChild> actor;
1256
1257 nsCOMPtr<nsIInputStream> innerStream;
1258
1259 RefPtr<nsIInputStreamCallback> inputStreamCallback;
1260 nsCOMPtr<nsIEventTarget> inputStreamCallbackEventTarget;
1261
1262 {
1263 MutexAutoLock lock(mMutex);
1264
1265 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Serialize %s", Describe().get()); } } while
(0)
1266 ("Serialize %s", Describe().get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Serialize %s", Describe().get()); } } while
(0)
;
1267
1268 actor = mActor.forget();
1269
1270 if (mAsyncInnerStream) {
1271 MOZ_ASSERT(!mInnerStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mInnerStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mInnerStream))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!mInnerStream",
"./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1271
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInnerStream" ")"
); do { MOZ_CrashSequence(__null, 1271); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1272 innerStream = mAsyncInnerStream.forget();
1273 } else {
1274 innerStream = mInnerStream.forget();
1275 }
1276
1277 // TODO(Bug 1737783): Notify to the mFileMetadataCallback that this
1278 // lazy input stream has been closed.
1279 mFileMetadataCallback = nullptr;
1280 mFileMetadataCallbackEventTarget = nullptr;
1281
1282 inputStreamCallback = mInputStreamCallback.forget();
1283 inputStreamCallbackEventTarget = mInputStreamCallbackEventTarget.forget();
1284
1285 mState = eClosed;
1286 }
1287
1288 if (inputStreamCallback) {
1289 InputStreamCallbackRunnable::Execute(
1290 inputStreamCallback.forget(), inputStreamCallbackEventTarget.forget(),
1291 this);
1292 }
1293
1294 bool closed = !actor && !innerStream;
1295 IPC::WriteParam(aWriter, closed);
1296 if (closed) {
1297 return;
1298 }
1299
1300 // If we still have a connection to our remote actor, create a clone endpoint
1301 // for it and tell it that the stream has been consumed. The clone of the
1302 // connection can be transferred to another process.
1303 if (actor) {
1304 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Serializing as actor: %s", nsIDToCString(
actor->StreamID()).get()); } } while (0)
1305 gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Serializing as actor: %s", nsIDToCString(
actor->StreamID()).get()); } } while (0)
1306 ("Serializing as actor: %s", nsIDToCString(actor->StreamID()).get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Serializing as actor: %s", nsIDToCString(
actor->StreamID()).get()); } } while (0)
;
1307 // Create a clone of the actor, and then tell it that this stream is no
1308 // longer referencing it.
1309 mozilla::ipc::Endpoint<PRemoteLazyInputStreamParent> parentEp;
1310 mozilla::ipc::Endpoint<PRemoteLazyInputStreamChild> childEp;
1311 MOZ_ALWAYS_SUCCEEDS(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &
childEp))), 1)))), 1))) { } else { do { do { } while (false);
MOZ_ReportCrash("" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1312
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
")"); do { MOZ_CrashSequence(__null, 1312); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1312 PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &
childEp))), 1)))), 1))) { } else { do { do { } while (false);
MOZ_ReportCrash("" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1312
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
")"); do { MOZ_CrashSequence(__null, 1312); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
1313
1314 RefPtr<RemoteLazyInputStreamThread> thread =
1315 RemoteLazyInputStreamThread::GetOrCreate();
1316 if (thread) {
1317 thread->Dispatch(NS_NewRunnableFunction(
1318 "RemoteLazyInputStreamChild::SendClone",
1319 [actor, parentEp = std::move(parentEp)]() mutable {
1320 bool ok = actor->SendClone(std::move(parentEp));
1321 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "SendClone for %s: %s", nsIDToCString(actor
->StreamID()).get(), ok ? "OK" : "ERR"); } } while (0)
1322 gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "SendClone for %s: %s", nsIDToCString(actor
->StreamID()).get(), ok ? "OK" : "ERR"); } } while (0)
1323 ("SendClone for %s: %s", nsIDToCString(actor->StreamID()).get(),do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "SendClone for %s: %s", nsIDToCString(actor
->StreamID()).get(), ok ? "OK" : "ERR"); } } while (0)
1324 ok ? "OK" : "ERR"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "SendClone for %s: %s", nsIDToCString(actor
->StreamID()).get(), ok ? "OK" : "ERR"); } } while (0)
;
1325 }));
1326
1327 } // else we are shutting down xpcom threads.
1328
1329 // NOTE: Call `StreamConsumed` after dispatching the `SendClone` runnable,
1330 // as this method may dispatch a runnable to `RemoteLazyInputStreamThread`
1331 // to call `SendGoodbye`, which needs to happen after `SendClone`.
1332 actor->StreamConsumed();
1333
1334 IPC::WriteParam(aWriter, actor->StreamID());
1335 IPC::WriteParam(aWriter, mStart);
1336 IPC::WriteParam(aWriter, mLength);
1337 IPC::WriteParam(aWriter, std::move(childEp));
1338
1339 if (innerStream) {
1340 innerStream->Close();
1341 }
1342 return;
1343 }
1344
1345 // If we have a stream and are in the parent process, create a new actor pair
1346 // and transfer ownership of the stream into storage.
1347 auto streamStorage = RemoteLazyInputStreamStorage::Get();
1348 if (streamStorage.isOk()) {
1349 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1349
); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { MOZ_CrashSequence(__null, 1349); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1350 nsID id = nsID::GenerateUUID();
1351 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Serializing as new stream: %s", nsIDToCString
(id).get()); } } while (0)
1352 ("Serializing as new stream: %s", nsIDToCString(id).get()))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Serializing as new stream: %s", nsIDToCString
(id).get()); } } while (0)
;
1353
1354 streamStorage.inspect()->AddStream(innerStream, id);
1355
1356 mozilla::ipc::Endpoint<PRemoteLazyInputStreamParent> parentEp;
1357 mozilla::ipc::Endpoint<PRemoteLazyInputStreamChild> childEp;
1358 MOZ_ALWAYS_SUCCEEDS(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &
childEp))), 1)))), 1))) { } else { do { do { } while (false);
MOZ_ReportCrash("" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1359
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
")"); do { MOZ_CrashSequence(__null, 1359); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1359 PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &
childEp))), 1)))), 1))) { } else { do { do { } while (false);
MOZ_ReportCrash("" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1359
); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(PRemoteLazyInputStream::CreateEndpoints(&parentEp, &childEp))"
")"); do { MOZ_CrashSequence(__null, 1359); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
1360
1361 // Bind the actor on our background thread.
1362 streamStorage.inspect()->TaskQueue()->Dispatch(NS_NewRunnableFunction(
1363 "RemoteLazyInputStreamParent::Bind",
1364 [parentEp = std::move(parentEp), id]() mutable {
1365 auto stream = MakeRefPtr<RemoteLazyInputStreamParent>(id);
1366 parentEp.Bind(stream);
1367 }));
1368
1369 IPC::WriteParam(aWriter, id);
1370 IPC::WriteParam(aWriter, 0);
1371 IPC::WriteParam(aWriter, UINT64_MAX(18446744073709551615UL));
1372 IPC::WriteParam(aWriter, std::move(childEp));
1373 return;
1374 }
1375
1376 MOZ_CRASH("Cannot serialize new RemoteLazyInputStream from this process")do { do { } while (false); MOZ_ReportCrash("" "Cannot serialize new RemoteLazyInputStream from this process"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1376
); AnnotateMozCrashReason("MOZ_CRASH(" "Cannot serialize new RemoteLazyInputStream from this process"
")"); do { MOZ_CrashSequence(__null, 1376); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1377}
1378
1379already_AddRefed<RemoteLazyInputStream> RemoteLazyInputStream::IPCRead(
1380 IPC::MessageReader* aReader) {
1381 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose, ("Deserialize"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Deserialize"); } } while (0)
;
1382
1383 bool closed;
1384 if (NS_WARN_IF(!IPC::ReadParam(aReader, &closed))NS_warn_if_impl(!IPC::ReadParam(aReader, &closed), "!IPC::ReadParam(aReader, &closed)"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1384
)
) {
1385 return nullptr;
1386 }
1387 if (closed) {
1388 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Deserialize closed stream"); } } while (
0)
1389 ("Deserialize closed stream"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Deserialize closed stream"); } } while (
0)
;
1390 return do_AddRef(new RemoteLazyInputStream());
1391 }
1392
1393 nsID id{};
1394 uint64_t start;
1395 uint64_t length;
1396 mozilla::ipc::Endpoint<PRemoteLazyInputStreamChild> endpoint;
1397 if (NS_WARN_IF(!IPC::ReadParam(aReader, &id))NS_warn_if_impl(!IPC::ReadParam(aReader, &id), "!IPC::ReadParam(aReader, &id)"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1397
)
||
1398 NS_WARN_IF(!IPC::ReadParam(aReader, &start))NS_warn_if_impl(!IPC::ReadParam(aReader, &start), "!IPC::ReadParam(aReader, &start)"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1398
)
||
1399 NS_WARN_IF(!IPC::ReadParam(aReader, &length))NS_warn_if_impl(!IPC::ReadParam(aReader, &length), "!IPC::ReadParam(aReader, &length)"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1399
)
||
1400 NS_WARN_IF(!IPC::ReadParam(aReader, &endpoint))NS_warn_if_impl(!IPC::ReadParam(aReader, &endpoint), "!IPC::ReadParam(aReader, &endpoint)"
, "./../../../../dom/file/ipc/RemoteLazyInputStream.cpp", 1400
)
) {
1401 return nullptr;
1402 }
1403
1404 if (!endpoint.IsValid()) {
1405 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Warning,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "Deserialize failed due to invalid endpoint!"
); } } while (0)
1406 ("Deserialize failed due to invalid endpoint!"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "Deserialize failed due to invalid endpoint!"
); } } while (0)
;
1407 return do_AddRef(new RemoteLazyInputStream());
1408 }
1409
1410 RefPtr<RemoteLazyInputStreamChild> actor =
1411 BindChildActor(id, std::move(endpoint));
1412
1413 if (!actor) {
1414 MOZ_LOG(gRemoteLazyStreamLog, LogLevel::Warning,do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "Deserialize failed as we are probably late in shutdown!"
); } } while (0)
1415 ("Deserialize failed as we are probably late in shutdown!"))do { const ::mozilla::LogModule* moz_real_module = gRemoteLazyStreamLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Warning)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Warning, "Deserialize failed as we are probably late in shutdown!"
); } } while (0)
;
1416 return do_AddRef(new RemoteLazyInputStream());
1417 }
1418
1419 return do_AddRef(new RemoteLazyInputStream(actor, start, length));
1420}
1421
1422} // namespace mozilla
1423
1424void IPC::ParamTraits<mozilla::RemoteLazyInputStream*>::Write(
1425 IPC::MessageWriter* aWriter, mozilla::RemoteLazyInputStream* aParam) {
1426 bool nonNull = !!aParam;
1427 IPC::WriteParam(aWriter, nonNull);
1428 if (aParam) {
1429 aParam->IPCWrite(aWriter);
1430 }
1431}
1432
1433bool IPC::ParamTraits<mozilla::RemoteLazyInputStream*>::Read(
1434 IPC::MessageReader* aReader,
1435 RefPtr<mozilla::RemoteLazyInputStream>* aResult) {
1436 bool nonNull = false;
1437 if (!IPC::ReadParam(aReader, &nonNull)) {
1438 return false;
1439 }
1440 if (!nonNull) {
1441 *aResult = nullptr;
1442 return true;
1443 }
1444 *aResult = mozilla::RemoteLazyInputStream::IPCRead(aReader);
1445 return *aResult;
1446}