Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/dom/file/ipc/RemoteLazyInputStream.cpp
Warning:line 275, column 15
Value stored to 'state' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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