mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-04 23:46:43 +00:00
ede4562c23
The native GstIterator is freed once the Gst.Enumerable instance is destroyed. At this point there could still be a Gst.Enumerator instance that uses the native GstIterator and would crash then. Store the Gst.Enumerable instance inside the Gst.Enumerator to prevent the GC from destroying it before the enumerator is destroyed.
92 lines
2.2 KiB
C#
92 lines
2.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Runtime.InteropServices;
|
|
using GLib;
|
|
|
|
namespace Gst {
|
|
|
|
internal class Enumerable : IEnumerable {
|
|
private class Enumerator : IEnumerator {
|
|
Enumerable enumerable;
|
|
Hashtable seen = new Hashtable ();
|
|
IntPtr iterator;
|
|
|
|
private object current = null;
|
|
public object Current {
|
|
get {
|
|
return current;
|
|
}
|
|
}
|
|
|
|
public bool MoveNext () {
|
|
IntPtr raw_ret;
|
|
bool retry = false;
|
|
|
|
if (iterator == IntPtr.Zero)
|
|
return false;
|
|
|
|
do {
|
|
int ret = gst_iterator_next (iterator, out raw_ret);
|
|
switch (ret) {
|
|
case 0:
|
|
return false;
|
|
case 1:
|
|
if (seen.Contains (raw_ret)) {
|
|
retry = true;
|
|
break;
|
|
}
|
|
|
|
seen.Add (raw_ret, null);
|
|
current = GLib.Object.GetObject (raw_ret, true);
|
|
return true;
|
|
case 2:
|
|
gst_iterator_resync (iterator);
|
|
retry = true;
|
|
break;
|
|
default:
|
|
case 3:
|
|
throw new Exception ("Error while iterating pads");
|
|
}
|
|
} while (retry);
|
|
|
|
return false;
|
|
}
|
|
|
|
public void Reset () {
|
|
seen.Clear ();
|
|
if (iterator != IntPtr.Zero)
|
|
gst_iterator_resync (iterator);
|
|
}
|
|
|
|
public Enumerator (Enumerable enumerable, IntPtr iterator) {
|
|
this.enumerable = enumerable;
|
|
this.iterator = iterator;
|
|
}
|
|
}
|
|
|
|
private IntPtr iterator;
|
|
private Enumerator enumerator;
|
|
|
|
public Enumerable (IntPtr iterator) {
|
|
this.iterator = iterator;
|
|
this.enumerator = new Enumerator (this, iterator);
|
|
}
|
|
|
|
public IEnumerator GetEnumerator () {
|
|
return this.enumerator;
|
|
}
|
|
|
|
~Enumerable () {
|
|
if (iterator != IntPtr.Zero)
|
|
gst_iterator_free (iterator);
|
|
}
|
|
|
|
[DllImport ("libgstreamer-0.10.dll") ]
|
|
static extern int gst_iterator_next (IntPtr iterator, out IntPtr elem);
|
|
[DllImport ("libgstreamer-0.10.dll") ]
|
|
static extern void gst_iterator_resync (IntPtr iterator);
|
|
[DllImport ("libgstreamer-0.10.dll") ]
|
|
static extern void gst_iterator_free (IntPtr iterator);
|
|
|
|
}
|
|
}
|