V4L/DVB (7708): pvrusb2-dvb: Fix stuck thread on streaming abort
authorMike Isely <isely@pobox.com>
Sun, 30 Mar 2008 23:36:31 +0000 (20:36 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Thu, 24 Apr 2008 17:09:48 +0000 (14:09 -0300)
If the device fails to stream, the feed thread will block forever
waiting for buffers.  But while in this state it was not looking for
an exit condition from the driver DVB interface.  This caused the
thread to jam.  Implement a new stop flag (which will be set
appropriately) to tell the thread to stop.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/pvrusb2/pvrusb2-dvb.c
drivers/media/video/pvrusb2/pvrusb2-dvb.h

index 58ef5caba83a29d324aec72cdd577acc74c6b192..d82fceae4689108a1cd99173333a2f5c5dec54b0 100644 (file)
@@ -41,6 +41,7 @@ static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap)
        stream = adap->channel.stream->stream;
 
        for (;;) {
+               if (adap->feed_thread_stop) break;
                if (kthread_should_stop()) break;
 
                /* Not sure about this... */
@@ -70,10 +71,12 @@ static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap)
                }
 
 
-               /* Wait until more buffers become available. */
+               /* Wait until more buffers become available or we're
+                  told not to wait any longer. */
                ret = wait_event_interruptible(
                    adap->buffer_wait_data,
-                   pvr2_stream_get_ready_count(stream) > 0);
+                   (pvr2_stream_get_ready_count(stream) > 0) ||
+                   adap->feed_thread_stop);
                if (ret < 0) break;
        }
 
@@ -107,6 +110,8 @@ static void pvr2_dvb_stream_end(struct pvr2_dvb_adapter *adap)
        struct pvr2_stream *stream;
 
        if (adap->thread) {
+               adap->feed_thread_stop = !0;
+               pvr2_dvb_notify(adap);
                kthread_stop(adap->thread);
                adap->thread = NULL;
        }
@@ -177,6 +182,7 @@ static int pvr2_dvb_stream_do_start(struct pvr2_dvb_adapter *adap)
                if (ret < 0) return ret;
        }
 
+       adap->feed_thread_stop = 0;
        adap->thread = kthread_run(pvr2_dvb_feed_thread, adap, "pvrusb2-dvb");
 
        if (IS_ERR(adap->thread)) {
index 884ff916a352cce11c0e7e48e9afdb1f1fbb942b..2dd0d4ef22a2cf5986f11c1ee6aef5537779cb17 100644 (file)
@@ -28,6 +28,7 @@ struct pvr2_dvb_adapter {
        unsigned int            stream_run:1;
 
        wait_queue_head_t       buffer_wait_data;
+       int                     feed_thread_stop;
        char                    *buffer_storage[PVR2_DVB_BUFFER_COUNT];
 };