mirror of https://gitee.com/openkylin/linux.git
sound: oss: vwsnd: avoid interruptible_sleep_on
Interruptible_sleep_on is racy and we want to remove it. This replaces the use in the vwsnd driver with an open-coded prepare_to_wait loop that fixes the race between concurrent open() and close() calls, and also drops the global mutex while waiting here, which restores the original behavior that was changed during the BKL removal. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
1a21576562
commit
7bd6972a92
|
@ -2921,6 +2921,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
|
|||
vwsnd_dev_t *devc;
|
||||
int minor = iminor(inode);
|
||||
int sw_samplefmt;
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
|
||||
|
||||
|
@ -2937,21 +2938,26 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
|
|||
}
|
||||
|
||||
mutex_lock(&devc->open_mutex);
|
||||
while (devc->open_mode & file->f_mode) {
|
||||
while (1) {
|
||||
prepare_to_wait(&devc->open_wait, &wait, TASK_INTERRUPTIBLE);
|
||||
if (!(devc->open_mode & file->f_mode))
|
||||
break;
|
||||
|
||||
mutex_unlock(&devc->open_mutex);
|
||||
mutex_unlock(&vwsnd_mutex);
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
DEC_USE_COUNT;
|
||||
mutex_unlock(&vwsnd_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
interruptible_sleep_on(&devc->open_wait);
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
DEC_USE_COUNT;
|
||||
mutex_unlock(&vwsnd_mutex);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
mutex_lock(&vwsnd_mutex);
|
||||
mutex_lock(&devc->open_mutex);
|
||||
}
|
||||
finish_wait(&devc->open_wait, &wait);
|
||||
devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
|
||||
mutex_unlock(&devc->open_mutex);
|
||||
|
||||
|
|
Loading…
Reference in New Issue