Module Name:    src
Committed By:   rmind
Date:           Sat May 14 02:27:35 UTC 2011

Modified Files:
        src/sys/arch/landisk/dev: button.c

Log Message:
Convert to mutex(9)/condvar(9).  Use RUN_ONCE(9) to avoid racy init.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/landisk/dev/button.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/landisk/dev/button.c
diff -u src/sys/arch/landisk/dev/button.c:1.5 src/sys/arch/landisk/dev/button.c:1.6
--- src/sys/arch/landisk/dev/button.c:1.5	Sat Mar  1 14:16:49 2008
+++ src/sys/arch/landisk/dev/button.c	Sat May 14 02:27:35 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: button.c,v 1.5 2008/03/01 14:16:49 rmind Exp $	*/
+/*	$NetBSD: button.c,v 1.6 2011/05/14 02:27:35 rmind Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -36,20 +36,18 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: button.c,v 1.5 2008/03/01 14:16:49 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: button.c,v 1.6 2011/05/14 02:27:35 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/simplelock.h>
 #include <sys/queue.h>
-#include <sys/proc.h>
-#include <sys/kthread.h>
+#include <sys/mutex.h>
 #include <sys/errno.h>
 #include <sys/fcntl.h>
 #include <sys/callout.h>
 #include <sys/kernel.h>
+#include <sys/once.h>
 #include <sys/poll.h>
 #include <sys/select.h>
 #include <sys/vnode.h>
@@ -61,17 +59,17 @@
 /*
  * event handler
  */
-static LIST_HEAD(, btn_event) btn_event_list =
-    LIST_HEAD_INITIALIZER(btn_event_list);
-static struct simplelock btn_event_list_slock =
-    SIMPLELOCK_INITIALIZER;
+static ONCE_DECL(btn_once);
+static LIST_HEAD(, btn_event) btn_event_list;
+static kmutex_t btn_event_list_lock;
 
 static struct lwp *btn_daemon;
 
 #define	BTN_MAX_EVENTS		32
 
-static struct simplelock btn_event_queue_slock =
-    SIMPLELOCK_INITIALIZER;
+static kmutex_t btn_event_queue_lock;
+static kcondvar_t btn_event_queue_cv;
+
 static button_event_t btn_event_queue[BTN_MAX_EVENTS];
 static int btn_event_queue_head;
 static int btn_event_queue_tail;
@@ -98,6 +96,19 @@
 };
 
 static int
+btn_init(void)
+{
+
+	LIST_INIT(&btn_event_list);
+	mutex_init(&btn_event_list_lock, MUTEX_DEFAULT, IPL_NONE);
+	mutex_init(&btn_event_queue_lock, MUTEX_DEFAULT, IPL_NONE);
+	cv_init(&btn_event_queue_cv, "btncv");
+	selinit(&btn_event_queue_selinfo);
+
+	return 0;
+}
+
+static int
 btn_queue_event(button_event_t *bev)
 {
 
@@ -138,19 +149,18 @@
 int
 btnopen(dev_t dev, int flag, int mode, struct lwp *l)
 {
-	static bool btn_event_queue_selinfo_init;	/* XXX */
 	int error;
 
-	if (!btn_event_queue_selinfo_init) {
-		selinit(&btn_event_queue_selinfo);
-		btn_event_queue_selinfo_init = true;
+	error = RUN_ONCE(&btn_once, btn_init);
+	if (error) {
+		return error;
 	}
 
 	if (minor(dev) != 0) {
 		return (ENODEV);
 	}
 
-	simple_lock(&btn_event_queue_slock);
+	mutex_enter(&btn_event_queue_lock);
 	if (btn_daemon != NULL) {
 		error = EBUSY;
 	} else {
@@ -158,7 +168,7 @@
 		btn_daemon = l;
 		btn_event_queue_flush();
 	}
-	simple_unlock(&btn_event_queue_slock);
+	mutex_exit(&btn_event_queue_lock);
 
 	return (error);
 }
@@ -172,11 +182,11 @@
 		return (ENODEV);
 	}
 
-	simple_lock(&btn_event_queue_slock);
+	mutex_enter(&btn_event_queue_lock);
 	count = btn_event_queue_count;
 	btn_daemon = NULL;
 	btn_event_queue_flush();
-	simple_unlock(&btn_event_queue_slock);
+	mutex_exit(&btn_event_queue_lock);
 
 	if (count) {
 		printf("WARNING: %d events lost by exiting daemon\n", count);
@@ -224,23 +234,22 @@
 		return (EINVAL);
 	}
 
-	simple_lock(&btn_event_queue_slock);
+	mutex_enter(&btn_event_queue_lock);
 	for (;;) {
 		if (btn_get_event(&bev)) {
-			simple_unlock(&btn_event_queue_slock);
+			mutex_exit(&btn_event_queue_lock);
 			return (uiomove(&bev, BUTTON_EVENT_MSG_SIZE, uio));
 		}
 
 		if (flags & IO_NDELAY) {
-			simple_unlock(&btn_event_queue_slock);
+			mutex_exit(&btn_event_queue_lock);
 			return (EWOULDBLOCK);
 		}
 
 		btn_event_queue_flags |= BEVQ_F_WAITING;
-		error = ltsleep(&btn_event_queue_count,
-		    (PRIBIO|PCATCH), "btnread", 0, &btn_event_queue_slock);
+		error = cv_wait_sig(&btn_event_queue_cv, &btn_event_queue_lock);
 		if (error) {
-			simple_unlock(&btn_event_queue_slock);
+			mutex_exit(&btn_event_queue_lock);
 			return (error);
 		}
 	}
@@ -261,13 +270,13 @@
 	if ((events & (POLLIN | POLLRDNORM)) == 0)
 		return (revents);
 
-	simple_lock(&btn_event_queue_slock);
+	mutex_enter(&btn_event_queue_lock);
 	if (btn_event_queue_count) {
 		revents |= events & (POLLIN | POLLRDNORM);
 	} else {
 		selrecord(l, &btn_event_queue_selinfo);
 	}
-	simple_unlock(&btn_event_queue_slock);
+	mutex_exit(&btn_event_queue_lock);
 
 	return (revents);
 }
