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

Changeset 284671 in webkit


Ignore:
Timestamp:
Oct 22, 2021, 1:18:15 AM (5 years ago)
Author:
commit-queue@webkit.org
Message:

StreamConnectionWorkQueue is not thread-safe
https://bugs.webkit.org/show_bug.cgi?id=232068

Patch by Kimmo Kinnunen <kkinnunen@apple.com> on 2021-10-22
Reviewed by Wenson Hsieh.

Make StreamConnectionWorkQueue thread-safe so that
addStreamConnection works from multiple threads.
In the future, this will be called when a new RemoteDisplayListRecorder is
added during the StreamConnectionWorkQueue message processing
invocation for RemoteRenderingBackend::createRemoteImageBuffer.

  • Platform/IPC/StreamConnectionWorkQueue.cpp:

(IPC::StreamConnectionWorkQueue::~StreamConnectionWorkQueue):
(IPC::StreamConnectionWorkQueue::dispatch):
(IPC::StreamConnectionWorkQueue::addStreamConnection):
(IPC::StreamConnectionWorkQueue::removeStreamConnection):
Change semantics so that adding and removing connections during
shutdown is ok. This is required for simpler code since
during stop we must dispatch all pending messages, but during
message code we might have unconditional start listening when
the message creates a new RemoteDisplayListRecorder.
As a consequence it's not an error to add a connection,
stop and destroy the work queue without removing it.
(IPC::StreamConnectionWorkQueue::stop):
(IPC::StreamConnectionWorkQueue::startProcessingThread):
(IPC::StreamConnectionWorkQueue::wakeUpProcessingThread): Deleted.

  • Platform/IPC/StreamConnectionWorkQueue.h:
