diff options
Diffstat (limited to 'sound/core/timer.c')
| -rw-r--r-- | sound/core/timer.c | 7 | 
1 files changed, 5 insertions, 2 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c index 2f836ca09860..cd67d1c12cf1 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1618,6 +1618,7 @@ static int snd_timer_user_tselect(struct file *file,  	if (err < 0)  		goto __err; +	tu->qhead = tu->qtail = tu->qused = 0;  	kfree(tu->queue);  	tu->queue = NULL;  	kfree(tu->tqueue); @@ -1959,6 +1960,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,  	tu = file->private_data;  	unit = tu->tread ? sizeof(struct snd_timer_tread) : sizeof(struct snd_timer_read); +	mutex_lock(&tu->ioctl_lock);  	spin_lock_irq(&tu->qlock);  	while ((long)count - result >= unit) {  		while (!tu->qused) { @@ -1974,7 +1976,9 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,  			add_wait_queue(&tu->qchange_sleep, &wait);  			spin_unlock_irq(&tu->qlock); +			mutex_unlock(&tu->ioctl_lock);  			schedule(); +			mutex_lock(&tu->ioctl_lock);  			spin_lock_irq(&tu->qlock);  			remove_wait_queue(&tu->qchange_sleep, &wait); @@ -1994,7 +1998,6 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,  		tu->qused--;  		spin_unlock_irq(&tu->qlock); -		mutex_lock(&tu->ioctl_lock);  		if (tu->tread) {  			if (copy_to_user(buffer, &tu->tqueue[qhead],  					 sizeof(struct snd_timer_tread))) @@ -2004,7 +2007,6 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,  					 sizeof(struct snd_timer_read)))  				err = -EFAULT;  		} -		mutex_unlock(&tu->ioctl_lock);  		spin_lock_irq(&tu->qlock);  		if (err < 0) @@ -2014,6 +2016,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,  	}   _error:  	spin_unlock_irq(&tu->qlock); +	mutex_unlock(&tu->ioctl_lock);  	return result > 0 ? result : err;  }  | 
