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

Changeset 278655 in webkit


Ignore:
Timestamp:
Jun 9, 2021, 3:58:36 AM (5 years ago)
Author:
aboya@igalia.com
Message:

[WTF][GStreamer] Add RAII lockers for 3rd party locks
https://bugs.webkit.org/show_bug.cgi?id=225650

Reviewed by Xabier Rodriguez-Calvar.

Source/WebCore:

This patch introduces RAII locker classes that wrap GST_OBJECT_LOCK
and GST_PAD_STREAM_LOCK to match the style, safety and convenience of
locks from WTF.

This patch also changes all usages of GStreamer locks in the WebKit
codebase to use these new lockers.

This patch introduces no behavior changes.

  • platform/graphics/gstreamer/GStreamerCommon.h:

(gstObjectLock):
(gstObjectUnlock):
(gstPadStreamLock):
(gstPadStreamUnlock):
(holdGstObjectLock):
(holdGstPadStreamLock):

  • platform/graphics/gstreamer/TextCombinerPadGStreamer.cpp:

(webkitTextCombinerPadGetProperty):
(webkitTextCombinerPadSetProperty):

  • platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp:

(webKitMediaSrcWaitForPadLinkedOrFlush):
(webKitMediaSrcLoop):
(webKitMediaSrcStreamFlush):
(webKitMediaSrcGetUri):
(webKitMediaSrcSetUri):

Source/WTF:

This patch introduces WTF::ExternalLocker, which allows to lock 3rd
party mutexes in a RAII fashion, very similar to WTF::Locker.

This is used also in WebCore to provide RAII lockers for GStreamer.

  • wtf/Locker.h:

(WTF::unlockFunction):