@@ -276,19 +285,19 @@
 filt_btn_rdetach(struct knote *kn)
 {
 
-	simple_lock(&btn_event_queue_slock);
+	mutex_enter(&btn_event_queue_lock);
 	SLIST_REMOVE(&btn_event_queue_selinfo.sel_klist,
 	    kn, knote, kn_selnext);
-	simple_unlock(&btn_event_queue_slock);
+	mutex_exit(&btn_event_queue_lock);
 }
 
 static int
 filt_btn_read(struct knote *kn, long hint)
 {
 
-	simple_lock(&btn_event_queue_slock);
+	mutex_enter(&btn_event_queue_lock);
 	kn->kn_data = btn_event_queue_count;
-	simple_unlock(&btn_event_queue_slock);
+	mutex_exit(&btn_event_queue_lock);
 
 	return (kn->kn_data > 0);
 }
@@ -323,9 +332,9 @@
 		return (1);
 	}
 
-	simple_lock(&btn_event_queue_slock);
+	mutex_enter(&btn_event_queue_lock);
 	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
-	simple_unlock(&btn_event_queue_slock);
+	mutex_exit(&btn_event_queue_lock);
 
 	return (0);
 }
@@ -346,9 +355,9 @@
 btn_event_register(struct btn_event *bev)
 {
 
-	simple_lock(&btn_event_list_slock);
+	mutex_enter(&btn_event_list_lock);
 	LIST_INSERT_HEAD(&btn_event_list, bev, bev_list);
-	simple_unlock(&btn_event_list_slock);
+	mutex_exit(&btn_event_list_lock);
 
 	return (0);
 }
@@ -357,9 +366,9 @@
 btn_event_unregister(struct btn_event *bev)
 {
 
-	simple_lock(&btn_event_list_slock);
+	mutex_enter(&btn_event_list_lock);
 	LIST_REMOVE(bev, bev_list);
-	simple_unlock(&btn_event_list_slock);
+	mutex_exit(&btn_event_list_lock);
 }
 
 void
@@ -368,30 +377,28 @@
 	button_event_t btnev;
 	int rv;
 
-	simple_lock(&btn_event_queue_slock);
-	if (btn_daemon != NULL) {
-		btnev.bev_type = BUTTON_EVENT_STATE_CHANGE;
-		btnev.bev_event.bs_state = event;
-		strcpy(btnev.bev_event.bs_name, bev->bev_name);
-
-		rv = btn_queue_event(&btnev);
-		if (rv == 0) {
-			simple_unlock(&btn_event_queue_slock);
-			printf("%s: WARNING: state change event %d lost; "
-			    "queue full\n", bev->bev_name, btnev.bev_type);
-		} else {
-			if (btn_event_queue_flags & BEVQ_F_WAITING) {
-				btn_event_queue_flags &= ~BEVQ_F_WAITING;
-				simple_unlock(&btn_event_queue_slock);
-				wakeup(&btn_event_queue_count);
-			} else {
-				simple_unlock(&btn_event_queue_slock);
-			}
-			selnotify(&btn_event_queue_selinfo, 0, 0);
-		}
+	mutex_enter(&btn_event_queue_lock);
+	if (btn_daemon == NULL) {
+		mutex_exit(&btn_event_queue_lock);
+		printf("%s: btn_event_send can't handle me.\n", bev->bev_name);
 		return;
 	}
-	simple_unlock(&btn_event_queue_slock);
 
-	printf("%s: btn_event_send can't handle me.\n", bev->bev_name);
+	btnev.bev_type = BUTTON_EVENT_STATE_CHANGE;
+	btnev.bev_event.bs_state = event;
+	strcpy(btnev.bev_event.bs_name, bev->bev_name);
+
+	rv = btn_queue_event(&btnev);
+	if (rv == 0) {
+		mutex_exit(&btn_event_queue_lock);
+		printf("%s: WARNING: state change event %d lost; "
+		    "queue full\n", bev->bev_name, btnev.bev_type);
+		return;
+	}
+	if (btn_event_queue_flags & BEVQ_F_WAITING) {
+		btn_event_queue_flags &= ~BEVQ_F_WAITING;
+		cv_broadcast(&btn_event_queue_cv);
+	}
+	selnotify(&btn_event_queue_selinfo, 0, 0);
+	mutex_exit(&btn_event_queue_lock);
 }

Reply via email to