|
@@ -910,7 +910,8 @@ int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
|
|
|
static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
|
|
|
struct snd_seq_event *event,
|
|
|
struct file *file, int blocking,
|
|
|
- int atomic, int hop)
|
|
|
+ int atomic, int hop,
|
|
|
+ struct mutex *mutexp)
|
|
|
{
|
|
|
struct snd_seq_event_cell *cell;
|
|
|
int err;
|
|
@@ -948,7 +949,8 @@ static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
|
|
|
return -ENXIO; /* queue is not allocated */
|
|
|
|
|
|
/* allocate an event cell */
|
|
|
- err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, file);
|
|
|
+ err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic,
|
|
|
+ file, mutexp);
|
|
|
if (err < 0)
|
|
|
return err;
|
|
|
|
|
@@ -1017,12 +1019,11 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
|
|
|
return -ENXIO;
|
|
|
|
|
|
/* allocate the pool now if the pool is not allocated yet */
|
|
|
+ mutex_lock(&client->ioctl_mutex);
|
|
|
if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) {
|
|
|
- mutex_lock(&client->ioctl_mutex);
|
|
|
err = snd_seq_pool_init(client->pool);
|
|
|
- mutex_unlock(&client->ioctl_mutex);
|
|
|
if (err < 0)
|
|
|
- return -ENOMEM;
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
/* only process whole events */
|
|
@@ -1073,7 +1074,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
|
|
|
/* ok, enqueue it */
|
|
|
err = snd_seq_client_enqueue_event(client, &event, file,
|
|
|
!(file->f_flags & O_NONBLOCK),
|
|
|
- 0, 0);
|
|
|
+ 0, 0, &client->ioctl_mutex);
|
|
|
if (err < 0)
|
|
|
break;
|
|
|
|
|
@@ -1084,6 +1085,8 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
|
|
|
written += len;
|
|
|
}
|
|
|
|
|
|
+ out:
|
|
|
+ mutex_unlock(&client->ioctl_mutex);
|
|
|
return written ? written : err;
|
|
|
}
|
|
|
|
|
@@ -2263,7 +2266,8 @@ static int kernel_client_enqueue(int client, struct snd_seq_event *ev,
|
|
|
if (! cptr->accept_output)
|
|
|
result = -EPERM;
|
|
|
else /* send it */
|
|
|
- result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, atomic, hop);
|
|
|
+ result = snd_seq_client_enqueue_event(cptr, ev, file, blocking,
|
|
|
+ atomic, hop, NULL);
|
|
|
|
|
|
snd_seq_client_unlock(cptr);
|
|
|
return result;
|