Location:
trunk/Source
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r278649 r278655  
     12021-06-09  Alicia Boya García  <aboya@igalia.com>
     2
     3        [WTF][GStreamer] Add RAII lockers for 3rd party locks
     4        https://bugs.webkit.org/show_bug.cgi?id=225650
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        This patch introduces WTF::ExternalLocker, which allows to lock 3rd
     9        party mutexes in a RAII fashion, very similar to WTF::Locker.
     10
     11        This is used also in WebCore to provide RAII lockers for GStreamer.
     12
     13        * wtf/Locker.h:
     14        (WTF::unlockFunction):
     15
    1162021-06-08  Alex Christensen  <achristensen@webkit.org>
    217
  • trunk/Source/WTF/wtf/Locker.h

    r277932 r278655  
    161161};
    162162
     163// This is a close replica of Locker, but for generic lock/unlock functions.
     164template<typename T, void (lockFunction)(T*), void (*unlockFunction)(T*)>
     165class ExternalLocker: public WTF::AbstractLocker {
     166public:
     167    explicit ExternalLocker(T* lockable)
     168        : m_lockable(lockable)
     169    {
     170        ASSERT(lockable);
     171        lock();
     172    }
     173
     174    ~ExternalLocker()
     175    {
     176        unlock();
     177    }
     178
     179    T* lockable() { return m_lockable; }
     180
     181    explicit operator bool() const { return !!m_lockable; }
     182
     183    void unlockEarly()
     184    {
     185        unlock();
     186        m_lockable = nullptr;
     187    }
     188
     189    ExternalLocker(ExternalLocker&& other)
     190        : m_lockable(other.m_lockable)
     191    {
     192        ASSERT(&other != this);
     193        other.m_lockable = nullptr;
     194    }
     195
     196    ExternalLocker& operator=(ExternalLocker&& other)
     197    {
     198        ASSERT(&other != this);
     199        m_lockable = other.m_lockable;
     200        other.m_lockable = nullptr;
     201        return *this;
     202    }
     203
     204private:
     205    template<typename>
     206    friend class DropLockForScope;
     207
     208    void unlock()
     209    {
     210        if (m_lockable)
     211            unlockFunction(m_lockable);
     212    }
     213
     214    void lock()
     215    {
     216        if (m_lockable)
     217            lockFunction(m_lockable);
     218    }
     219
     220    T* m_lockable;
     221};
     222
    163223}
    164224
     
    169229using WTF::NoLockingNecessary;
    170230using WTF::DropLockForScope;
     231using WTF::ExternalLocker;
  • trunk/Source/WebCore/ChangeLog

    r278651 r278655  
     12021-06-09  Alicia Boya García  <aboya@igalia.com>
     2
     3        [WTF][GStreamer] Add RAII lockers for 3rd party locks
     4        https://bugs.webkit.org/show_bug.cgi?id=225650
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        This patch introduces RAII locker classes that wrap GST_OBJECT_LOCK
     9        and GST_PAD_STREAM_LOCK to match the style, safety and convenience of
     10        locks from WTF.
     11
     12        This patch also changes all usages of GStreamer locks in the WebKit
     13        codebase to use these new lockers.
     14
     15        This patch introduces no behavior changes.
     16
     17        * platform/graphics/gstreamer/GStreamerCommon.h:
     18        (gstObjectLock):
     19        (gstObjectUnlock):
     20        (gstPadStreamLock):
     21        (gstPadStreamUnlock):
     22        (holdGstObjectLock):
     23        (holdGstPadStreamLock):
     24        * platform/graphics/gstreamer/TextCombinerPadGStreamer.cpp:
     25        (webkitTextCombinerPadGetProperty):
     26        (webkitTextCombinerPadSetProperty):
     27        * platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp:
     28        (webKitMediaSrcWaitForPadLinkedOrFlush):
     29        (webKitMediaSrcLoop):
     30        (webKitMediaSrcStreamFlush):
     31        (webKitMediaSrcGetUri):
     32        (webKitMediaSrcSetUri):
     33
    1342021-06-09  Chris Dumez  <cdumez@apple.com>
    235
  • trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h

    r278253 r278655  
    321321#endif
    322322
     323// We can't pass macros as template parameters, so we need to wrap them in inline functions.
     324inline void gstObjectLock(void* object) { GST_OBJECT_LOCK(object); }
     325inline void gstObjectUnlock(void* object) { GST_OBJECT_UNLOCK(object); }
     326inline void gstPadStreamLock(GstPad* pad) { GST_PAD_STREAM_LOCK(pad); }
     327inline void gstPadStreamUnlock(GstPad* pad) { GST_PAD_STREAM_UNLOCK(pad); }
     328
     329using GstObjectLocker = ExternalLocker<void, gstObjectLock, gstObjectUnlock>;
     330using GstPadStreamLocker = ExternalLocker<GstPad, gstPadStreamLock, gstPadStreamUnlock>;
     331
    323332#endif // USE(GSTREAMER)
  • trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerPadGStreamer.cpp

    r275816 r278655  
    6363        ASSERT(tags);
    6464
    65         GST_OBJECT_LOCK(pad);
    66         if (!combinerPad->priv->tags)
    67             combinerPad->priv->tags = adoptGRef(gst_tag_list_copy(tags));
    68         else
    69             gst_tag_list_insert(combinerPad->priv->tags.get(), tags, GST_TAG_MERGE_REPLACE);
    70         GST_OBJECT_UNLOCK(pad);
     65        {
     66            auto locker = GstObjectLocker(pad);
     67            if (!combinerPad->priv->tags)
     68                combinerPad->priv->tags = adoptGRef(gst_tag_list_copy(tags));
     69            else
     70                gst_tag_list_insert(combinerPad->priv->tags.get(), tags, GST_TAG_MERGE_REPLACE);
     71        }
    7172
    7273        g_object_notify_by_pspec(G_OBJECT(pad), sObjProperties[PROP_PAD_TAGS]);
     
    8384    auto* pad = WEBKIT_TEXT_COMBINER_PAD(object);
    8485    switch (propertyId) {
    85     case PROP_PAD_TAGS:
    86         GST_OBJECT_LOCK(object);
     86    case PROP_PAD_TAGS: {
     87        auto locker = GstObjectLocker(object);
    8788        if (pad->priv->tags)
    8889            g_value_take_boxed(value, gst_tag_list_copy(pad->priv->tags.get()));
    89         GST_OBJECT_UNLOCK(object);
    9090        break;
    91     case PROP_INNER_COMBINER_PAD:
    92         GST_OBJECT_LOCK(object);
     91    }
     92    case PROP_INNER_COMBINER_PAD: {
     93        auto locker = GstObjectLocker(object);
    9394        g_value_set_object(value, pad->priv->innerCombinerPad.get());
    94         GST_OBJECT_UNLOCK(object);
    9595        break;
     96    }
    9697    default:
    9798        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
     
    104105    auto* pad = WEBKIT_TEXT_COMBINER_PAD(object);
    105106    switch (propertyId) {
    106     case PROP_INNER_COMBINER_PAD:
    107         GST_OBJECT_LOCK(object);
     107    case PROP_INNER_COMBINER_PAD: {
     108        auto locker = GstObjectLocker(object);
    108109        pad->priv->innerCombinerPad = adoptGRef(GST_PAD_CAST(g_value_get_object(value)));
    109         GST_OBJECT_UNLOCK(object);
    110110        break;
     111    }
    111112    default:
    112113        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
  • trunk/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp

    r278248 r278655  
    369369}
    370370
     371static void webKitMediaSrcWaitForPadLinkedOrFlush(GstPad* pad, DataMutexLocker<Stream::StreamingMembers>& streamingMembers)
     372{
     373    {
     374        auto locker = GstObjectLocker(pad);
     375        if (LIKELY(GST_PAD_IS_LINKED(pad)))
     376            return;
     377
     378        GST_DEBUG_OBJECT(pad, "Waiting for the pad to be linked...");
     379        g_signal_connect(pad, "linked", G_CALLBACK(webKitMediaSrcPadLinked), nullptr);
     380    }
     381
     382    assertIsHeld(streamingMembers.mutex());
     383    streamingMembers->padLinkedOrFlushedCondition.wait(streamingMembers.mutex());
     384
     385    g_signal_handlers_disconnect_by_func(pad, reinterpret_cast<void*>(webKitMediaSrcPadLinked), nullptr);
     386    GST_DEBUG_OBJECT(pad, "Finished waiting for the pad to be linked.");
     387}
     388
    371389// Called with STREAM_LOCK.
    372390static void webKitMediaSrcLoop(void* userData)
     
    383401    // Since the pad can and will be added when the element is in PLAYING state, this task can start running
    384402    // before the pad is linked. Wait for the pad to be linked to avoid buffers being lost to not-linked errors.
    385     GST_OBJECT_LOCK(pad);
    386     if (!GST_PAD_IS_LINKED(pad)) {
    387         GST_DEBUG_OBJECT(pad, "Waiting for the pad to be linked...");
    388         g_signal_connect(pad, "linked", G_CALLBACK(webKitMediaSrcPadLinked), nullptr);
    389         GST_OBJECT_UNLOCK(pad);
    390 
    391         streamingMembers->padLinkedOrFlushedCondition.wait(streamingMembers.mutex());
    392 
    393         g_signal_handlers_disconnect_by_func(pad, reinterpret_cast<void*>(webKitMediaSrcPadLinked), nullptr);
    394         GST_DEBUG_OBJECT(pad, "Finished waiting for the pad to be linked.");
    395         if (streamingMembers->isFlushing) {
    396             gst_pad_pause_task(pad);
    397             return;
    398         }
    399     } else
    400         GST_OBJECT_UNLOCK(pad);
     403    webKitMediaSrcWaitForPadLinkedOrFlush(pad, streamingMembers);
     404    if (streamingMembers->isFlushing) {
     405        gst_pad_pause_task(pad);
     406        return;
     407    }
    401408    ASSERT(gst_pad_is_linked(pad));
    402409
     
    612619        // By taking the stream lock we are waiting for the streaming thread task to stop if it hadn't yet.
    613620        GST_DEBUG_OBJECT(stream->pad.get(), "Taking the STREAM_LOCK.");
    614         GST_PAD_STREAM_LOCK(stream->pad.get());
     621        auto streamLock = GstPadStreamLocker(stream->pad.get());
    615622        {
    616623            GST_DEBUG_OBJECT(stream->pad.get(), "Taking the StreamingMembers mutex again.");
     
    628635        GST_DEBUG_OBJECT(stream->pad.get(), "Starting webKitMediaSrcLoop task and releasing the STREAM_LOCK.");
    629636        gst_pad_start_task(stream->pad.get(), webKitMediaSrcLoop, stream->pad.get(), nullptr);
    630         GST_PAD_STREAM_UNLOCK(stream->pad.get());
    631637    }
    632638}
     
    738744{
    739745    WebKitMediaSrc* source = WEBKIT_MEDIA_SRC(handler);
    740     gchar* result;
    741 
    742     GST_OBJECT_LOCK(source);
    743     result = g_strdup(source->priv->uri.get());
    744     GST_OBJECT_UNLOCK(source);
    745     return result;
     746
     747    auto locker = GstObjectLocker(source);
     748    return g_strdup(source->priv->uri.get());
    746749}
    747750
     
    755758    }
    756759
    757     GST_OBJECT_LOCK(source);
     760    auto locker = GstObjectLocker(source);
    758761    source->priv->uri = GUniquePtr<char>(g_strdup(uri));
    759     GST_OBJECT_UNLOCK(source);
    760762    return TRUE;
    761763}
Note: See TracChangeset for help on using the changeset viewer.