⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 113138 in webkit


Ignore:
Timestamp:
Apr 3, 2012, 10:00:54 PM (14 years ago)
Author:
yutak@chromium.org
Message:

Crash in WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel
https://bugs.webkit.org/show_bug.cgi?id=82873

Reviewed by David Levin.

Source/WebCore:

WorkerThreadableWebSocketChannel::Bridge should properly handle the cases where inter-thread
callback is not called due to the termination of the worker run loop. Specifically, the bridge
should not send its "this" pointer to the main thread, because the bridge object may be freed
in the worker thread before the main thread starts to process.

Test: http/tests/websocket/tests/hybi/workers/worker-reload.html

  • Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:

(WebCore::ThreadableWebSocketChannelClientWrapper::ThreadableWebSocketChannelClientWrapper):
(WebCore::ThreadableWebSocketChannelClientWrapper::peer):
(WebCore::ThreadableWebSocketChannelClientWrapper::didCreateWebSocketChannel):
Renamed from setUseHixie76Protocol, as this funtion now also sets m_peer.
Sets m_syncMethodDone to true, because this function is called in the end of
synchronous wait of Bridge::initialize().
(WebCore::ThreadableWebSocketChannelClientWrapper::clearPeer):
(WebCore::ThreadableWebSocketChannelClientWrapper::useHixie76Protocol):

  • Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:

Add WorkerThreadableWebSocketChannel::Peer which is initialized after the creation of
WebSocketChannel in the main thread.
(ThreadableWebSocketChannelClientWrapper):

  • Modules/websockets/WorkerThreadableWebSocketChannel.cpp:

(WebCore::WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel):
Don't do synchronous wait in the constructor, as a member function may be called
during the wait before the constructor finishes. The meat of the constructor has
moved to initialize() function.
(WebCore::WorkerThreadableWebSocketChannel::Bridge::Bridge):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::~Bridge):
(WorkerContextDidInitializeTask):
(WebCore::WorkerContextDidInitializeTask::create):
(WebCore::WorkerContextDidInitializeTask::~WorkerContextDidInitializeTask):
(WebCore::WorkerContextDidInitializeTask::WorkerContextDidInitializeTask):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadInitialize):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::initialize):
Don't pass "this" object to the main thread. Receive the pointer to the peer object
via ThreadableWebSocketChannelClientWrapper which is ThreadSafeRefCounted<>.
(WebCore::WorkerThreadableWebSocketChannel::Bridge::connect):
m_peer may be NULL, and we should not do anything in that case.
(WebCore::WorkerThreadableWebSocketChannel::Bridge::send):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::bufferedAmount):
(WebCore::WorkerThreadableWebSocketChannel::mainThreadClose):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::close):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::fail):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::suspend):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::resume):

  • Modules/websockets/WorkerThreadableWebSocketChannel.h:

(WorkerThreadableWebSocketChannel):
(WebCore::WorkerThreadableWebSocketChannel::refThreadableWebSocketChannel):
(WebCore::WorkerThreadableWebSocketChannel::derefThreadableWebSocketChannel):
(Bridge):

  • workers/DefaultSharedWorkerRepository.cpp:

(SharedWorkerProxy):
(WebCore::SharedWorkerProxy::postTaskForModeToWorkerContext):

  • workers/WorkerLoaderProxy.h:

(WorkerLoaderProxy::postTaskForModeToWorkerContext):
Return bool to indicate whether postTask was successful or not. This is necessary
to avoid memory leaks of Peer object in Bridge::initialize() function.

  • workers/WorkerMessagingProxy.cpp:

(WebCore::WorkerMessagingProxy::postTaskForModeToWorkerContext):

  • workers/WorkerMessagingProxy.h:

(WorkerMessagingProxy):

Source/WebKit/chromium:

Change the function signature of WorkerLoaderProxy::postTaskForModeToWorkerContext().

  • src/WebSharedWorkerImpl.cpp:

