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

Changeset 293274 in webkit


Ignore:
Timestamp:
Apr 22, 2022, 5:44:22 PM (4 years ago)
Author:
Russell Epstein
Message:

Revert "Apply patch. rdar://problem/88904160"

This reverts commit r293259.

Location:
branches/safari-613.2.7.0-branch/Source/WebKit
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-613.2.7.0-branch/Source/WebKit/ChangeLog

    r293259 r293274  
    1 2022-04-22  Russell Epstein  <repstein@apple.com>
    2 
    3         Apply patch. rdar://problem/88904160
    4 
    5     2022-04-22  Kimmo Kinnunen  <kkinnunen@apple.com>
    6 
    7             Multiple concurrency violations in LibWebRTCCodecsProxy
    8             https://bugs.webkit.org/show_bug.cgi?id=236767
    9             <rdar://88904160>
    10 
    11             Reviewed by Antti Koivisto.
    12 
    13             - ThreadMessageReceivers should not add IPC listeners in constructors,
    14             as the delivery starts right away and uses the unconstructed virtual pointer.
    15             - The work queue functions should not use GPUConnectionToWebProcess, as that is
    16             main thread object.
    17             - Locked m_encoders, m_decoders are sometimes accessed without lock.
    18 
    19             Instead:
    20             - Add the IPC listeners in initialize function.
    21             - Remove the IPC listeners when GPUConnectionToWebProcess disconnects.
    22             - Store the thread-safe conection, video frame object heap, process identity
    23             objects as member variables.
    24             - Do not lock m_encoders, m_decoders. If they are work queue instances,
    25             just access them in the work queue functions. Add thread requirements
    26             to the variables so that the compiler checks the access.
    27             - Use IPC testing assertions when skipping incorrect messages.
    28             - Use separate atomic counter (bool) to check if allowsExitUnderMemoryPressure.
    29 
    30             No new tests, tested with existing tests and ASAN.
    31 
    32             * GPUProcess/GPUConnectionToWebProcess.cpp:
    33             (WebKit::GPUConnectionToWebProcess::~GPUConnectionToWebProcess):
    34             (WebKit::GPUConnectionToWebProcess::didClose):
    35             * GPUProcess/GPUConnectionToWebProcess.h:
    36             * GPUProcess/webrtc/LibWebRTCCodecsProxy.h:
    37             * GPUProcess/webrtc/LibWebRTCCodecsProxy.mm:
    38             (WebKit::LibWebRTCCodecsProxy::create):
    39             (WebKit::LibWebRTCCodecsProxy::LibWebRTCCodecsProxy):
    40             (WebKit::LibWebRTCCodecsProxy::stopListeningForIPC):
    41             (WebKit::LibWebRTCCodecsProxy::initialize):
    42             (WebKit::LibWebRTCCodecsProxy::dispatchToThread):
    43             (WebKit::LibWebRTCCodecsProxy::createDecoderCallback):
    44             (WebKit::LibWebRTCCodecsProxy::createH264Decoder):
    45             (WebKit::LibWebRTCCodecsProxy::createH265Decoder):
    46             (WebKit::LibWebRTCCodecsProxy::createVP9Decoder):
    47             (WebKit::LibWebRTCCodecsProxy::releaseDecoder):
    48             (WebKit::LibWebRTCCodecsProxy::createEncoder):
    49             (WebKit::LibWebRTCCodecsProxy::releaseEncoder):
    50             (WebKit::LibWebRTCCodecsProxy::initializeEncoder):
    51             (WebKit::LibWebRTCCodecsProxy::findEncoder):
    52             (WebKit::LibWebRTCCodecsProxy::encodeFrame):
    53             (WebKit::LibWebRTCCodecsProxy::setEncodeRates):
    54             (WebKit::LibWebRTCCodecsProxy::setSharedVideoFrameSemaphore):
    55             (WebKit::LibWebRTCCodecsProxy::setSharedVideoFrameMemory):
    56             (WebKit::LibWebRTCCodecsProxy::allowsExitUnderMemoryPressure const):
    57 
    5812022-04-22  Russell Epstein  <repstein@apple.com>
    592
     
    4032440267
    4032540268        CMake is expanding templates in the pkg-config files that are not supposed to be expanded.
    40326         Let's switch back to using @SVN_REVISION@ instead of ${SVN_REVISION} as the template
     40269        Oops! Let's switch back to using @SVN_REVISION@ instead of ${SVN_REVISION} as the template
    4032740270        for inserting the SVN revision into the pkg-config file, so we can tell CMake to leave the
    4032840271        ${} variables alone.
  • branches/safari-613.2.7.0-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp

    r293259 r293274  
    275275    m_sampleBufferDisplayLayerManager->close();
    276276#endif
     277#if PLATFORM(COCOA) && USE(LIBWEBRTC)
     278    m_libWebRTCCodecsProxy->close();
     279#endif
    277280
    278281    --gObjectCountForTesting;
     
    307310    });
    308311#endif
    309 #if PLATFORM(COCOA) && USE(LIBWEBRTC)
    310     m_libWebRTCCodecsProxy = nullptr;
    311 #endif
     312
    312313    gpuProcess().connectionToWebProcessClosed(connection);
    313314    gpuProcess().removeGPUConnectionToWebProcess(*this); // May destroy |this|.
  • branches/safari-613.2.7.0-branch/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h

    r293259 r293274  
    286286    PAL::SessionID m_sessionID;
    287287#if PLATFORM(COCOA) && USE(LIBWEBRTC)
    288     IPC::ScopedActiveMessageReceiveQueue<LibWebRTCCodecsProxy> m_libWebRTCCodecsProxy;
     288    Ref<LibWebRTCCodecsProxy> m_libWebRTCCodecsProxy;
    289289#endif
    290290#if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
  • branches/safari-613.2.7.0-branch/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.h

    r293259 r293274  
    3232#include "RTCDecoderIdentifier.h"
    3333#include "RTCEncoderIdentifier.h"
    34 #include <atomic>
    35 #include <wtf/ThreadAssertions.h>
     34#include <wtf/Lock.h>
    3635
    3736namespace IPC {
     
    5352class GPUConnectionToWebProcess;
    5453
    55 class LibWebRTCCodecsProxy final : public IPC::Connection::ThreadMessageReceiverRefCounted {
     54class LibWebRTCCodecsProxy : public IPC::Connection::ThreadMessageReceiverRefCounted {
    5655    WTF_MAKE_FAST_ALLOCATED;
    5756public:
    58     static Ref<LibWebRTCCodecsProxy> create(GPUConnectionToWebProcess&);
     57    static Ref<LibWebRTCCodecsProxy> create(GPUConnectionToWebProcess& process) { return adoptRef(*new LibWebRTCCodecsProxy(process)); }
    5958    ~LibWebRTCCodecsProxy();
    60     void stopListeningForIPC(Ref<LibWebRTCCodecsProxy>&& refFromConnection);
     59
     60    void close();
     61
    6162    bool allowsExitUnderMemoryPressure() const;
    6263
    6364private:
    6465    explicit LibWebRTCCodecsProxy(GPUConnectionToWebProcess&);
    65     void initialize();
    66     auto createDecoderCallback(RTCDecoderIdentifier, bool useRemoteFrames);
    67     WorkQueue& workQueue() const { return m_queue; }
    6866
    6967    // IPC::Connection::ThreadMessageReceiver
     
    8886    CFDictionaryRef ioSurfacePixelBufferCreationOptions(IOSurfaceRef);
    8987
     88    GPUConnectionToWebProcess& m_gpuConnectionToWebProcess;
     89
     90    mutable Lock m_lock;
     91    HashMap<RTCDecoderIdentifier, webrtc::LocalDecoder> m_decoders WTF_GUARDED_BY_LOCK(m_lock); // Only modified on the libWebRTCCodecsQueue but may get accessed from the main thread.
     92    HashMap<RTCEncoderIdentifier, webrtc::LocalEncoder> m_encoders WTF_GUARDED_BY_LOCK(m_lock); // Only modified on the libWebRTCCodecsQueue but may get accessed from the main thread.
    9093
    9194    Ref<WorkQueue> m_queue;
    92     HashMap<RTCDecoderIdentifier, webrtc::LocalDecoder> m_decoders WTF_GUARDED_BY_LOCK(workQueue());
    93     HashMap<RTCEncoderIdentifier, webrtc::LocalEncoder> m_encoders WTF_GUARDED_BY_LOCK(workQueue());
    94     std::atomic<bool> m_hasEncodersOrDecoders { false };
    9595};
    9696
  • branches/safari-613.2.7.0-branch/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.mm

    r293259 r293274  
    3131#import "GPUConnectionToWebProcess.h"
    3232#import "GPUProcess.h"
    33 #import "IPCTester.h"
    3433#import "LibWebRTCCodecsMessages.h"
    3534#import "LibWebRTCCodecsProxyMessages.h"
     
    4544namespace WebKit {
    4645
    47 Ref<LibWebRTCCodecsProxy> LibWebRTCCodecsProxy::create(GPUConnectionToWebProcess& webProcessConnection)
    48 {
    49     auto instance = adoptRef(*new LibWebRTCCodecsProxy(webProcessConnection));
    50     instance->initialize();
    51     return instance;
    52 }
    53 
    54 LibWebRTCCodecsProxy::LibWebRTCCodecsProxy(GPUConnectionToWebProcess& webProcessConnection)
    55     : m_connection(webProcessConnection.connection())
    56     , m_queue(webProcessConnection.gpuProcess().libWebRTCCodecsQueue())
    57     , m_resourceOwner(webProcessConnection.webProcessIdentity())
    58 {
    59 }
    60 
    61 LibWebRTCCodecsProxy::~LibWebRTCCodecsProxy() = default;
    62 
    63 void LibWebRTCCodecsProxy::stopListeningForIPC(Ref<LibWebRTCCodecsProxy>&& refFromConnection)
    64 {
    65     m_connection->removeThreadMessageReceiver(Messages::LibWebRTCCodecsProxy::messageReceiverName());
    66 
    67     dispatchToThread([this, protectedThis = WTFMove(refFromConnection)] {
    68         assertIsCurrent(workQueue());
     46LibWebRTCCodecsProxy::LibWebRTCCodecsProxy(GPUConnectionToWebProcess& connection)
     47    : m_gpuConnectionToWebProcess(connection)
     48    , m_queue(connection.gpuProcess().libWebRTCCodecsQueue())
     49{
     50    m_gpuConnectionToWebProcess.connection().addThreadMessageReceiver(Messages::LibWebRTCCodecsProxy::messageReceiverName(), this);
     51}
     52
     53LibWebRTCCodecsProxy::~LibWebRTCCodecsProxy()
     54{
     55}
     56
     57void LibWebRTCCodecsProxy::dispatchToThread(Function<void()>&& function)
     58{
     59    m_queue->dispatch(WTFMove(function));
     60}
     61
     62void LibWebRTCCodecsProxy::close()
     63{
     64    m_gpuConnectionToWebProcess.connection().removeThreadMessageReceiver(Messages::LibWebRTCCodecsProxy::messageReceiverName());
     65
     66    dispatchToThread([this, protectedThis = Ref { *this }] {
     67        Locker locker { m_lock };
    6968        auto decoders = WTFMove(m_decoders);
    7069        for (auto decoder : decoders.values())
     
    7675}
    7776
    78 void LibWebRTCCodecsProxy::initialize()
    79 {
    80     m_connection->addThreadMessageReceiver(Messages::LibWebRTCCodecsProxy::messageReceiverName(), this);
    81 }
    82 
    83 void LibWebRTCCodecsProxy::dispatchToThread(Function<void()>&& function)
    84 {
    85     m_queue->dispatch(WTFMove(function));
    86 }
    87 
    88 auto LibWebRTCCodecsProxy::createDecoderCallback(RTCDecoderIdentifier identifier)
    89 {
    90     return [identifier, connection = m_connection, resourceOwner = m_resourceOwner] (CVPixelBufferRef pixelBuffer, uint32_t timeStampNs, uint32_t timeStamp) mutable {
    91         auto sample = WebCore::MediaSampleAVFObjC::createImageSample(pixelBuffer, WebCore::MediaSample::VideoRotation::None, false, MediaTime(timeStampNs, 1), { });
    92         if (!sample)
    93             return;
    94         if (resourceOwner)
    95             sample->setOwnershipIdentity(resourceOwner);
    96         connection->send(Messages::LibWebRTCCodecs::CompletedDecoding { identifier, timeStamp, *sample }, 0);
     77static Function<void(CVPixelBufferRef pixelBuffer, uint32_t timeStampNs, uint32_t timeStamp)> createDecoderCallback(RTCDecoderIdentifier identifier, GPUConnectionToWebProcess& gpuConnectionToWebProcess)
     78{
     79    return [connection = Ref { gpuConnectionToWebProcess.connection() }, resourceOwner = gpuConnectionToWebProcess.webProcessIdentity(), identifier] (CVPixelBufferRef pixelBuffer, uint32_t timeStampNs, uint32_t timeStamp) {
     80        if (auto sample = WebCore::RemoteVideoSample::create(pixelBuffer, MediaTime(timeStampNs, 1))) {
     81            if (resourceOwner)
     82                sample->setOwnershipIdentity(resourceOwner);
     83            connection->send(Messages::LibWebRTCCodecs::CompletedDecoding { identifier, timeStamp, *sample }, 0);
     84        }
    9785    };
    9886}
     
    10088void LibWebRTCCodecsProxy::createH264Decoder(RTCDecoderIdentifier identifier)
    10189{
    102     assertIsCurrent(workQueue());
    103     auto result = m_decoders.add(identifier, webrtc::createLocalH264Decoder(makeBlockPtr(createDecoderCallback(identifier)).get()));
    104     ASSERT_UNUSED(result, result.isNewEntry || isTestingIPC());
    105     m_hasEncodersOrDecoders = true;
     90    ASSERT(!isMainRunLoop());
     91    Locker locker { m_lock };
     92    ASSERT(!m_decoders.contains(identifier));
     93    m_decoders.add(identifier, webrtc::createLocalH264Decoder(makeBlockPtr(createDecoderCallback(identifier, m_gpuConnectionToWebProcess)).get()));
    10694}
    10795
    10896void LibWebRTCCodecsProxy::createH265Decoder(RTCDecoderIdentifier identifier)
    10997{
    110     assertIsCurrent(workQueue());
    111     auto result = m_decoders.add(identifier, webrtc::createLocalH265Decoder(makeBlockPtr(createDecoderCallback(identifier)).get()));
    112     ASSERT_UNUSED(result, result.isNewEntry || isTestingIPC());
    113     m_hasEncodersOrDecoders = true;
     98    ASSERT(!isMainRunLoop());
     99    Locker locker { m_lock };
     100    ASSERT(!m_decoders.contains(identifier));
     101    m_decoders.add(identifier, webrtc::createLocalH265Decoder(makeBlockPtr(createDecoderCallback(identifier, m_gpuConnectionToWebProcess)).get()));
    114102}
    115103
    116104void LibWebRTCCodecsProxy::createVP9Decoder(RTCDecoderIdentifier identifier)
    117105{
    118     assertIsCurrent(workQueue());
    119     auto result = m_decoders.add(identifier, webrtc::createLocalVP9Decoder(makeBlockPtr(createDecoderCallback(identifier)).get()));
    120     ASSERT_UNUSED(result, result.isNewEntry || isTestingIPC());
    121     m_hasEncodersOrDecoders = true;
     106    ASSERT(!isMainRunLoop());
     107    Locker locker { m_lock };
     108    ASSERT(!m_decoders.contains(identifier));
     109    m_decoders.add(identifier, webrtc::createLocalVP9Decoder(makeBlockPtr(createDecoderCallback(identifier, m_gpuConnectionToWebProcess)).get()));
    122110}
    123111
    124112void LibWebRTCCodecsProxy::releaseDecoder(RTCDecoderIdentifier identifier)
    125113{
    126     assertIsCurrent(workQueue());
    127     auto decoder = m_decoders.take(identifier);
    128     if (!decoder) {
    129         ASSERT_IS_TESTING_IPC();
    130         return;
    131     }
    132     webrtc::releaseLocalDecoder(decoder);
    133     m_hasEncodersOrDecoders = !m_encoders.isEmpty() || !m_decoders.isEmpty();}
    134 }
    135 
    136 void LibWebRTCCodecsProxy::decodeFrame(RTCDecoderIdentifier identifier, uint32_t timeStamp, const IPC::DataReference& data)
    137 {
    138     assertIsCurrent(workQueue());
     114    ASSERT(!isMainRunLoop());
     115    Locker locker { m_lock };
     116    ASSERT(m_decoders.contains(identifier));
     117    if (auto decoder = m_decoders.take(identifier))
     118        webrtc::releaseLocalDecoder(decoder);
     119}
     120
     121// For performance reasons, this function accesses m_decoders without locking. This is safe because this function runs on the libWebRTCCodecsQueue
     122// and m_decoders only get modified on this queue.
     123void LibWebRTCCodecsProxy::decodeFrame(RTCDecoderIdentifier identifier, uint32_t timeStamp, const IPC::DataReference& data) WTF_IGNORES_THREAD_SAFETY_ANALYSIS
     124{
     125    ASSERT(!isMainRunLoop());
     126    ASSERT(m_decoders.contains(identifier));
    139127    auto decoder = m_decoders.get(identifier);
    140     if (!decoder) {
    141         ASSERT_IS_TESTING_IPC();
    142         return;
    143     }
     128    if (!decoder)
     129        return;
     130
    144131    if (webrtc::decodeFrame(decoder, timeStamp, data.data(), data.size()))
    145         m_connection->send(Messages::LibWebRTCCodecs::FailedDecoding { identifier }, 0);
    146 }
    147 
    148 void LibWebRTCCodecsProxy::setFrameSize(RTCDecoderIdentifier identifier, uint16_t width, uint16_t height)
    149 {
    150     assertIsCurrent(workQueue());
     132        m_gpuConnectionToWebProcess.connection().send(Messages::LibWebRTCCodecs::FailedDecoding { identifier }, 0);
     133}
     134
     135// For performance reasons, this function accesses m_decoders without locking. This is safe because this function runs on the libWebRTCCodecsQueue
     136// and m_decoders only get modified on this queue.
     137void LibWebRTCCodecsProxy::setFrameSize(RTCDecoderIdentifier identifier, uint16_t width, uint16_t height) WTF_IGNORES_THREAD_SAFETY_ANALYSIS
     138{
     139    ASSERT(!isMainRunLoop());
     140    ASSERT(m_decoders.contains(identifier));
    151141    auto decoder = m_decoders.get(identifier);
    152     if (!decoder) {
    153         ASSERT_IS_TESTING_IPC();
    154         return;
    155     }
     142    if (!decoder)
     143        return;
     144
    156145    webrtc::setDecoderFrameSize(decoder, width, height);
    157146}
     
    159148void LibWebRTCCodecsProxy::createEncoder(RTCEncoderIdentifier identifier, const String& formatName, const Vector<std::pair<String, String>>& parameters, bool useLowLatency)
    160149{
    161     assertIsCurrent(workQueue());
     150    ASSERT(!isMainRunLoop());
     151    Locker locker { m_lock };
     152    ASSERT(!m_encoders.contains(identifier));
     153
    162154    std::map<std::string, std::string> rtcParameters;
    163155    for (auto& parameter : parameters)
    164156        rtcParameters.emplace(parameter.first.utf8().data(), parameter.second.utf8().data());
    165157
    166     auto* encoder = webrtc::createLocalEncoder(webrtc::SdpVideoFormat { formatName.utf8().data(), rtcParameters }, makeBlockPtr([connection = m_connection, identifier](const uint8_t* buffer, size_t size, const webrtc::WebKitEncodedFrameInfo& info) {
     158    auto* encoder = webrtc::createLocalEncoder(webrtc::SdpVideoFormat { formatName.utf8().data(), rtcParameters }, makeBlockPtr([connection = Ref { m_gpuConnectionToWebProcess.connection() }, identifier](const uint8_t* buffer, size_t size, const webrtc::WebKitEncodedFrameInfo& info) {
    167159        connection->send(Messages::LibWebRTCCodecs::CompletedEncoding { identifier, IPC::DataReference { buffer, size }, info }, 0);
    168160    }).get());
    169161    webrtc::setLocalEncoderLowLatency(encoder, useLowLatency);
    170     auto result = m_encoders.add(identifier, Encoder { encoder, nullptr });
    171     ASSERT_UNUSED(result, result.isNewEntry || isTestingIPC());
    172     m_hasEncodersOrDecoders = true;
     162    m_encoders.add(identifier, encoder);
    173163}
    174164
    175165void LibWebRTCCodecsProxy::releaseEncoder(RTCEncoderIdentifier identifier)
    176166{
    177     assertIsCurrent(workQueue());
    178     auto encoder = m_encoders.take(identifier);
    179     if (!encoder.webrtcEncoder) {
    180         ASSERT_IS_TESTING_IPC();
    181         return;
    182     }
    183     webrtc::releaseLocalEncoder(encoder.webrtcEncoder);
    184     m_hasEncodersOrDecoders = !m_encoders.isEmpty() || !m_decoders.isEmpty();
    185 }
    186 
    187 void LibWebRTCCodecsProxy::initializeEncoder(RTCEncoderIdentifier identifier, uint16_t width, uint16_t height, unsigned startBitrate, unsigned maxBitrate, unsigned minBitrate, uint32_t maxFramerate)
    188 {
    189     assertIsCurrent(workQueue());
    190     auto* encoder = findEncoder(identifier);
    191     if (!encoder) {
    192         ASSERT_IS_TESTING_IPC();
    193         return;
    194     }
    195     webrtc::initializeLocalEncoder(encoder->webrtcEncoder, width, height, startBitrate, maxBitrate, minBitrate, maxFramerate);
     167    ASSERT(!isMainRunLoop());
     168    Locker locker { m_lock };
     169    ASSERT(m_encoders.contains(identifier));
     170    if (auto encoder = m_encoders.take(identifier))
     171        webrtc::releaseLocalEncoder(encoder);
     172}
     173
     174// For performance reasons, this function accesses m_encoders without locking. This is safe because this function runs on the libWebRTCCodecsQueue
     175// and m_encoders only get modified on this queue.
     176void LibWebRTCCodecsProxy::initializeEncoder(RTCEncoderIdentifier identifier, uint16_t width, uint16_t height, unsigned startBitrate, unsigned maxBitrate, unsigned minBitrate, uint32_t maxFramerate) WTF_IGNORES_THREAD_SAFETY_ANALYSIS
     177{
     178    ASSERT(!isMainRunLoop());
     179    ASSERT(m_encoders.contains(identifier));
     180    auto encoder = m_encoders.get(identifier);
     181    if (!encoder)
     182        return;
     183
     184    webrtc::initializeLocalEncoder(encoder, width, height, startBitrate, maxBitrate, minBitrate, maxFramerate);
    196185}
    197186
     
    212201}
    213202
    214 void LibWebRTCCodecsProxy::encodeFrame(RTCEncoderIdentifier identifier, WebCore::RemoteVideoSample&& sample, uint32_t timeStamp, bool shouldEncodeAsKeyFrame)
    215 {
    216     assertIsCurrent(workQueue());
     203// For performance reasons, this function accesses m_encoders without locking. This is safe because this function runs on the libWebRTCCodecsQueue
     204// and m_encoders only get modified on this queue.
     205void LibWebRTCCodecsProxy::encodeFrame(RTCEncoderIdentifier identifier, WebCore::RemoteVideoSample&& sample, uint32_t timeStamp, bool shouldEncodeAsKeyFrame) WTF_IGNORES_THREAD_SAFETY_ANALYSIS
     206{
     207    ASSERT(!isMainRunLoop());
    217208    ASSERT(m_encoders.contains(identifier));
    218209    auto encoder = m_encoders.get(identifier);
     
    230221}
    231222
    232 void LibWebRTCCodecsProxy::setEncodeRates(RTCEncoderIdentifier identifier, uint32_t bitRate, uint32_t frameRate)
    233 {
    234     assertIsCurrent(workQueue());
     223// For performance reasons, this function accesses m_encoders without locking. This is safe because this function runs on the libWebRTCCodecsQueue
     224// and m_encoders only get modified on this queue.
     225void LibWebRTCCodecsProxy::setEncodeRates(RTCEncoderIdentifier identifier, uint32_t bitRate, uint32_t frameRate) WTF_IGNORES_THREAD_SAFETY_ANALYSIS
     226{
     227    ASSERT(!isMainRunLoop());
    235228    auto encoder = m_encoders.get(identifier);
    236229    if (!encoder)
     
    242235bool LibWebRTCCodecsProxy::allowsExitUnderMemoryPressure() const
    243236{
    244     assertIsMainRunLoop();
    245     return !m_hasEncodersOrDecoders;
     237    ASSERT(isMainRunLoop());
     238    Locker locker { m_lock };
     239    return m_encoders.isEmpty() && m_decoders.isEmpty();
    246240}
    247241
Note: See TracChangeset for help on using the changeset viewer.