diff options
Diffstat (limited to 'linux')
-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; |