v4l2: fix race condition
authorRob Clark <rob@ti.com>
Sun, 4 Apr 2010 11:39:52 +0000 (06:39 -0500)
committerRob Clark <rob@ti.com>
Wed, 29 Dec 2010 17:46:41 +0000 (11:46 -0600)
The size of the buffer would be zero'd out in gst_v4l2_buffer_finalize()
after the buffer is qbuf'd or pushed onto the queue of available buffers..
leaving a race condition where the thread waiting for the buffer could awake
and set back a valid size before the finalizing thread zeros out the length.
This would result that the newly allocated buffer has length of zero.

sys/v4l2/gstv4l2bufferpool.c

index 2d9893c..a8e7e79 100644 (file)
@@ -472,8 +472,10 @@ gst_v4l2_buffer_pool_get (GstV4l2BufferPool * pool, gboolean blocking)
   }
 
   if (buf) {
+    GST_V4L2_BUFFER_POOL_LOCK (pool);
     GST_BUFFER_SIZE (buf) = buf->vbuffer.length;
     GST_BUFFER_FLAG_UNSET (buf, 0xffffffff);
+    GST_V4L2_BUFFER_POOL_UNLOCK (pool);
   }
 
   pool->running = TRUE;
@@ -555,8 +557,6 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool)
     GST_DEBUG_OBJECT (pool->v4l2elem, "num_live_buffers++: %d",
         pool->num_live_buffers);
 
-    GST_V4L2_BUFFER_POOL_UNLOCK (pool);
-
     /* set top/bottom field first if v4l2_buffer has the information */
     if (buffer.field == V4L2_FIELD_INTERLACED_TB)
       GST_BUFFER_FLAG_SET (pool_buffer, GST_VIDEO_BUFFER_TFF);
@@ -566,6 +566,8 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool)
     /* this can change at every frame, esp. with jpeg */
     GST_BUFFER_SIZE (pool_buffer) = buffer.bytesused;
 
+    GST_V4L2_BUFFER_POOL_UNLOCK (pool);
+
     return pool_buffer;
   }