<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">---------------------
PatchSet 3091 
Date: 2005/04/04 16:44:58
Author: perex
Branch: HEAD
Tag: (none) 
Log:
Summary: timer - added tread semaphore

Members: 
	core/timer.c:1.69-&gt;1.70 

Index: /sound/core/timer.c
diff -u /sound/core/timer.c.old /sound/core/timer.c
--- /sound/core/timer.c.old	Tue Mar 22 07:31:21 2005
+++ /sound/core/timer.c	Mon Apr  4 08:44:58 2005
@@ -69,6 +69,7 @@
 	struct timespec tstamp;		/* trigger tstamp */
 	wait_queue_head_t qchange_sleep;
 	struct fasync_struct *fasync;
+	struct semaphore tread_sem;
 } snd_timer_user_t;
 
 /* list of timers */
@@ -1208,6 +1209,7 @@
 		return -ENOMEM;
 	spin_lock_init(&amp;tu-&gt;qlock);
 	init_waitqueue_head(&amp;tu-&gt;qchange_sleep);
+	init_MUTEX(&amp;tu-&gt;tread_sem);
 	tu-&gt;ticks = 1;
 	tu-&gt;queue_size = 128;
 	tu-&gt;queue = (snd_timer_read_t *)kmalloc(tu-&gt;queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
@@ -1454,18 +1456,23 @@
 	snd_timer_user_t *tu;
 	snd_timer_select_t tselect;
 	char str[32];
-	int err;
+	int err = 0;
 	
 	tu = file-&gt;private_data;
-	if (tu-&gt;timeri)
+	down(&amp;tu-&gt;tread_sem);
+	if (tu-&gt;timeri) {
 		snd_timer_close(tu-&gt;timeri);
-	if (copy_from_user(&amp;tselect, _tselect, sizeof(tselect)))
-		return -EFAULT;
+		tu-&gt;timeri = NULL;
+	}
+	if (copy_from_user(&amp;tselect, _tselect, sizeof(tselect))) {
+		err = -EFAULT;
+		goto __err;
+	}
 	sprintf(str, "application %i", current-&gt;pid);
 	if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
 		tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
 	if ((err = snd_timer_open(&amp;tu-&gt;timeri, str, &amp;tselect.id, current-&gt;pid)) &lt; 0)
-		return err;
+		goto __err;
 
 	if (tu-&gt;queue) {
 		kfree(tu-&gt;queue);
@@ -1477,23 +1484,27 @@
 	}
 	if (tu-&gt;tread) {
 		tu-&gt;tqueue = (snd_timer_tread_t *)kmalloc(tu-&gt;queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
-		if (tu-&gt;tqueue == NULL) {
-			snd_timer_close(tu-&gt;timeri);
-			return -ENOMEM;
-		}
+		if (tu-&gt;tqueue == NULL)
+			err = -ENOMEM;
 	} else {
 		tu-&gt;queue = (snd_timer_read_t *)kmalloc(tu-&gt;queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
-		if (tu-&gt;queue == NULL) {
-			snd_timer_close(tu-&gt;timeri);
-			return -ENOMEM;
-		}
+		if (tu-&gt;queue == NULL)
+			err = -ENOMEM;
 	}
 	
-	tu-&gt;timeri-&gt;flags |= SNDRV_TIMER_IFLG_FAST;
-	tu-&gt;timeri-&gt;callback = tu-&gt;tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
-	tu-&gt;timeri-&gt;ccallback = snd_timer_user_ccallback;
-	tu-&gt;timeri-&gt;callback_data = (void *)tu;
-	return 0;
+      	if (err &lt; 0) {
+		snd_timer_close(tu-&gt;timeri);
+      		tu-&gt;timeri = NULL;
+      	} else {
+		tu-&gt;timeri-&gt;flags |= SNDRV_TIMER_IFLG_FAST;
+		tu-&gt;timeri-&gt;callback = tu-&gt;tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
+		tu-&gt;timeri-&gt;ccallback = snd_timer_user_ccallback;
+		tu-&gt;timeri-&gt;callback_data = (void *)tu;
+	}
+
+      __err:
+      	up(&amp;tu-&gt;tread_sem);
+	return err;
 }
 
 static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info)
@@ -1685,11 +1696,17 @@
 	{
 		int xarg;
 		
-		if (tu-&gt;timeri)		/* too late */
+		down(&amp;tu-&gt;tread_sem);
+		if (tu-&gt;timeri)	{	/* too late */
+			up(&amp;tu-&gt;tread_sem);
 			return -EBUSY;
-		if (get_user(xarg, p))
+		}
+		if (get_user(xarg, p)) {
+			up(&amp;tu-&gt;tread_sem);
 			return -EFAULT;
+		}
 		tu-&gt;tread = xarg ? 1 : 0;
+		up(&amp;tu-&gt;tread_sem);
 		return 0;
 	}
 	case SNDRV_TIMER_IOCTL_GINFO:
</pre></body></html>