diff options
author | Mathias Hasselmann <mathias.hasselmann@kdab.com> | 2013-11-06 23:15:14 +0100 |
---|---|---|
committer | Mathias Hasselmann <mathias.hasselmann@kdab.com> | 2013-11-06 23:15:14 +0100 |
commit | 6eeba4f47a619f68b361f11a7a763657a2a4cb4f (patch) | |
tree | 2ae6089339b802177d0ca4a6daa64a3d88a51fbc | |
parent | c2bbf169b37d75a300592a1fd7cc8fb1e3a2ae8f (diff) | |
download | qtquickstreamer-6eeba4f47a619f68b361f11a7a763657a2a4cb4f.tar.gz qtquickstreamer-6eeba4f47a619f68b361f11a7a763657a2a4cb4f.tar.xz |
Properly lock bins when iterating their children
-rw-r--r-- | src/QuickStreamer/item.cpp | 82 |
1 files changed, 56 insertions, 26 deletions
diff --git a/src/QuickStreamer/item.cpp b/src/QuickStreamer/item.cpp index e757dda..53aef4b 100644 --- a/src/QuickStreamer/item.cpp +++ b/src/QuickStreamer/item.cpp @@ -12,7 +12,24 @@ namespace QQuickStreamer { namespace Private { -typedef QQmlListProperty<Item> ElementList; +class ObjectLocker +{ +public: + explicit ObjectLocker(GstObject *object) + : m_object(object) + { + Q_ASSERT(m_object); + GST_OBJECT_LOCK(m_object); + } + + ~ObjectLocker() + { + GST_OBJECT_UNLOCK(m_object); + } + +private: + GstObject *const m_object; +}; struct PropertyInfo { @@ -281,40 +298,53 @@ static void writeNothing(Item *item, const QByteArray &name, const void *) G_OBJECT_TYPE_NAME(item->target()), name.constData()); } -static void appendChild(ElementList *list, Item *child) +class ElementList : public QQmlListProperty<Item> { - auto *const parent = static_cast<Item *>(list->object); +public: + explicit ElementList(Item *item = Q_NULLPTR) + : QQmlListProperty<Item>(item, Q_NULLPTR, + &ElementList::appendChild, + &ElementList::countChildren, + &ElementList::childAt, + &ElementList::clearChildren) + { + } - gst_bin_add(GST_BIN(parent->target()), - GST_ELEMENT(child->target())); -} + static void appendChild(QQmlListProperty<Item> *list, Item *child) + { + auto *const parent = static_cast<Item *>(list->object); + gst_bin_add(GST_BIN(parent->target()), GST_ELEMENT(child->target())); + } -static int countChildren(ElementList *list) -{ - auto *const parentItem = static_cast<Item *>(list->object); - return GST_BIN_NUMCHILDREN(parentItem->target()); -} + static int countChildren(QQmlListProperty<Item> *list) + { + auto *const parent = static_cast<Item *>(list->object); + ObjectLocker locker(parent->target()); -static Item *childAt(ElementList *list, int offset) -{ - // FIXME: need to store the wrapper object somewhere - qDebug() << Q_FUNC_INFO; - return Q_NULLPTR; -} + return GST_BIN_NUMCHILDREN(parent->target()); + } -static void clearChildren(ElementList *list) -{ - auto *const parentItem = static_cast<Item *>(list->object); - auto *const elementBin = GST_BIN(parentItem->target()); + static Item *childAt(QQmlListProperty<Item> *list, int offset) + { + // FIXME: need to store the wrapper object somewhere + qDebug() << Q_FUNC_INFO; + return Q_NULLPTR; + } - while (elementBin->children) - gst_bin_remove(elementBin, GST_ELEMENT(elementBin->children->data)); -} + static void clearChildren(QQmlListProperty<Item> *list) + { + auto *const parent = static_cast<Item *>(list->object); + auto *const elementBin = GST_BIN(parent->target()); + ObjectLocker locker(parent->target()); + + while (elementBin->children) + gst_bin_remove(elementBin, GST_ELEMENT(elementBin->children->data)); + } +}; static void readChildren(Item *item, void *value) { - *static_cast<ElementList *>(value) = - ElementList(item, Q_NULLPTR, &appendChild, &countChildren, &childAt, &clearChildren); + *static_cast<ElementList *>(value) = ElementList(item); } static void readState(Item *item, void *value) |