(WebKit::WebSharedWorkerImpl::postTaskForModeToWorkerContext):

  • src/WebSharedWorkerImpl.h:

(WebSharedWorkerImpl):

  • src/WebWorkerClientImpl.cpp:

(WebKit::WebWorkerClientImpl::postTaskForModeToWorkerContext):

  • src/WebWorkerClientImpl.h:

(WebWorkerClientImpl):

LayoutTests:

  • http/tests/websocket/tests/hybi/workers/resources/worker-reload-iframe.html: Added.
  • http/tests/websocket/tests/hybi/workers/resources/worker-reload.js: Added.
  • http/tests/websocket/tests/hybi/workers/worker-reload-expected.txt: Added.
  • http/tests/websocket/tests/hybi/workers/worker-reload.html: Added.
Location:
trunk
Files:
4 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r113137 r113138  
     12012-04-03  Yuta Kitamura  <yutak@chromium.org>
     2
     3        Crash in WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel
     4        https://bugs.webkit.org/show_bug.cgi?id=82873
     5
     6        Reviewed by David Levin.
     7
     8        * http/tests/websocket/tests/hybi/workers/resources/worker-reload-iframe.html: Added.
     9        * http/tests/websocket/tests/hybi/workers/resources/worker-reload.js: Added.
     10        * http/tests/websocket/tests/hybi/workers/worker-reload-expected.txt: Added.
     11        * http/tests/websocket/tests/hybi/workers/worker-reload.html: Added.
     12
    1132012-04-03  Keishi Hattori  <keishi@webkit.org>
    214
  • trunk/Source/WebCore/ChangeLog

    r113137 r113138  
     12012-04-03  Yuta Kitamura  <yutak@chromium.org>
     2
     3        Crash in WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel
     4        https://bugs.webkit.org/show_bug.cgi?id=82873
     5
     6        Reviewed by David Levin.
     7
     8        WorkerThreadableWebSocketChannel::Bridge should properly handle the cases where inter-thread
     9        callback is not called due to the termination of the worker run loop. Specifically, the bridge
     10        should not send its "this" pointer to the main thread, because the bridge object may be freed
     11        in the worker thread before the main thread starts to process.
     12
     13        Test: http/tests/websocket/tests/hybi/workers/worker-reload.html
     14
     15        * Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
     16        (WebCore::ThreadableWebSocketChannelClientWrapper::ThreadableWebSocketChannelClientWrapper):
     17        (WebCore::ThreadableWebSocketChannelClientWrapper::peer):
     18        (WebCore::ThreadableWebSocketChannelClientWrapper::didCreateWebSocketChannel):
     19        Renamed from setUseHixie76Protocol, as this funtion now also sets m_peer.
     20        Sets m_syncMethodDone to true, because this function is called in the end of
     21        synchronous wait of Bridge::initialize().
     22        (WebCore::ThreadableWebSocketChannelClientWrapper::clearPeer):
     23        (WebCore::ThreadableWebSocketChannelClientWrapper::useHixie76Protocol):
     24        * Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:
     25        Add WorkerThreadableWebSocketChannel::Peer which is initialized after the creation of
     26        WebSocketChannel in the main thread.
     27        (ThreadableWebSocketChannelClientWrapper):
     28        * Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
     29        (WebCore::WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel):
     30        Don't do synchronous wait in the constructor, as a member function may be called
     31        during the wait before the constructor finishes. The meat of the constructor has
     32        moved to initialize() function.
     33        (WebCore::WorkerThreadableWebSocketChannel::Bridge::Bridge):
     34        (WebCore::WorkerThreadableWebSocketChannel::Bridge::~Bridge):
     35        (WorkerContextDidInitializeTask):
     36        (WebCore::WorkerContextDidInitializeTask::create):
     37        (WebCore::WorkerContextDidInitializeTask::~WorkerContextDidInitializeTask):
     38        (WebCore::WorkerContextDidInitializeTask::WorkerContextDidInitializeTask):
     39        (WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadInitialize):
     40        (WebCore::WorkerThreadableWebSocketChannel::Bridge::initialize):
     41        Don't pass "this" object to the main thread. Receive the pointer to the peer object
     42        via ThreadableWebSocketChannelClientWrapper which is ThreadSafeRefCounted<>.
     43        (WebCore::WorkerThreadableWebSocketChannel::Bridge::connect):
     44        m_peer may be NULL, and we should not do anything in that case.
     45        (WebCore::WorkerThreadableWebSocketChannel::Bridge::send):
     46        (WebCore::WorkerThreadableWebSocketChannel::Bridge::bufferedAmount):
     47        (WebCore::WorkerThreadableWebSocketChannel::mainThreadClose):
     48        (WebCore::WorkerThreadableWebSocketChannel::Bridge::close):
     49        (WebCore::WorkerThreadableWebSocketChannel::Bridge::fail):
     50        (WebCore::WorkerThreadableWebSocketChannel::Bridge::suspend):
     51        (WebCore::WorkerThreadableWebSocketChannel::Bridge::resume):
     52        * Modules/websockets/WorkerThreadableWebSocketChannel.h:
     53        (WorkerThreadableWebSocketChannel):
     54        (WebCore::WorkerThreadableWebSocketChannel::refThreadableWebSocketChannel):
     55        (WebCore::WorkerThreadableWebSocketChannel::derefThreadableWebSocketChannel):
     56        (Bridge):
     57        * workers/DefaultSharedWorkerRepository.cpp:
     58        (SharedWorkerProxy):
     59        (WebCore::SharedWorkerProxy::postTaskForModeToWorkerContext):
     60        * workers/WorkerLoaderProxy.h:
     61        (WorkerLoaderProxy::postTaskForModeToWorkerContext):
     62        Return bool to indicate whether postTask was successful or not. This is necessary
     63        to avoid memory leaks of Peer object in Bridge::initialize() function.
     64        * workers/WorkerMessagingProxy.cpp:
     65        (WebCore::WorkerMessagingProxy::postTaskForModeToWorkerContext):
     66        * workers/WorkerMessagingProxy.h:
     67        (WorkerMessagingProxy):
     68
    1692012-04-03  Keishi Hattori  <keishi@webkit.org>
    270
  • trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp

    r110012 r113138  
    4545    : m_context(context)
    4646    , m_client(client)
     47    , m_peer(0)
    4748    , m_syncMethodDone(true)
    4849    , m_useHixie76Protocol(true)
     
    7374}
    7475
     76WorkerThreadableWebSocketChannel::Peer* ThreadableWebSocketChannelClientWrapper::peer() const
     77{
     78    return m_peer;
     79}
     80
     81void ThreadableWebSocketChannelClientWrapper::didCreateWebSocketChannel(WorkerThreadableWebSocketChannel::Peer* peer, bool useHixie76Protocol)
     82{
     83    m_peer = peer;
     84    m_useHixie76Protocol = useHixie76Protocol;
     85    m_syncMethodDone = true;
     86}
     87
     88void ThreadableWebSocketChannelClientWrapper::clearPeer()
     89{
     90    m_peer = 0;
     91}
     92
    7593bool ThreadableWebSocketChannelClientWrapper::useHixie76Protocol() const
    7694{
    7795    return m_useHixie76Protocol;
    78 }
    79 
    80 void ThreadableWebSocketChannelClientWrapper::setUseHixie76Protocol(bool useHixie76Protocol)
    81 {
    82     m_useHixie76Protocol = useHixie76Protocol;
    8396}
    8497
  • trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h

    r110012 r113138  
    3838#include "ThreadableWebSocketChannel.h"
    3939#include "WebSocketChannelClient.h"
     40#include "WorkerThreadableWebSocketChannel.h"
    4041#include <wtf/Forward.h>
    4142#include <wtf/OwnPtr.h>
     
    5758    bool syncMethodDone() const;
    5859
     60    WorkerThreadableWebSocketChannel::Peer* peer() const;
     61    void didCreateWebSocketChannel(WorkerThreadableWebSocketChannel::Peer*, bool useHixie76Protocol);
     62    void clearPeer();
     63
    5964    // The value of useHixie76Protocol flag is cachable; this value is saved after WebSocketChannel (on the main
    6065    // thread) is constructed.
    6166    bool useHixie76Protocol() const;
    62     void setUseHixie76Protocol(bool);
    6367
    6468    // Subprotocol and extensions are cached too. Will be available when didConnect() callback is invoked.
     
    101105    ScriptExecutionContext* m_context;
    102106    WebSocketChannelClient* m_client;
     107    WorkerThreadableWebSocketChannel::Peer* m_peer;
    103108    bool m_syncMethodDone;
    104109    bool m_useHixie76Protocol;
  • trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp

    r110012 r113138  
    5858    , m_bridge(Bridge::create(m_workerClientWrapper, m_workerContext, taskMode))
    5959{
     60    m_bridge->initialize();
    6061}
    6162
     
    343344    m_mainWebSocketChannel = 0;
    344345    m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidClose, m_workerClientWrapper, unhandledBufferedAmount, closingHandshakeCompletion, code, reason), m_taskMode);
    345 }
    346 
    347 void WorkerThreadableWebSocketChannel::Bridge::setWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, Peer* peer, PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, bool useHixie76Protocol)
    348 {
    349     ASSERT_UNUSED(context, context->isWorkerContext());
    350     thisPtr->m_peer = peer;
    351     workerClientWrapper->setUseHixie76Protocol(useHixie76Protocol);
    352     workerClientWrapper->setSyncMethodDone();
    353 }
    354 
    355 void WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode)
    356 {
    357     ASSERT(isMainThread());
    358     ASSERT_UNUSED(context, context->isDocument());
    359 
    360     RefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper = prpClientWrapper;
    361 
    362     Peer* peer = Peer::create(clientWrapper, thisPtr->m_loaderProxy, context, taskMode);
    363     thisPtr->m_loaderProxy.postTaskForModeToWorkerContext(
    364         createCallbackTask(&Bridge::setWebSocketChannel,
    365                            AllowCrossThreadAccess(thisPtr),
    366                            AllowCrossThreadAccess(peer), clientWrapper, peer->useHixie76Protocol()), taskMode);
    367346}
    368347
     
    375354{
    376355    ASSERT(m_workerClientWrapper.get());
     356}
     357
     358WorkerThreadableWebSocketChannel::Bridge::~Bridge()
     359{
     360    disconnect();
     361}
     362
     363class WorkerContextDidInitializeTask : public ScriptExecutionContext::Task {
     364public:
     365    static PassOwnPtr<ScriptExecutionContext::Task> create(WorkerThreadableWebSocketChannel::Peer* peer,
     366                                                           PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper,
     367                                                           bool useHixie76Protocol)
     368    {
     369        return adoptPtr(new WorkerContextDidInitializeTask(peer, workerClientWrapper, useHixie76Protocol));
     370    }
     371
     372    virtual ~WorkerContextDidInitializeTask() { }
     373    virtual void performTask(ScriptExecutionContext* context) OVERRIDE
     374    {
     375        ASSERT_UNUSED(context, context->isWorkerContext());
     376        m_workerClientWrapper->didCreateWebSocketChannel(m_peer, m_useHixie76Protocol);
     377    }
     378    virtual bool isCleanupTask() const OVERRIDE { return true; }
     379
     380private:
     381    WorkerContextDidInitializeTask(WorkerThreadableWebSocketChannel::Peer* peer,
     382                                   PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper,
     383                                   bool useHixie76Protocol)
     384        : m_peer(peer)
     385        , m_workerClientWrapper(workerClientWrapper)
     386        , m_useHixie76Protocol(useHixie76Protocol)
     387    {
     388    }
     389
     390    WorkerThreadableWebSocketChannel::Peer* m_peer;
     391    RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;
     392    bool m_useHixie76Protocol;
     393};
     394
     395void WorkerThreadableWebSocketChannel::Bridge::mainThreadInitialize(ScriptExecutionContext* context, WorkerLoaderProxy* loaderProxy, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode)
     396{
     397    ASSERT(isMainThread());
     398    ASSERT_UNUSED(context, context->isDocument());
     399
     400    RefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper = prpClientWrapper;
     401
     402    Peer* peer = Peer::create(clientWrapper, *loaderProxy, context, taskMode);
     403    bool sent = loaderProxy->postTaskForModeToWorkerContext(
     404        WorkerContextDidInitializeTask::create(peer, clientWrapper, peer->useHixie76Protocol()), taskMode);
     405    if (!sent) {
     406        clientWrapper->clearPeer();
     407        delete peer;
     408    }
     409}
     410
     411void WorkerThreadableWebSocketChannel::Bridge::initialize()
     412{
     413    ASSERT(!m_peer);
    377414    setMethodNotCompleted();
     415    RefPtr<Bridge> protect(this);
    378416    m_loaderProxy.postTaskToLoader(
    379         createCallbackTask(&Bridge::mainThreadCreateWebSocketChannel,
    380                            AllowCrossThreadAccess(this), m_workerClientWrapper, m_taskMode));
     417        createCallbackTask(&Bridge::mainThreadInitialize,
     418                           AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper, m_taskMode));
    381419    waitForMethodCompletion();
    382     ASSERT(m_peer);
    383 }
    384 
    385 WorkerThreadableWebSocketChannel::Bridge::~Bridge()
    386 {
    387     disconnect();
     420    // m_peer may be null when the nested runloop exited before a peer has created.
     421    m_peer = m_workerClientWrapper->peer();
    388422}
    389423
     
    400434{
    401435    ASSERT(m_workerClientWrapper);
    402     ASSERT(m_peer);
     436    if (!m_peer)
     437        return;
    403438    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadConnect, AllowCrossThreadAccess(m_peer), url, protocol));
    404439}
     
    435470ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const String& message)
    436471{
    437     if (!m_workerClientWrapper)
    438         return ThreadableWebSocketChannel::SendFail;
    439     ASSERT(m_peer);
     472    if (!m_workerClientWrapper || !m_peer)
     473        return ThreadableWebSocketChannel::SendFail;
    440474    setMethodNotCompleted();
    441475    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSend, AllowCrossThreadAccess(m_peer), message));
     
    450484ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryData)
    451485{
    452     if (!m_workerClientWrapper)
    453         return ThreadableWebSocketChannel::SendFail;
    454     ASSERT(m_peer);
     486    if (!m_workerClientWrapper || !m_peer)
     487        return ThreadableWebSocketChannel::SendFail;
    455488    // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>.
    456489    OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(binaryData.byteLength()));
     
    469502ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const Blob& binaryData)
    470503{
    471     if (!m_workerClientWrapper)
    472         return ThreadableWebSocketChannel::SendFail;
    473     ASSERT(m_peer);
     504    if (!m_workerClientWrapper || !m_peer)
     505        return ThreadableWebSocketChannel::SendFail;
    474506    setMethodNotCompleted();
    475507    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSendBlob, AllowCrossThreadAccess(m_peer), binaryData.url(), binaryData.type(), binaryData.size()));
     
    493525unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount()
    494526{
    495     if (!m_workerClientWrapper)
     527    if (!m_workerClientWrapper || !m_peer)
    496528        return 0;
    497     ASSERT(m_peer);
    498529    setMethodNotCompleted();
    499530    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadBufferedAmount, AllowCrossThreadAccess(m_peer)));
     
    506537}
    507538
    508 void WorkerThreadableWebSocketChannel::mainThreadClose(ScriptExecutionContext* context, Peer* peer, int code, const String&reason)
     539void WorkerThreadableWebSocketChannel::mainThreadClose(ScriptExecutionContext* context, Peer* peer, int code, const String& reason)
    509540{
    510541    ASSERT(isMainThread());
     
    517548void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& reason)
    518549{
    519     ASSERT(m_peer);
     550    if (!m_peer)
     551        return;
    520552    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadClose, AllowCrossThreadAccess(m_peer), code, reason));
    521553}
     
    532564void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason)
    533565{
    534     ASSERT(m_peer);
     566    if (!m_peer)
     567        return;
    535568    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadFail, AllowCrossThreadAccess(m_peer), reason));
    536569}
     
    567600void WorkerThreadableWebSocketChannel::Bridge::suspend()
    568601{
    569     ASSERT(m_peer);
     602    if (!m_peer)
     603        return;
    570604    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSuspend, AllowCrossThreadAccess(m_peer)));
    571605}
     
    582616void WorkerThreadableWebSocketChannel::Bridge::resume()
    583617{
    584     ASSERT(m_peer);
     618    if (!m_peer)
     619        return;
    585620    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadResume, AllowCrossThreadAccess(m_peer)));
    586621}
  • trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h

    r110012 r113138  
    3737#include "ThreadableWebSocketChannel.h"
    3838#include "WebSocketChannelClient.h"
     39#include "WorkerContext.h"
    3940
    4041#include <wtf/PassRefPtr.h>
     
    7677    virtual void resume() OVERRIDE;
    7778
    78     using RefCounted<WorkerThreadableWebSocketChannel>::ref;
    79     using RefCounted<WorkerThreadableWebSocketChannel>::deref;
    80 
    81 protected:
    82     virtual void refThreadableWebSocketChannel() { ref(); }
    83     virtual void derefThreadableWebSocketChannel() { deref(); }
    84 
    85 private:
    8679    // Generated by the bridge.  The Peer and its bridge should have identical
    8780    // lifetimes.
     
    124117    };
    125118
     119    using RefCounted<WorkerThreadableWebSocketChannel>::ref;
     120    using RefCounted<WorkerThreadableWebSocketChannel>::deref;
     121
     122protected:
     123    virtual void refThreadableWebSocketChannel() { ref(); }
     124    virtual void derefThreadableWebSocketChannel() { deref(); }
     125
     126private:
    126127    // Bridge for Peer.  Running on the worker thread.
    127128    class Bridge : public RefCounted<Bridge> {
     
    132133        }
    133134        ~Bridge();
     135        void initialize();
    134136        void connect(const KURL&, const String& protocol);
    135137        ThreadableWebSocketChannel::SendResult send(const String& message);
     
    152154
    153155        // Executed on the main thread to create a Peer for this bridge.
    154         static void mainThreadCreateWebSocketChannel(ScriptExecutionContext*, Bridge* thisPtr, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, const String& taskMode);
     156        static void mainThreadInitialize(ScriptExecutionContext*, WorkerLoaderProxy*, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, const String& taskMode);
    155157
    156158        // Executed on the worker context's thread.
  • trunk/Source/WebCore/workers/DefaultSharedWorkerRepository.cpp

    r110023 r113138  
    7878    // WorkerLoaderProxy
    7979    virtual void postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task>);
    80     virtual void postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String&);
     80    virtual bool postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String&);
    8181
    8282    // WorkerReportingProxy
     
    152152}
    153153
    154 void SharedWorkerProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
     154bool SharedWorkerProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
    155155{
    156156    if (isClosing())
    157         return;
     157        return false;
    158158    ASSERT(m_thread);
    159159    m_thread->runLoop().postTaskForMode(task, mode);
     160    return true;
    160161}
    161162
  • trunk/Source/WebCore/workers/WorkerLoaderProxy.h

    r95901 r113138  
    5454        // Posts callbacks from loading code to the WorkerContext. The 'mode' is used to differentiate
    5555        // specific synchronous loading requests so they can be 'nested', per spec.
    56         virtual void postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode) = 0;
     56        // Returns true if the task was posted successfully.
     57        virtual bool postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode) = 0;
    5758    };
    5859
  • trunk/Source/WebCore/workers/WorkerMessagingProxy.cpp

    r108344 r113138  
    297297}
    298298
    299 void WorkerMessagingProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
    300 {
    301     if (m_askedToTerminate)
    302         return;
     299bool WorkerMessagingProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
     300{
     301    if (m_askedToTerminate)
     302        return false;
    303303
    304304    ASSERT(m_workerThread);
    305305    m_workerThread->runLoop().postTaskForMode(task, mode);
     306    return true;
    306307}
    307308
  • trunk/Source/WebCore/workers/WorkerMessagingProxy.h

    r98237 r113138  
    8383        // requests and to send callbacks back to WorkerContext.
    8484        virtual void postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task>);
    85         virtual void postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode);
     85        virtual bool postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode);
    8686
    8787        void workerThreadCreated(PassRefPtr<DedicatedWorkerThread>);
  • trunk/Source/WebKit/chromium/ChangeLog

    r113116 r113138  
     12012-04-03  Yuta Kitamura  <yutak@chromium.org>
     2
     3        Crash in WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel
     4        https://bugs.webkit.org/show_bug.cgi?id=82873
     5
     6        Reviewed by David Levin.
     7
     8        Change the function signature of WorkerLoaderProxy::postTaskForModeToWorkerContext().
     9
     10        * src/WebSharedWorkerImpl.cpp:
     11        (WebKit::WebSharedWorkerImpl::postTaskForModeToWorkerContext):
     12        * src/WebSharedWorkerImpl.h:
     13        (WebSharedWorkerImpl):
     14        * src/WebWorkerClientImpl.cpp:
     15        (WebKit::WebWorkerClientImpl::postTaskForModeToWorkerContext):
     16        * src/WebWorkerClientImpl.h:
     17        (WebWorkerClientImpl):
     18
    1192012-04-03  Ian Vollick  <vollick@chromium.org>
    220
  • trunk/Source/WebKit/chromium/src/WebSharedWorkerImpl.cpp

    r108344 r113138  
    321321}
    322322
    323 void WebSharedWorkerImpl::postTaskForModeToWorkerContext(
     323bool WebSharedWorkerImpl::postTaskForModeToWorkerContext(
    324324    PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
    325325{
    326326    m_workerThread->runLoop().postTaskForMode(task, mode);
     327    return true;
    327328}
    328329
  • trunk/Source/WebKit/chromium/src/WebSharedWorkerImpl.h

    r105687 r113138  
    8787    // WebCore::WorkerLoaderProxy methods:
    8888    virtual void postTaskToLoader(PassOwnPtr<WebCore::ScriptExecutionContext::Task>);
    89     virtual void postTaskForModeToWorkerContext(
     89    virtual bool postTaskForModeToWorkerContext(
    9090        PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const WTF::String& mode);
    9191
  • trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.cpp

    r109948 r113138  
    150150}
    151151
    152 void WebWorkerClientImpl::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
     152bool WebWorkerClientImpl::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
    153153{
    154154    m_proxy->postTaskForModeToWorkerContext(task, mode);
     155    return true;
    155156}
    156157
  • trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.h

    r109958 r113138  
    8787    // WebCore::WorkerLoaderProxy methods:
    8888    virtual void postTaskToLoader(PassOwnPtr<WebCore::ScriptExecutionContext::Task>) OVERRIDE;
    89     virtual void postTaskForModeToWorkerContext(PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const String& mode) OVERRIDE;
     89    virtual bool postTaskForModeToWorkerContext(PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const String& mode) OVERRIDE;
    9090
    9191    // WebCore::WorkerObjectProxy methods:
Note: See TracChangeset for help on using the changeset viewer.