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 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
32 | namespace mozilla { |
33 | |
34 | mozilla::LazyLogModule gRemoteLazyStreamLog("RemoteLazyStream"); |
35 | |
36 | namespace { |
37 | |
38 | class 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 | |
79 | class 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 | |
118 | NS_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; }; |
119 | NS_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 | |
121 | NS_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 |
134 | NS_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 | |
136 | RemoteLazyInputStream::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 | |
155 | RemoteLazyInputStream::RemoteLazyInputStream(nsIInputStream* aStream) |
156 | : mStart(0), mLength(UINT64_MAX(18446744073709551615UL)), mState(eRunning), mInnerStream(aStream) {} |
157 | |
158 | static 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 | |
178 | already_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 | |
230 | NS_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 | |
262 | NS_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 | |
272 | RemoteLazyInputStream::~RemoteLazyInputStream() { Close(); } |
273 | |
274 | nsCString 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 | |
302 | NS_IMETHODIMPnsresult |
303 | RemoteLazyInputStream::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 | |
333 | NS_IMETHODIMPnsresult |
334 | RemoteLazyInputStream::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 | |
363 | NS_IMETHODIMPnsresult |
364 | RemoteLazyInputStream::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 | |
410 | NS_IMETHODIMPnsresult |
411 | RemoteLazyInputStream::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 | |
460 | void 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 | |
476 | NS_IMETHODIMPnsresult |
477 | RemoteLazyInputStream::IsNonBlocking(bool* aNonBlocking) { |
478 | *aNonBlocking = true; |
479 | return NS_OK; |
480 | } |
481 | |
482 | NS_IMETHODIMPnsresult |
483 | RemoteLazyInputStream::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 | |
540 | NS_IMETHODIMPnsresult |
541 | RemoteLazyInputStream::GetCloneable(bool* aCloneable) { |
542 | *aCloneable = true; |
543 | return NS_OK; |
544 | } |
545 | |
546 | NS_IMETHODIMPnsresult |
547 | RemoteLazyInputStream::Clone(nsIInputStream** aResult) { |
548 | return CloneWithRange(0, UINT64_MAX(18446744073709551615UL), aResult); |
549 | } |
550 | |
551 | // nsICloneableInputStreamWithRange interface |
552 | |
553 | NS_IMETHODIMPnsresult |
554 | RemoteLazyInputStream::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 | |
698 | NS_IMETHODIMPnsresult |
699 | RemoteLazyInputStream::CloseWithStatus(nsresult aStatus) { return Close(); } |
700 | |
701 | NS_IMETHODIMPnsresult |
702 | RemoteLazyInputStream::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 | |
802 | void 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 | |
884 | NS_IMETHODIMPnsresult |
885 | RemoteLazyInputStream::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 | |
925 | void RemoteLazyInputStream::SerializedComplexity(uint32_t aMaxSize, |
926 | uint32_t* aSizeUsed, |
927 | uint32_t* aNewPipes, |
928 | uint32_t* aTransferables) { |
929 | *aTransferables = 1; |
930 | } |
931 | |
932 | void 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 | |
938 | bool 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 | |
946 | NS_IMETHODIMPnsresult |
947 | RemoteLazyInputStream::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 | |
1007 | NS_IMETHODIMPnsresult |
1008 | RemoteLazyInputStream::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 | |
1024 | NS_IMETHODIMPnsresult |
1025 | RemoteLazyInputStream::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 | |
1041 | NS_IMETHODIMPnsresult |
1042 | RemoteLazyInputStream::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 | |
1058 | nsresult 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 | |
1141 | NS_IMETHODIMPnsresult |
1142 | RemoteLazyInputStream::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 | |
1156 | namespace { |
1157 | |
1158 | class 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 | |
1202 | NS_IMETHODIMPnsresult |
1203 | RemoteLazyInputStream::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 | |
1265 | void 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 | |
1391 | already_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 | |
1436 | void 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 | |
1445 | bool 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 | } |