summaryrefslogtreecommitdiff
path: root/drivers/media/dvb/dvb-core/dvb_frontend.c
diff options
context:
space:
mode:
authorAndreas Oberritter <obi@linuxtv.org>2011-12-09 21:37:00 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-12-30 17:16:01 -0200
commitb9d5efcceb6b34ee20111b62cf7be61ae79af4e9 (patch)
tree7a0dc9653474e821ebd2de3ee1d2f6faf9cab75f /drivers/media/dvb/dvb-core/dvb_frontend.c
parenta1dca1e30ac7991d8a90a3377008c850eb466edf (diff)
[media] DVB: dvb_frontend: fix delayed thread exit
There are some issues and miss-behaves at the dvb fe thread: 1) dvb_shutdown_timeout should be dvb_shutdown_timeout * HZ instead of (dvb_shutdown_timeout * HZ + 1); 2) add a memory barrier to warrant that all CPU's will consider the new value for release_jiffies; 3) wake up dvb thread also when fepriv->exit == DVB_FE_NO_EXIT. Signed-off-by: Andreas Oberritter <obi@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/dvb-core/dvb_frontend.c')
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 66537b10132c..3ff37cfde6ab 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -507,7 +507,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
return 1;
if (fepriv->dvbdev->writers == 1)
- if (time_after(jiffies, fepriv->release_jiffies +
+ if (time_after_eq(jiffies, fepriv->release_jiffies +
dvb_shutdown_timeout * HZ))
return 1;
@@ -2116,12 +2116,15 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
dprintk ("%s\n", __func__);
- if ((file->f_flags & O_ACCMODE) != O_RDONLY)
+ if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
fepriv->release_jiffies = jiffies;
+ mb();
+ }
ret = dvb_generic_release (inode, file);
if (dvbdev->users == -1) {
+ wake_up(&fepriv->wait_queue);
if (fepriv->exit != DVB_FE_NO_EXIT) {
fops_put(file->f_op);
file->f_op = NULL;