Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog (216488 => 216489)
--- releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog 2017-05-09 09:41:49 UTC (rev 216488)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog 2017-05-09 09:58:24 UTC (rev 216489)
@@ -1,3 +1,25 @@
+2017-04-12 Carlos Garcia Campos <cgar...@igalia.com>
+
+ [GTK] Crash at WebCore::ResourceHandle::clearClient() when streaming live video from dailymotion
+ https://bugs.webkit.org/show_bug.cgi?id=169725
+
+ Reviewed by Michael Catanzaro.
+
+ Make ResourceHandleStreamingClient refcounted and add an invalidate method to do the cleanup in the networking
+ thread while keeping a reference.
+
+ * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
+ (webKitWebSrcStop): Call invalidate before reseting client pointer.
+ (webKitWebSrcStart): Ditto.
+ (ResourceHandleStreamingClient::ResourceHandleStreamingClient): Remove all cleanup code after the run loop run call.
+ (ResourceHandleStreamingClient::~ResourceHandleStreamingClient): Just detach the thread.
+ (ResourceHandleStreamingClient::invalidate): Schedule a task on the networking thread to clean up and fiish the
+ run loop, protecting this.
+ (ResourceHandleStreamingClient::setDefersLoading): Protect this.
+ (ResourceHandleStreamingClient::didReceiveResponse): Do nothing if client was invalidated.
+ (ResourceHandleStreamingClient::didReceiveBuffer): Ditto.
+ (ResourceHandleStreamingClient::didFinishLoading): Ditto.
+
2017-04-07 Alex Christensen <achristen...@webkit.org>
REGRESSION(r204512): WebSocket errors with "Failed to send WebSocket frame." if too much data is sent
Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp (216488 => 216489)
--- releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp 2017-05-09 09:41:49 UTC (rev 216488)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp 2017-05-09 09:58:24 UTC (rev 216489)
@@ -80,17 +80,24 @@
void loadFinished(PlatformMediaResource&) override;
};
-class ResourceHandleStreamingClient : public ResourceHandleClient, public StreamingClient {
- WTF_MAKE_NONCOPYABLE(ResourceHandleStreamingClient); WTF_MAKE_FAST_ALLOCATED;
+class ResourceHandleStreamingClient : public ThreadSafeRefCounted<ResourceHandleStreamingClient>, public ResourceHandleClient, public StreamingClient {
public:
- ResourceHandleStreamingClient(WebKitWebSrc*, ResourceRequest&&);
+ static Ref<ResourceHandleStreamingClient> create(WebKitWebSrc* src, ResourceRequest&& request)
+ {
+ return adoptRef(*new ResourceHandleStreamingClient(src, WTFMove(request)));
+ }
virtual ~ResourceHandleStreamingClient();
+ void invalidate();
+
// StreamingClient virtual methods.
bool loadFailed() const;
void setDefersLoading(bool);
private:
+ ResourceHandleStreamingClient(WebKitWebSrc*, ResourceRequest&&);
+ void cleanupAndStopRunLoop();
+
// ResourceHandleClient virtual methods.
#if USE(SOUP)
char* getOrCreateReadBuffer(size_t requestedSize, size_t& actualSize) override;
@@ -135,7 +142,7 @@
RefPtr<PlatformMediaResourceLoader> loader;
RefPtr<PlatformMediaResource> resource;
- std::unique_ptr<ResourceHandleStreamingClient> client;
+ RefPtr<ResourceHandleStreamingClient> client;
bool didPassAccessControlCheck;
@@ -404,12 +411,15 @@
});
}
+ if (priv->client) {
+ priv->client->invalidate();
+ priv->client = nullptr;
+ }
+
WTF::GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
bool wasSeeking = std::exchange(priv->isSeeking, false);
- priv->client = nullptr;
-
if (priv->buffer) {
unmapGstBuffer(priv->buffer.get());
priv->buffer.clear();
@@ -557,10 +567,9 @@
request.setHTTPHeaderField(HTTPHeaderName::IcyMetadata, "1");
if (!priv->player || !priv->createdInMainThread) {
- priv->client = std::make_unique<ResourceHandleStreamingClient>(src, WTFMove(request));
+ priv->client = ResourceHandleStreamingClient::create(src, WTFMove(request));
if (priv->client->loadFailed()) {
GST_ERROR_OBJECT(src, "Failed to setup streaming client");
- priv->client = nullptr;
locker.unlock();
webKitWebSrcStop(src);
} else
@@ -1080,14 +1089,6 @@
m_runLoop->dispatch([this] { m_resource->setDefersLoading(false); });
m_runLoop->run();
- {
- LockHolder locker(m_terminateRunLoopConditionMutex);
- m_runLoop = nullptr;
- m_resource->clearClient();
- m_resource->cancel();
- m_resource = nullptr;
- m_terminateRunLoopCondition.notifyOne();
- }
});
m_initializeRunLoopCondition.wait(m_initializeRunLoopConditionMutex);
}
@@ -1098,14 +1099,30 @@
detachThread(m_thread);
m_thread = 0;
}
+}
- if (m_runLoop == &RunLoop::current())
- m_runLoop->stop();
- else {
+void ResourceHandleStreamingClient::cleanupAndStopRunLoop()
+{
+ m_resource->clearClient();
+ m_resource->cancel();
+ m_resource = nullptr;
+ m_runLoop->stop();
+}
+
+void ResourceHandleStreamingClient::invalidate()
+{
+ if (m_runLoop == &RunLoop::current()) {
+ cleanupAndStopRunLoop();
+ return;
+ }
+
+ LockHolder locker(m_terminateRunLoopConditionMutex);
+ m_runLoop->dispatch([this, protectedThis = makeRef(*this)] {
+ cleanupAndStopRunLoop();
LockHolder locker(m_terminateRunLoopConditionMutex);
- m_runLoop->stop();
- m_terminateRunLoopCondition.wait(m_terminateRunLoopConditionMutex);
- }
+ m_terminateRunLoopCondition.notifyOne();
+ });
+ m_terminateRunLoopCondition.wait(m_terminateRunLoopConditionMutex);
}
bool ResourceHandleStreamingClient::loadFailed() const
@@ -1115,7 +1132,7 @@
void ResourceHandleStreamingClient::setDefersLoading(bool defers)
{
- m_runLoop->dispatch([this, defers] {
+ m_runLoop->dispatch([this, protectedThis = makeRef(*this), defers] {
if (m_resource)
m_resource->setDefersLoading(defers);
});
@@ -1135,7 +1152,8 @@
void ResourceHandleStreamingClient::didReceiveResponse(ResourceHandle*, ResourceResponse&& response)
{
- handleResponseReceived(response);
+ if (m_resource)
+ handleResponseReceived(response);
}
void ResourceHandleStreamingClient::didReceiveData(ResourceHandle*, const char* /* data */, unsigned /* length */, int)
@@ -1145,6 +1163,9 @@
void ResourceHandleStreamingClient::didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&& buffer, int /* encodedLength */)
{
+ if (!m_resource)
+ return;
+
// This pattern is suggested by SharedBuffer.h.
const char* segment;
unsigned position = 0;
@@ -1156,7 +1177,8 @@
void ResourceHandleStreamingClient::didFinishLoading(ResourceHandle*, double)
{
- handleNotifyFinished();
+ if (m_resource)
+ handleNotifyFinished();
}
void ResourceHandleStreamingClient::didFail(ResourceHandle*, const ResourceError& error)