<html><head></head><body>Hi,<br><br>Well I don't challenge that the static cast between derived and base class is valid. But cast to/from void* still seems wrong to me as before.<br><br><div class="gmail_quote">Le 29 avril 2019 14:59:23 GMT+02:00, pierre@videolabs.io a écrit :<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<pre class="k9mail">Hi,<br><br>This patch move      the destruction of the callback to the Derived class <br>to       avoid<br>race conditions when the callback is called during the object <br>destruction.<br><br>Note that casting from the base class QVLCVariable to the Derived class <br>is safe with a<br>static_cast as QVLCVariable is a non virtual base classe of Derived. <br>hence no<br>pointer fixup is required.<br><br><br>On 2019-04-29 14:57, Pierre Lamot wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;">children object isn't built yet.<br><br>  Fixes #22187<hr> modules/gui/qt/adapters/var_common_p.hpp | 18 +++++++<br> modules/gui/qt/adapters/variables.hpp    | 60 ++++++++++++++++--------<br> 2 files changed, 59 insertions(+), 19 deletions(-)<br><br>diff --git a/modules/gui/qt/adapters/var_common_p.hpp<br>b/modules/gui/qt/adapters/var_common_p.hpp<br>index 47f8e89ca1..7ac324739b 100644<br>--- a/modules/gui/qt/adapters/var_common_p.hpp<br>+++ b/modules/gui/qt/adapters/var_common_p.hpp<br>@@ -51,6 +51,8 @@ public:<br>         assert(false);<br>     }<br><br>+    virtual void clear() {}<br>+<br>     operator bool() const {<br>         return get() != nullptr;<br>     }<br>@@ -81,6 +83,10 @@ public:<br>         m_object.reset(vout, hold);<br>     }<br><br>+    void clear() override {<br>+        m_object.reset(NULL, false);<br>+    }<br>+<br> private:<br>     static void obj_hold( vout_thread_t* obj ) { vout_Hold(obj); }<br>     static void obj_release( vout_thread_t* obj ) { vout_Release(obj); <br>}<br>@@ -108,6 +114,10 @@ public:<br>         m_object = p_intf;<br>     }<br><br>+    void clear() override {<br>+        m_object = NULL;<br>+    }<br>+<br> private:<br>     intf_thread_t* m_object;<br> };<br>@@ -133,6 +143,10 @@ public:<br>         m_object.reset(aout, hold);<br>     }<br><br>+    void clear() override {<br>+        m_object.reset(NULL, false);<br>+    }<br>+<br> private:<br>     static void obj_hold( audio_output_t* obj ) { aout_Hold(obj); }<br>     static void obj_release( audio_output_t* obj ) { <br>aout_Release(obj); }<br>@@ -157,6 +171,10 @@ public:<br>         m_object = obj;<br>     }<br><br>+    void clear() override {<br>+        m_object = NULL;<br>+    }<br>+<br> private:<br>     vlc_object_t *m_object;<br> };<br>diff --git a/modules/gui/qt/adapters/variables.hpp<br>b/modules/gui/qt/adapters/variables.hpp<br>index 710880cf23..c500187c50 100644<br>--- a/modules/gui/qt/adapters/variables.hpp<br>+++ b/modules/gui/qt/adapters/variables.hpp<br>@@ -112,39 +112,26 @@ public:<br>         , m_object(new VLCObjectHolderImpl<T>(nullptr))<br>         , m_property(property)<br>     {<br>-        resetObject<T>(object);<br>-        Derived* derived = static_cast<Derived*>(this);<br>-        connect(derived, &Derived::valueChangedInternal, this,<br>&QVLCVariable<Derived, BaseType>::onValueChangedInternal,<br>Qt::QueuedConnection);<br>     }<br><br>     virtual ~QVLCVariable()<br>     {<br>-        if (m_object->get())<br>-        {<br>-            Derived* derived = static_cast<Derived*>(this);<br>-            var_DelCallback(m_object->get(), qtu(m_property),<br>value_modified, derived);<br>-            var_Destroy(m_object->get(), qtu(m_property));<br>-        }<br>+        assert(m_object->get() == nullptr);<br>     }<br><br>     ///change the object beeing observed<br>     template<typename T><br>     void resetObject( T* object )<br>     {<br>-        Derived* derived = static_cast<Derived*>(this);<br>-        if (m_object->get()) {<br>-            var_DelCallback( m_object->get(), qtu(m_property),<br>value_modified, derived );<br>-            var_Destroy(m_object->get(), qtu(m_property));<br>-        }<br>-<br>-        m_object->reset( object, true );<br>-        if (m_object->get())<br>+        clearObject();<br>+        if (object)<br>         {<br>+            m_object->reset( object, true );<br>             int type = var_Type(object, qtu(m_property));<br>             if (type == 0) //variable not found<br>             {<br>                 msg_Warn(m_object->get(), "variable %s not found in<br>object", qtu(m_property));<br>-                m_object->reset((T*)nullptr);<br>+                m_object->clear();<br>                 return;<br>             }<br>             assert((type & VLC_VAR_CLASS) ==<br>VLCVarTypeTraits<BaseType>::var_type);<br>@@ -154,13 +141,24 @@ public:<br>                 BaseType value =<br>VLCVarTypeTraits<BaseType>::fromValue(currentvalue);<br>                 if (m_value != value)<br>                 {<br>+                    Derived* derived = static_cast<Derived*>(this);<br>                     m_value = value;<br>                     emit derived->valueChanged( m_value );<br>                 }<br>             }<br><br>             var_Create(m_object->get(), qtu(m_property),<br>VLCVarTypeTraits<BaseType>::var_type);<br>-            var_AddCallback(m_object->get(), qtu(m_property),<br>value_modified, derived);<br>+            var_AddCallback(m_object->get(), qtu(m_property),<br>value_modified, this);<br>+        }<br>+    }<br>+<br>+    void clearObject()<br>+    {<br>+        if (m_object->get())<br>+        {<br>+            var_DelCallback( m_object->get(), qtu(m_property),<br>value_modified, this );<br>+            var_Destroy(m_object->get(), qtu(m_property));<br>+            m_object->clear();<br>         }<br>     }<br><br>@@ -221,6 +219,12 @@ public:<br>     QVLCBool(T* object, QString property, QObject* parent = nullptr)<br>         : QVLCVariable<QVLCBool, bool>(object, property, parent)<br>     {<br>+        resetObject<T>(object);<br>+        connect(this, &QVLCBool::valueChangedInternal, this,<br>&QVLCBool::onValueChangedInternal, Qt::QueuedConnection);<br>+    }<br>+<br>+    ~QVLCBool() {<br>+        clearObject();<br>     }<br><br> public slots:<br>@@ -241,6 +245,12 @@ public:<br>     QVLCString(T* object, QString property, QObject* parent = nullptr)<br>         : QVLCVariable<QVLCString, QString>(object, property, parent)<br>     {<br>+        resetObject<T>(object);<br>+        connect(this, &QVLCString::valueChangedInternal, this,<br>&QVLCString::onValueChangedInternal, Qt::QueuedConnection);<br>+    }<br>+<br>+    ~QVLCString() {<br>+        clearObject();<br>     }<br><br> public slots:<br>@@ -261,6 +271,12 @@ public:<br>     QVLCFloat(T* object, QString property, QObject* parent = nullptr)<br>         : QVLCVariable<QVLCFloat, float>(object, property, parent)<br>     {<br>+        resetObject<T>(object);<br>+        connect(this, &QVLCFloat::valueChangedInternal, this,<br>&QVLCFloat::onValueChangedInternal, Qt::QueuedConnection);<br>+    }<br>+<br>+    ~QVLCFloat() {<br>+        clearObject();<br>     }<br><br> public slots:<br>@@ -282,6 +298,12 @@ public:<br>     QVLCInteger(T* object, QString property, QObject* parent = <br>nullptr)<br>         : QVLCVariable<QVLCInteger, int64_t>(object, property, parent)<br>     {<br>+        resetObject<T>(object);<br>+        connect(this, &QVLCInteger::valueChangedInternal, this,<br>&QVLCInteger::onValueChangedInternal, Qt::QueuedConnection);<br>+    }<br>+<br>+    ~QVLCInteger() {<br>+        clearObject();<br>     }<br><br> public slots:<br></blockquote><hr>vlc-devel mailing list<br>To unsubscribe or modify your subscription options:<br><a href="https://mailman.videolan.org/listinfo/vlc-devel">https://mailman.videolan.org/listinfo/vlc-devel</a></pre></blockquote></div><br>-- <br>Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.</body></html>