aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-08-17 06:27:22 -0400
committerTakashi Iwai <tiwai@suse.de>2009-08-17 06:48:15 -0400
commitf217ac59b6dd73105abc13da3fe656391fa6d135 (patch)
treed0ff4a0dec41b603df76baec15ec51bf62146ee6
parent317b80817fcaeac7ae7e062fcccef0d2aba38a78 (diff)
sound: snd_ctl_remove_unlocked_id: simplify user control counting
Move the decrementing of the user controls counter from snd_ctl_elem_remove to snd_ctl_remove_unlocked_id; this saves the separate locking of the controls semaphore, and therefore removes a harmless race. Since the purpose of the function is to operate on user controls (the control being unlocked is just a prerequisite), rename it to snd_ctl_remove_user_ctl. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/core/control.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index 9d91f77bc880..bc64b723415b 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -414,7 +414,7 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
414EXPORT_SYMBOL(snd_ctl_remove_id); 414EXPORT_SYMBOL(snd_ctl_remove_id);
415 415
416/** 416/**
417 * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it 417 * snd_ctl_remove_user_ctl - remove and release the unlocked user control
418 * @file: active control handle 418 * @file: active control handle
419 * @id: the control id to remove 419 * @id: the control id to remove
420 * 420 *
@@ -423,8 +423,8 @@ EXPORT_SYMBOL(snd_ctl_remove_id);
423 * 423 *
424 * Returns 0 if successful, or a negative error code on failure. 424 * Returns 0 if successful, or a negative error code on failure.
425 */ 425 */
426static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file, 426static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file,
427 struct snd_ctl_elem_id *id) 427 struct snd_ctl_elem_id *id)
428{ 428{
429 struct snd_card *card = file->card; 429 struct snd_card *card = file->card;
430 struct snd_kcontrol *kctl; 430 struct snd_kcontrol *kctl;
@@ -442,6 +442,9 @@ static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file,
442 goto error; 442 goto error;
443 } 443 }
444 ret = snd_ctl_remove(card, kctl); 444 ret = snd_ctl_remove(card, kctl);
445 if (ret < 0)
446 goto error;
447 card->user_ctl_count--;
445error: 448error:
446 up_write(&card->controls_rwsem); 449 up_write(&card->controls_rwsem);
447 return ret; 450 return ret;
@@ -1053,18 +1056,10 @@ static int snd_ctl_elem_remove(struct snd_ctl_file *file,
1053 struct snd_ctl_elem_id __user *_id) 1056 struct snd_ctl_elem_id __user *_id)
1054{ 1057{
1055 struct snd_ctl_elem_id id; 1058 struct snd_ctl_elem_id id;
1056 int err;
1057 1059
1058 if (copy_from_user(&id, _id, sizeof(id))) 1060 if (copy_from_user(&id, _id, sizeof(id)))
1059 return -EFAULT; 1061 return -EFAULT;
1060 err = snd_ctl_remove_unlocked_id(file, &id); 1062 return snd_ctl_remove_user_ctl(file, &id);
1061 if (! err) {
1062 struct snd_card *card = file->card;
1063 down_write(&card->controls_rwsem);
1064 card->user_ctl_count--;
1065 up_write(&card->controls_rwsem);
1066 }
1067 return err;
1068} 1063}
1069 1064
1070static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr) 1065static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)