Commit e0a40164 authored by ukai@chromium.org's avatar ukai@chromium.org

2010-02-02 Fumitoshi Ukai <ukai@chromium.org>

        Reviewed by Alexey Proskuryakov.

        WebSocket wrapper can be collected even if events are pending
        https://bugs.webkit.org/show_bug.cgi?id=34014

        * websocket/tests/websocket-pending-activity-expected.txt: Added.
        * websocket/tests/websocket-pending-activity.html: Added.
2010-02-02  Fumitoshi Ukai  <ukai@chromium.org>

        Reviewed by Alexey Proskuryakov.

        WebSocket set pending activity to avoid unexpected GC.
        https://bugs.webkit.org/show_bug.cgi?id=34014

        Test: websocket/tests/websocket-pending-activity.html

        * websockets/WebSocket.cpp:
        (WebCore::WebSocket::connect): set pending activity until it receives didClose.
        (WebCore::WebSocket::contextDestroyed): check socket is already closed.
        (WebCore::WebSocket::stop): close the connection and unset pending activity when it stops.
        (WebCore::WebSocket::didClose): unset pending activity.
        * websockets/WebSocket.h:
        * websockets/WebSocketChannel.cpp:
        (WebCore::WebSocketChannel::didReceiveData): protect this while it processes received data.

git-svn-id: svn://svn.chromium.org/blink/trunk@54267 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 818fa908
2010-02-02 Fumitoshi Ukai <ukai@chromium.org>
Reviewed by Alexey Proskuryakov.
WebSocket wrapper can be collected even if events are pending
https://bugs.webkit.org/show_bug.cgi?id=34014
* websocket/tests/websocket-pending-activity-expected.txt: Added.
* websocket/tests/websocket-pending-activity.html: Added.
2010-02-02 Eric Seidel <eric@webkit.org> 2010-02-02 Eric Seidel <eric@webkit.org>
Reviewed by Gustavo Noronha Silva. Reviewed by Gustavo Noronha Silva.
......
<body onload="test()">
<p>Should alert "PASS".</p>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
function gc()
{
if (window.GCController)
return GCController.collect();
for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect)
var s = new String("abc");
}
}
function test()
{
var ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/echo");
ws.onopen = function() {
this.send("PASS");
}
ws.onmessage = function(msg) {
alert(msg.data);
if (window.layoutTestController)
layoutTestController.notifyDone();
}
ws = null;
gc();
}
</script>
2010-02-02 Fumitoshi Ukai <ukai@chromium.org>
Reviewed by Alexey Proskuryakov.
WebSocket set pending activity to avoid unexpected GC.
https://bugs.webkit.org/show_bug.cgi?id=34014
Test: websocket/tests/websocket-pending-activity.html
* websockets/WebSocket.cpp:
(WebCore::WebSocket::connect): set pending activity until it receives didClose.
(WebCore::WebSocket::contextDestroyed): check socket is already closed.
(WebCore::WebSocket::stop): close the connection and unset pending activity when it stops.
(WebCore::WebSocket::didClose): unset pending activity.
* websockets/WebSocket.h:
* websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::didReceiveData): protect this while it processes received data.
2010-02-02 Gustavo Noronha Silva <gns@gnome.org> 2010-02-02 Gustavo Noronha Silva <gns@gnome.org>
No review, rolling out r54261. No review, rolling out r54261.
......
...@@ -151,6 +151,7 @@ void WebSocket::connect(const KURL& url, const String& protocol, ExceptionCode& ...@@ -151,6 +151,7 @@ void WebSocket::connect(const KURL& url, const String& protocol, ExceptionCode&
m_channel = ThreadableWebSocketChannel::create(scriptExecutionContext(), this, m_url, m_protocol); m_channel = ThreadableWebSocketChannel::create(scriptExecutionContext(), this, m_url, m_protocol);
m_channel->connect(); m_channel->connect();
ActiveDOMObject::setPendingActivity(this);
} }
bool WebSocket::send(const String& message, ExceptionCode& ec) bool WebSocket::send(const String& message, ExceptionCode& ec)
...@@ -198,6 +199,26 @@ ScriptExecutionContext* WebSocket::scriptExecutionContext() const ...@@ -198,6 +199,26 @@ ScriptExecutionContext* WebSocket::scriptExecutionContext() const
return ActiveDOMObject::scriptExecutionContext(); return ActiveDOMObject::scriptExecutionContext();
} }
void WebSocket::contextDestroyed()
{
LOG(Network, "WebSocket %p scriptExecutionContext destroyed", this);
ASSERT(!m_channel);
ASSERT(m_state == CLOSED);
ActiveDOMObject::contextDestroyed();
}
void WebSocket::stop()
{
bool pending = hasPendingActivity();
if (m_channel)
m_channel->disconnect();
m_channel = 0;
m_state = CLOSED;
ActiveDOMObject::stop();
if (pending)
ActiveDOMObject::unsetPendingActivity(this);
}
void WebSocket::didConnect() void WebSocket::didConnect()
{ {
LOG(Network, "WebSocket %p didConnect", this); LOG(Network, "WebSocket %p didConnect", this);
...@@ -224,6 +245,9 @@ void WebSocket::didClose() ...@@ -224,6 +245,9 @@ void WebSocket::didClose()
LOG(Network, "WebSocket %p didClose", this); LOG(Network, "WebSocket %p didClose", this);
m_state = CLOSED; m_state = CLOSED;
dispatchEvent(Event::create(eventNames().closeEvent, false, false)); dispatchEvent(Event::create(eventNames().closeEvent, false, false));
m_channel = 0;
if (hasPendingActivity())
ActiveDOMObject::unsetPendingActivity(this);
} }
EventTargetData* WebSocket::eventTargetData() EventTargetData* WebSocket::eventTargetData()
......
...@@ -82,6 +82,8 @@ namespace WebCore { ...@@ -82,6 +82,8 @@ namespace WebCore {
virtual WebSocket* toWebSocket() { return this; } virtual WebSocket* toWebSocket() { return this; }
virtual ScriptExecutionContext* scriptExecutionContext() const; virtual ScriptExecutionContext* scriptExecutionContext() const;
virtual void contextDestroyed();
virtual void stop();
using RefCounted<WebSocket>::ref; using RefCounted<WebSocket>::ref;
using RefCounted<WebSocket>::deref; using RefCounted<WebSocket>::deref;
......
...@@ -141,6 +141,7 @@ void WebSocketChannel::didClose(SocketStreamHandle* handle) ...@@ -141,6 +141,7 @@ void WebSocketChannel::didClose(SocketStreamHandle* handle)
void WebSocketChannel::didReceiveData(SocketStreamHandle* handle, const char* data, int len) void WebSocketChannel::didReceiveData(SocketStreamHandle* handle, const char* data, int len)
{ {
LOG(Network, "WebSocketChannel %p didReceiveData %d", this, len); LOG(Network, "WebSocketChannel %p didReceiveData %d", this, len);
RefPtr<WebSocketChannel> protect(this); // The client can close the channel, potentially removing the last reference.
ASSERT(handle == m_handle); ASSERT(handle == m_handle);
if (!appendToBuffer(data, len)) { if (!appendToBuffer(data, len)) {
handle->close(); handle->close();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment