Bug Summary

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