aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/seq/seq_clientmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/seq/seq_clientmgr.c')
-rw-r--r--sound/core/seq/seq_clientmgr.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 04d4db44fae5..61a07fe34cd2 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -255,12 +255,12 @@ static int seq_free_client1(struct snd_seq_client *client)
255 255
256 if (!client) 256 if (!client)
257 return 0; 257 return 0;
258 snd_seq_delete_all_ports(client);
259 snd_seq_queue_client_leave(client->number);
260 spin_lock_irqsave(&clients_lock, flags); 258 spin_lock_irqsave(&clients_lock, flags);
261 clienttablock[client->number] = 1; 259 clienttablock[client->number] = 1;
262 clienttab[client->number] = NULL; 260 clienttab[client->number] = NULL;
263 spin_unlock_irqrestore(&clients_lock, flags); 261 spin_unlock_irqrestore(&clients_lock, flags);
262 snd_seq_delete_all_ports(client);
263 snd_seq_queue_client_leave(client->number);
264 snd_use_lock_sync(&client->use_lock); 264 snd_use_lock_sync(&client->use_lock);
265 snd_seq_queue_client_termination(client->number); 265 snd_seq_queue_client_termination(client->number);
266 if (client->pool) 266 if (client->pool)
@@ -910,7 +910,8 @@ int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
910static int snd_seq_client_enqueue_event(struct snd_seq_client *client, 910static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
911 struct snd_seq_event *event, 911 struct snd_seq_event *event,
912 struct file *file, int blocking, 912 struct file *file, int blocking,
913 int atomic, int hop) 913 int atomic, int hop,
914 struct mutex *mutexp)
914{ 915{
915 struct snd_seq_event_cell *cell; 916 struct snd_seq_event_cell *cell;
916 int err; 917 int err;
@@ -948,7 +949,8 @@ static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
948 return -ENXIO; /* queue is not allocated */ 949 return -ENXIO; /* queue is not allocated */
949 950
950 /* allocate an event cell */ 951 /* allocate an event cell */
951 err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, file); 952 err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic,
953 file, mutexp);
952 if (err < 0) 954 if (err < 0)
953 return err; 955 return err;
954 956
@@ -1017,12 +1019,11 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
1017 return -ENXIO; 1019 return -ENXIO;
1018 1020
1019 /* allocate the pool now if the pool is not allocated yet */ 1021 /* allocate the pool now if the pool is not allocated yet */
1022 mutex_lock(&client->ioctl_mutex);
1020 if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) { 1023 if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) {
1021 mutex_lock(&client->ioctl_mutex);
1022 err = snd_seq_pool_init(client->pool); 1024 err = snd_seq_pool_init(client->pool);
1023 mutex_unlock(&client->ioctl_mutex);
1024 if (err < 0) 1025 if (err < 0)
1025 return -ENOMEM; 1026 goto out;
1026 } 1027 }
1027 1028
1028 /* only process whole events */ 1029 /* only process whole events */
@@ -1073,7 +1074,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
1073 /* ok, enqueue it */ 1074 /* ok, enqueue it */
1074 err = snd_seq_client_enqueue_event(client, &event, file, 1075 err = snd_seq_client_enqueue_event(client, &event, file,
1075 !(file->f_flags & O_NONBLOCK), 1076 !(file->f_flags & O_NONBLOCK),
1076 0, 0); 1077 0, 0, &client->ioctl_mutex);
1077 if (err < 0) 1078 if (err < 0)
1078 break; 1079 break;
1079 1080
@@ -1084,6 +1085,8 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
1084 written += len; 1085 written += len;
1085 } 1086 }
1086 1087
1088 out:
1089 mutex_unlock(&client->ioctl_mutex);
1087 return written ? written : err; 1090 return written ? written : err;
1088} 1091}
1089 1092
@@ -1838,9 +1841,11 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
1838 (! snd_seq_write_pool_allocated(client) || 1841 (! snd_seq_write_pool_allocated(client) ||
1839 info->output_pool != client->pool->size)) { 1842 info->output_pool != client->pool->size)) {
1840 if (snd_seq_write_pool_allocated(client)) { 1843 if (snd_seq_write_pool_allocated(client)) {
1844 /* is the pool in use? */
1845 if (atomic_read(&client->pool->counter))
1846 return -EBUSY;
1841 /* remove all existing cells */ 1847 /* remove all existing cells */
1842 snd_seq_pool_mark_closing(client->pool); 1848 snd_seq_pool_mark_closing(client->pool);
1843 snd_seq_queue_client_leave_cells(client->number);
1844 snd_seq_pool_done(client->pool); 1849 snd_seq_pool_done(client->pool);
1845 } 1850 }
1846 client->pool->size = info->output_pool; 1851 client->pool->size = info->output_pool;
@@ -2260,7 +2265,8 @@ static int kernel_client_enqueue(int client, struct snd_seq_event *ev,
2260 if (! cptr->accept_output) 2265 if (! cptr->accept_output)
2261 result = -EPERM; 2266 result = -EPERM;
2262 else /* send it */ 2267 else /* send it */
2263 result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, atomic, hop); 2268 result = snd_seq_client_enqueue_event(cptr, ev, file, blocking,
2269 atomic, hop, NULL);
2264 2270
2265 snd_seq_client_unlock(cptr); 2271 snd_seq_client_unlock(cptr);
2266 return result; 2272 return result;