Location:
trunk/Source/WebKit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r284662 r284671  
     12021-10-22  Kimmo Kinnunen  <kkinnunen@apple.com>
     2
     3        StreamConnectionWorkQueue is not thread-safe
     4        https://bugs.webkit.org/show_bug.cgi?id=232068
     5
     6        Reviewed by Wenson Hsieh.
     7
     8        Make StreamConnectionWorkQueue thread-safe so that
     9        addStreamConnection works from multiple threads.
     10        In the future, this will be called when a new RemoteDisplayListRecorder is
     11        added during the StreamConnectionWorkQueue message processing
     12        invocation for RemoteRenderingBackend::createRemoteImageBuffer.
     13
     14        * Platform/IPC/StreamConnectionWorkQueue.cpp:
     15        (IPC::StreamConnectionWorkQueue::~StreamConnectionWorkQueue):
     16        (IPC::StreamConnectionWorkQueue::dispatch):
     17        (IPC::StreamConnectionWorkQueue::addStreamConnection):
     18        (IPC::StreamConnectionWorkQueue::removeStreamConnection):
     19        Change semantics so that adding and removing connections during
     20        shutdown is ok. This is required for simpler code since
     21        during stop we must dispatch all pending messages, but during
     22        message code we might have unconditional start listening when
     23        the message creates a new RemoteDisplayListRecorder.
     24        As a consequence it's not an error to add a connection,
     25        stop and destroy the work queue without removing it.
     26        (IPC::StreamConnectionWorkQueue::stop):
     27        (IPC::StreamConnectionWorkQueue::startProcessingThread):
     28        (IPC::StreamConnectionWorkQueue::wakeUpProcessingThread): Deleted.
     29        * Platform/IPC/StreamConnectionWorkQueue.h:
     30
    1312021-10-21  Alex Christensen  <achristensen@webkit.org>
    232
  • trunk/Source/WebKit/Platform/IPC/StreamConnectionWorkQueue.cpp

    r284427 r284671  
    3434}
    3535
     36StreamConnectionWorkQueue::~StreamConnectionWorkQueue()
     37{
     38    // `StreamConnectionWorkQueue::stop()` should be called if anything has been dispatched or listened to.
     39    ASSERT(!m_processingThread);
     40}
     41
    3642void StreamConnectionWorkQueue::dispatch(WTF::Function<void()>&& function)
    3743{
     44    ASSERT(!m_shouldQuit); // Re-entering during shutdown not supported.
    3845    {
    3946        Locker locker { m_lock };
    4047        m_functions.append(WTFMove(function));
    41         ASSERT(!m_shouldQuit); // Re-entering during shutdown not supported.
     48        if (!m_shouldQuit && !m_processingThread) {
     49            startProcessingThread();
     50            return;
     51        }
    4252    }
    43     wakeUpProcessingThread();
     53    wakeUp();
     54}
    4455
    45 }
    4656void StreamConnectionWorkQueue::addStreamConnection(StreamServerConnectionBase& connection)
    4757{
     
    4959        Locker locker { m_lock };
    5060        m_connections.add(connection);
    51         ASSERT(!m_shouldQuit); // Re-entering during shutdown not supported.
     61        if (!m_shouldQuit && !m_processingThread) {
     62            startProcessingThread();
     63            return;
     64        }
    5265    }
    53     wakeUpProcessingThread();
     66    wakeUp();
    5467}
    5568
    5669void StreamConnectionWorkQueue::removeStreamConnection(StreamServerConnectionBase& connection)
    5770{
    58     ASSERT(m_processingThread);
    5971    {
    6072        Locker locker { m_lock };
    6173        m_connections.remove(connection);
    62         ASSERT(!m_shouldQuit); // Re-entering during shutdown not supported.
    6374    }
    64     m_wakeUpSemaphore.signal();
     75    wakeUp();
    6576}
    6677
     
    6879{
    6980    m_shouldQuit = true;
    70     if (!m_processingThread)
     81    RefPtr<Thread> processingThread;
     82    {
     83        Locker locker { m_lock };
     84        processingThread = WTFMove(m_processingThread);
     85    }
     86    if (!processingThread)
    7187        return;
    72     m_wakeUpSemaphore.signal();
    73     m_processingThread->waitForCompletion();
    74     m_processingThread = nullptr;
     88    ASSERT(Thread::current().uid() != processingThread->uid());
     89    wakeUp();
     90    processingThread->waitForCompletion();
    7591}
    7692
     
    85101}
    86102
    87 void StreamConnectionWorkQueue::wakeUpProcessingThread()
     103void StreamConnectionWorkQueue::startProcessingThread()
    88104{
    89     if (m_processingThread) {
    90         m_wakeUpSemaphore.signal();
    91         return;
    92     }
    93 
    94105    auto task = [this]() mutable {
    95106        for (;;) {
  • trunk/Source/WebKit/Platform/IPC/StreamConnectionWorkQueue.h

    r284427 r284671  
    4545
    4646    StreamConnectionWorkQueue(const char*);
    47     ~StreamConnectionWorkQueue() = default;
     47    ~StreamConnectionWorkQueue();
    4848    void addStreamConnection(StreamServerConnectionBase&);
    4949    void removeStreamConnection(StreamServerConnectionBase&);
     
    5656    Semaphore& wakeUpSemaphore();
    5757private:
    58     void wakeUpProcessingThread();
     58    void startProcessingThread() WTF_REQUIRES_LOCK(m_lock);
    5959    void processStreams();
    6060
     
    6262
    6363    Semaphore m_wakeUpSemaphore;
    64     RefPtr<Thread> m_processingThread;
    65 
    6664    std::atomic<bool> m_shouldQuit { false };
    6765
    6866    Lock m_lock;
     67    RefPtr<Thread> m_processingThread WTF_GUARDED_BY_LOCK(m_lock);
    6968    Deque<Function<void()>> m_functions WTF_GUARDED_BY_LOCK(m_lock);
    7069    HashSet<Ref<StreamServerConnectionBase>> m_connections WTF_GUARDED_BY_LOCK(m_lock);
Note: See TracChangeset for help on using the changeset viewer.