Closed
Bug 1424183
Opened 7 years ago
Closed 7 years ago
merged Blob from sliced one produce corrupted Blob - follow up
Categories
(Core :: DOM: File, defect, P1)
Tracking
()
RESOLVED
FIXED
mozilla59
Tracking | Status | |
---|---|---|
firefox-esr52 | --- | unaffected |
firefox57 | --- | unaffected |
firefox58 | --- | wontfix |
firefox59 | --- | fixed |
People
(Reporter: baku, Assigned: baku)
References
Details
(Keywords: regression)
Attachments
(4 files, 4 obsolete files)
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
This is the continuation of bug 1421176.
I have to admit that when I was testing that issue I was using 4096 as a buffer size to make the test faster. This was hiding bugs in nsMultiplexInputStream when using the testcase from bug 1421176.
Assignee | ||
Comment 1•7 years ago
|
||
nsMultiplexInputStream::AsyncWait() calls asyncWait for any substream. This ends up creating too many file descriptors in this scenario: DOM File pointing to a underlying OS File, split in more than 1024 parts, and reassembled.
Initially, the multiple asyncWait() calls were needed because ::Available() was counting the available size for each substream. This is not the case anymore after bug 1421176.
This means that we can call asyncWait() only on the current stream.
Bonus goal, we don't have to use the main-thread if the eventTarget is not passed. I have a separate patch with a gtest.
Assignee: nobody → amarchesini
Attachment #8935684 -
Flags: review?(bugs)
Assignee | ||
Comment 2•7 years ago
|
||
We must call the nsIInputStreamCallback callback also when the stream is already closed. This is correct following nsIAsyncInputStream.idl and it makes nsInputStreamPump happy.
Attachment #8935685 -
Flags: review?(bugs)
Assignee | ||
Comment 3•7 years ago
|
||
Last part is about ::Available(). If the current stream is closed, we must move to the following one, otherwise, if ::AsyncWait() is called, we end up calling ::AsyncWait() on the current stream where there is nothing else to read.
Attachment #8935687 -
Flags: review?(bugs)
Assignee | ||
Comment 4•7 years ago
|
||
gtest was already there. Better to merge the patch.
Attachment #8935684 -
Attachment is obsolete: true
Attachment #8935684 -
Flags: review?(bugs)
Attachment #8935693 -
Flags: review?(bugs)
Comment 5•7 years ago
|
||
Comment on attachment 8935685 [details] [diff] [review]
part 2 - closed stream and AsyncWait
ok, I don't yet understand the later part of the patch.
Comment 6•7 years ago
|
||
Comment on attachment 8935687 [details] [diff] [review]
part 3 - currentStream is closed
ok, looks like also elsewhere mCurrentStream may point outside mStreams. A bit worrisome, but since that is the case elsewhere too, fine.
Attachment #8935687 -
Flags: review?(bugs) → review+
Comment 7•7 years ago
|
||
Comment on attachment 8935693 [details] [diff] [review]
part 1 - too many file descriptors
>@@ -179,20 +175,16 @@ TEST(TestMultiplexInputStream, AsyncWait
> RefPtr<testing::InputStreamCallback> cb =
> new testing::InputStreamCallback();
>
> ASSERT_EQ(NS_OK, ais->AsyncWait(cb, nsIAsyncInputStream::WAIT_CLOSURE_ONLY,
> 0, nullptr));
> ASSERT_FALSE(cb->Called());
>
> ais->CloseWithStatus(NS_ERROR_FAILURE);
>- ASSERT_FALSE(cb->Called());
>-
>- // Eventually it is called.
>- MOZ_ALWAYS_TRUE(mozilla::SpinEventLoopUntil([&]() { return cb->Called(); }));
> ASSERT_TRUE(cb->Called());
Why SpinEventLoopUntil can be removed?
AsyncWait says that the callback should be called async.
That hints aboud some unexpected behavior here.
Attachment #8935693 -
Flags: review?(bugs) → review-
Comment 8•7 years ago
|
||
Comment on attachment 8935685 [details] [diff] [review]
part 2 - closed stream and AsyncWait
I tried and failed to understand
- if (mCurrentStream < mStreams.Length() &&
+ if (NS_SUCCEEDED(mStatus) &&
+ mCurrentStream < mStreams.Length() &&
Please add a comment there explaining why we don't use the stream in NS_FAILED case
Attachment #8935685 -
Flags: review?(bugs) → review-
Comment 9•7 years ago
|
||
FWIW, I think the documentation is unclear here.
https://searchfox.org/mozilla-central/rev/f5f1c3f294f89cfd242c3af9eb2c40d19d5e04e7/xpcom/io/nsIAsyncInputStream.idl#56-57
What does "event will be dispatched immediately" means?
OnInputStreamReady is not any kind of event or runnable.
And the first sentence about the method says
"Asynchronously wait for the stream to be readable or closed."
Assignee | ||
Comment 10•7 years ago
|
||
> AsyncWait says that the callback should be called async.
> That hints aboud some unexpected behavior here.
Absolutely not. This is the behavior described in nsIAsyncInputStream::asyncWait and it is the same behavior implemented elsewhere. IPCBlobInputStream, pipe, SlicedInputStream and so on.
Flags: needinfo?(bugs)
Assignee | ||
Comment 11•7 years ago
|
||
> And the first sentence about the method says
> "Asynchronously wait for the stream to be readable or closed."
https://searchfox.org/mozilla-central/rev/f5f1c3f294f89cfd242c3af9eb2c40d19d5e04e7/xpcom/io/nsIAsyncInputStream.idl#71-74
* @param aEventTarget
* Specify NULL to receive notification on ANY thread (possibly even
* recursively on the calling thread -- i.e., synchronously), or
* specify that the notification be delivered to a specific event
* target.
Assignee | ||
Comment 12•7 years ago
|
||
Comments improved
Attachment #8935685 -
Attachment is obsolete: true
Attachment #8936001 -
Flags: review?(bugs)
Assignee | ||
Comment 13•7 years ago
|
||
Attachment #8936001 -
Attachment is obsolete: true
Attachment #8936001 -
Flags: review?(bugs)
Attachment #8936002 -
Flags: review?(bugs)
Updated•7 years ago
|
Flags: needinfo?(bugs)
Attachment #8936002 -
Flags: review?(bugs) → review+
Comment 14•7 years ago
|
||
Please ask then re-review for part 1. I have not reviewed it.
At least the documentation needs to be fixed.
Updated•7 years ago
|
status-firefox58:
--- → affected
status-firefox59:
--- → affected
Assignee | ||
Comment 15•7 years ago
|
||
Attachment #8935693 -
Attachment is obsolete: true
Attachment #8936228 -
Flags: review?(bugs)
Comment 16•7 years ago
|
||
BTW, since asyncWait isn't then really async, I'm pretty sure we have bugs where code expects it to be async. We should either rename it or fix it to be always async.
The current setup is totally broken.
Comment 17•7 years ago
|
||
But that isn't really about this bug. But just very very error prone setup.
Comment 18•7 years ago
|
||
Comment on attachment 8936228 [details] [diff] [review]
part 1 - too many file descriptors
I don't understand why we need to inject the broken AsyncWait handling here too.
Why we can't keep async handling always?
Either I'm missing something, or removing that asynchronousness has nothing to do with this bug.
Please explain.
Attachment #8936228 -
Flags: review?(bugs) → review-
Assignee | ||
Updated•7 years ago
|
Attachment #8936228 -
Flags: review- → review?(bugs)
Comment 19•7 years ago
|
||
Comment on attachment 8936228 [details] [diff] [review]
part 1 - too many file descriptors
> nsMultiplexInputStream::Close()
> {
>- MutexAutoLock lock(mLock);
>- mStatus = NS_BASE_STREAM_CLOSED;
>+ nsTArray<nsCOMPtr<nsIInputStream>> streams;
>+
>+ // Let's take a copy of the streams becuase, calling close() it could trigger
because
Attachment #8936228 -
Flags: review?(bugs) → review+
Assignee | ||
Comment 20•7 years ago
|
||
This is the last part: nsIAsyncInputStream must always have data (if not closed) after a OnInputStreamReady(). We must be sure that nsMultiplexInputStream behaves in this way.
This patch expands an existing test to be sure that all the possible combinations are covered. If you want, I can add a gtest as well.
Attachment #8936484 -
Flags: review?(bugs)
Updated•7 years ago
|
Attachment #8936484 -
Flags: review?(bugs) → review+
Comment 21•7 years ago
|
||
Pushed by amarchesini@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/26cc9645024a
nsMultiplexInputStream must not call AsyncOpen on more than the current stream, r=smaug
https://hg.mozilla.org/integration/mozilla-inbound/rev/4d0f2d6cd33d
nsMultiplexInputStream must call OnInputStreamReady when closed, r=smaug
https://hg.mozilla.org/integration/mozilla-inbound/rev/c5fd38f7fea7
nsMultiplexInputStream must move to the following stream if the current one doesn't have data to read, r=smaug
https://hg.mozilla.org/integration/mozilla-inbound/rev/dfeab081202f
nsMultiplexInputStream must call OnInputStreamReady only when there is data available, r=smaug
Comment 22•7 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/26cc9645024a
https://hg.mozilla.org/mozilla-central/rev/4d0f2d6cd33d
https://hg.mozilla.org/mozilla-central/rev/c5fd38f7fea7
https://hg.mozilla.org/mozilla-central/rev/dfeab081202f
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla59
Comment 23•7 years ago
|
||
You will hate me...
It seems to have fixed something, but I guess there is still something wrong:
Have a look at https://jsfiddle.net/bbnh7L7n/
Choose a big File (at least a few MB)
On my computer, after clicking on "download", the download speed is around 30ko/s.
This can also be seen when trying to play the merged video blob in a video element, somehow, the video element takes a long time to load it.
And worse, after cancelling the downloading, FF eventually crashes.
What is really weird though, is that this doesn't happens with Blob loaded through network (e.g fetch#blob()). In this case, there is absolutely no problem.
Should I open a new issue?
Flags: needinfo?(amarchesini)
Comment 25•7 years ago
|
||
Too late for Beta58. Mark 58 won't fix.
Updated•7 years ago
|
status-firefox57:
--- → unaffected
status-firefox-esr52:
--- → unaffected
You need to log in
before you can comment on or make changes to this bug.
Description
•