diff options
author | Andrew de Quincy <devnull@localhost> | 2004-03-12 10:20:24 +0000 |
---|---|---|
committer | Andrew de Quincy <devnull@localhost> | 2004-03-12 10:20:24 +0000 |
commit | ce115aac8f6de26814e410542d68553a1c9789a4 (patch) | |
tree | 86155f131dba0f8aa3ba97c9bc2291f50910e836 /linux/drivers | |
parent | 25b300b94271ba4a58687b352d22ac05ea413e41 (diff) | |
download | mediapointer-dvb-s2-ce115aac8f6de26814e410542d68553a1c9789a4.tar.gz mediapointer-dvb-s2-ce115aac8f6de26814e410542d68553a1c9789a4.tar.bz2 |
Fix wake_on_interruptible_timeout call so it can also be woken up when
we need it
Diffstat (limited to 'linux/drivers')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 84e9627aa..df9dbc902 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -110,6 +110,7 @@ struct dvb_frontend_data { int max_drift; int step_size; int exit; + int wakeup; fe_status_t status; }; @@ -460,6 +461,19 @@ static int dvb_frontend_is_exiting (struct dvb_frontend_data *fe) return 0; } +static int dvb_frontend_should_wakeup (struct dvb_frontend_data *fe) +{ + if (fe->wakeup) { + fe->wakeup = 0; + return 1; + } + return dvb_frontend_is_exiting(fe); +} + +static void dvb_frontend_wakeup (struct dvb_frontend_data *fe) { + fe->wakeup = 1; + wake_up_interruptible(&fe->wait_queue); +} static int dvb_frontend_thread (void *data) { @@ -483,7 +497,7 @@ static int dvb_frontend_thread (void *data) while (1) { up (&fe->sem); /* is locked when we enter the thread... */ - timeout = wait_event_interruptible_timeout(fe->wait_queue,0 != dvb_frontend_is_exiting (fe), delay); + timeout = wait_event_interruptible_timeout(fe->wait_queue,0 != dvb_frontend_should_wakeup (fe), delay); if (-ERESTARTSYS == timeout || 0 != dvb_frontend_is_exiting (fe)) { /* got signal or quitting */ break; @@ -578,6 +592,7 @@ static int dvb_frontend_thread (void *data) // tune occurs if (fe->state & FESTATE_RETUNE) { fe->state = FESTATE_TUNING_FAST; + dvb_frontend_wakeup(fe); } } @@ -599,7 +614,7 @@ static int dvb_frontend_thread (void *data) fe->thread_pid = 0; mb(); - wake_up_interruptible (&fe->wait_queue); + dvb_frontend_wakeup(fe); return 0; } @@ -626,7 +641,7 @@ static void dvb_frontend_stop (struct dvb_frontend_data *fe) } /* wake up the frontend thread, so it notices that fe->exit == 1 */ - wake_up_interruptible(&fe->wait_queue); + dvb_frontend_wakeup(fe); /* wait until the frontend thread has exited */ ret = wait_event_interruptible(fe->wait_queue,0 == fe->thread_pid); @@ -791,13 +806,8 @@ static int dvb_frontend_ioctl (struct inode *inode, struct file *file, // This ensures the app doesn't start reading data too quickly, perhaps from the // previous lock, which is REALLY CONFUSING TO DEBUG! if ((cmd == FE_SET_FRONTEND) && (err == 0)) { - // note: cannot use wait_event_interruptible_* here as that - // causes the thread not to wake until AFTER the call here returns. This is useless - // because the whole point is to have the thread wake first, and perform at least one tune - wake_up_interruptible(&fe->wait_queue); - while(fe->state & FESTATE_RETUNE) { - dvb_delay(10); - } + dvb_frontend_wakeup(fe); + err = wait_event_interruptible(fe->wait_queue, fe->state & ~FESTATE_RETUNE); } return err; |