The error handler of ReadableJSStream should own stream object
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Sep 2015 00:04:04 +0000 (00:04 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Sep 2015 00:04:04 +0000 (00:04 +0000)
commit143ece120db543faf3da6821463977a91ba0a225
treec4730ca688e3cb587cf4061d0d1170d3c434002e
parent0f8053c2725e57b6c815556f109c80c389f362fe
The error handler of ReadableJSStream should own stream object
https://bugs.webkit.org/show_bug.cgi?id=148653

Reviewed by Sam Weinig.

ReadableJSStream's m_errorFunction does not own the readable stream.
So when this error callback is executed asynchronously through Promises,
the stream could be already destroyed.
The fulfill callback which is jointly configured with this error callback
owns the stream. However, when the promise is rejected, the following things
occur.

1. Promise clears the fulfill handlers immediately.
2. queue the reject handlers to the microtask queue.
3. When draining the microtasks, the rejected handler will be executed.

At the time of 2 or 3, the references to the fulfill handlers are already discarded.
So when GC occurs at the time of 2 or 3, it will collect the fulfill handlers and the
stream object owned by the fulfill handlers even if the error callback will touch the
stream object later.

Before r189124, this fault does not occur. This is because the std::function in the
fulfill handler is not destroyed before that patch. Since the std::function owns the
stream object, the std::function and the stream object were leaked and never destroyed.
After that patch, the std::function in the fulfill handler becomes destroyed. And it
makes this fault happen.

In this patch, we separate the error callback from the stream object. Previously, the
error callback resides in the stream object as the member. To avoid the cyclic references,
this error callback did not own the stream object. But this causes this fault.
Instead of caching the error callback in the stream object, we always create the error
callback, when it is needed. The created error callback owns the stream object as well as
the fulfill callbacks owns the stream object.

No behavior change.

* bindings/js/ReadableJSStream.cpp:
(WebCore::createGenericErrorRejectedFunction):
(WebCore::ReadableJSStream::doStart):
(WebCore::ReadableJSStream::doPull):
(WebCore::ReadableJSStream::ReadableJSStream): Deleted.
* bindings/js/ReadableJSStream.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189196 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/ReadableJSStream.cpp
Source/WebCore/bindings/js/ReadableJSStream.h