summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Hasselmann <mathias.hasselmann@kdab.com>2013-11-06 23:15:14 +0100
committerMathias Hasselmann <mathias.hasselmann@kdab.com>2013-11-06 23:15:14 +0100
commit6eeba4f47a619f68b361f11a7a763657a2a4cb4f (patch)
tree2ae6089339b802177d0ca4a6daa64a3d88a51fbc
parentc2bbf169b37d75a300592a1fd7cc8fb1e3a2ae8f (diff)
downloadqtquickstreamer-6eeba4f47a619f68b361f11a7a763657a2a4cb4f.tar.gz
qtquickstreamer-6eeba4f47a619f68b361f11a7a763657a2a4cb4f.tar.xz
Properly lock bins when iterating their children
-rw-r--r--src/QuickStreamer/item.cpp82
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)