Changeset 247094 in webkit


Ignore:
Timestamp:
Jul 3, 2019 10:48:41 AM (5 years ago)
Author:
Chris Dumez
Message:

Crash under WTF::RefCounted<WebKit::TaskCounter>::deref()
https://bugs.webkit.org/show_bug.cgi?id=199453
<rdar://problem/51991477>

Reviewed by Youenn Fablet.

The crash was caused by StorageManager::suspend() getting called on the main thread but calling
its completion handler on a background queue. The completion handler was capturing a TaskCounter
object which is RefCounted (not ThreadSafeRefCounted).

Address the issue by making sure StorageManager::suspend() calls its completion handler on the
main thread. Also get rid of TaskCounter and use a WTF::CallbackAggregator instead.

  • NetworkProcess/NetworkProcess.cpp:

(WebKit::NetworkProcess::actualPrepareToSuspend):
(WebKit::TaskCounter::TaskCounter): Deleted.
(WebKit::TaskCounter::~TaskCounter): Deleted.

  • NetworkProcess/WebStorage/StorageManager.cpp:

(WebKit::StorageManager::suspend):

Location:
trunk/Source/WebKit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r247092 r247094  
     12019-07-03  Chris Dumez  <cdumez@apple.com>
     2
     3        Crash under WTF::RefCounted<WebKit::TaskCounter>::deref()
     4        https://bugs.webkit.org/show_bug.cgi?id=199453
     5        <rdar://problem/51991477>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        The crash was caused by StorageManager::suspend() getting called on the main thread but calling
     10        its completion handler on a background queue. The completion handler was capturing a TaskCounter
     11        object which is RefCounted (not ThreadSafeRefCounted).
     12
     13        Address the issue by making sure StorageManager::suspend() calls its completion handler on the
     14        main thread. Also get rid of TaskCounter and use a WTF::CallbackAggregator instead.
     15
     16        * NetworkProcess/NetworkProcess.cpp:
     17        (WebKit::NetworkProcess::actualPrepareToSuspend):
     18        (WebKit::TaskCounter::TaskCounter): Deleted.
     19        (WebKit::TaskCounter::~TaskCounter): Deleted.
     20        * NetworkProcess/WebStorage/StorageManager.cpp:
     21        (WebKit::StorageManager::suspend):
     22
    1232019-07-03  Youenn Fablet  <youenn@apple.com>
    224
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp

    r247072 r247094  
    20302030}
    20312031
    2032 // FIXME: We can remove this one by adapting RefCounter.
    2033 class TaskCounter : public RefCounted<TaskCounter> {
    2034 public:
    2035     explicit TaskCounter(Function<void()>&& callback) : m_callback(WTFMove(callback)) { }
    2036     ~TaskCounter() { m_callback(); };
    2037 
    2038 private:
    2039     Function<void()> m_callback;
    2040 };
    2041 
    20422032void NetworkProcess::actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shouldAcknowledgeWhenReadyToSuspend)
    20432033{
     
    20482038    lowMemoryHandler(Critical::Yes);
    20492039
    2050     RefPtr<TaskCounter> delayedTaskCounter;
     2040    RefPtr<CallbackAggregator> callbackAggregator;
    20512041    if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) {
    2052         delayedTaskCounter = adoptRef(new TaskCounter([this] {
     2042        callbackAggregator = CallbackAggregator::create([this] {
    20532043            RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::notifyProcessReadyToSuspend() Sending ProcessReadyToSuspend IPC message", this);
    20542044            if (parentProcessConnection())
    20552045                parentProcessConnection()->send(Messages::NetworkProcessProxy::ProcessReadyToSuspend(), 0);
    2056         }));
    2057     }
    2058 
    2059     platformPrepareToSuspend([delayedTaskCounter] { });
    2060     platformSyncAllCookies([delayedTaskCounter] { });
     2046        });
     2047    }
     2048
     2049    platformPrepareToSuspend([callbackAggregator] { });
     2050    platformSyncAllCookies([callbackAggregator] { });
    20612051
    20622052    for (auto& connection : m_webProcessConnections)
    2063         connection->cleanupForSuspension([delayedTaskCounter] { });
     2053        connection->cleanupForSuspension([callbackAggregator] { });
    20642054
    20652055#if ENABLE(SERVICE_WORKER)
    20662056    for (auto& server : m_swServers.values()) {
    20672057        ASSERT(m_swServers.get(server->sessionID()) == server.get());
    2068         server->startSuspension([delayedTaskCounter] { });
     2058        server->startSuspension([callbackAggregator] { });
    20692059    }
    20702060#endif
    20712061
    20722062    for (auto& session : m_networkSessions)
    2073         session.value->storageManager().suspend([delayedTaskCounter] { });
     2063        session.value->storageManager().suspend([callbackAggregator] { });
    20742064}
    20752065
  • trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp

    r247092 r247094  
    937937        ASSERT(m_state != State::Suspended);
    938938
    939         completionHandler();
    940 
    941         if (m_state != State::WillSuspend)
     939        if (m_state != State::WillSuspend) {
     940            RunLoop::main().dispatch(WTFMove(completionHandler));
    942941            return;
     942        }
     943
    943944        m_state = State::Suspended;
     945        RunLoop::main().dispatch(WTFMove(completionHandler));
     946       
    944947        while (m_state == State::Suspended)
    945948            m_stateChangeCondition.wait(m_stateLock);
Note: See TracChangeset for help on using the changeset viewer.