summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2010-07-29 17:27:06 +0200
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2010-07-29 17:29:00 +0200
commit2057cf6d79451e81a25babd9a8965bdc56c427b3 (patch)
tree1c2eb974ac6420b7465f0692a68d1b715b2f9258
parent29289ee79e1b49b6dcbb314bee8c760395e5c8e9 (diff)
queue2: download mode; prevent range corruption due to race
Current range was being updated in the thread performing seek, but as no locks were kept for a short section, data flow could resume before current range updated, so data for the new range would be accepted as from the previous range. Rather, range should be updated in serialized manner based on newsegment event.
-rw-r--r--plugins/elements/gstqueue2.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c
index 83af4b9bd5..8f595a22ca 100644
--- a/plugins/elements/gstqueue2.c
+++ b/plugins/elements/gstqueue2.c
@@ -241,12 +241,15 @@ static gboolean gst_queue2_sink_activate_push (GstPad * pad, gboolean active);
static GstStateChangeReturn gst_queue2_change_state (GstElement * element,
GstStateChange transition);
static gboolean gst_queue2_is_empty (GstQueue2 * queue);
static gboolean gst_queue2_is_filled (GstQueue2 * queue);
+static void update_cur_level (GstQueue2 * queue, GstQueue2Range * range);
+
+
/* static guint gst_queue2_signals[LAST_SIGNAL] = { 0 }; */
static void
gst_queue2_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
@@ -645,12 +648,18 @@ apply_segment (GstQueue2 * queue, GstEvent * event, GstSegment * segment)
"received NEWSEGMENT update %d, rate %lf, applied rate %lf, "
"format %d, "
"%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);
if (format == GST_FORMAT_BYTES) {
+ if (QUEUE_IS_USING_TEMP_FILE (queue)) {
+ /* start is where we'll be getting from and as such writing next */
+ queue->current = add_range (queue, start);
+ /* update the stats for this range */
+ update_cur_level (queue, queue->current);
+ }
}
/* now configure the values, we use these to track timestamps on the
* sinkpad. */
if (format != GST_FORMAT_TIME) {
/* non-time format, pretent the current time segment is closed with a
@@ -1009,17 +1018,12 @@ perform_seek_to_offset (GstQueue2 * queue, guint64 offset)
GST_SEEK_TYPE_NONE, -1);
GST_QUEUE2_MUTEX_UNLOCK (queue);
res = gst_pad_push_event (queue->sinkpad, event);
GST_QUEUE2_MUTEX_LOCK (queue);
- if (res) {
- queue->current = add_range (queue, offset);
- /* update the stats for this range */
- update_cur_level (queue, queue->current);
- }
return res;
}
/* see if there is enough data in the file to read a full buffer */
static gboolean
gst_queue2_have_data (GstQueue2 * queue, guint64 offset, guint length)