Module Name:    src
Committed By:   pooka
Date:           Sun Feb  6 18:25:49 UTC 2011

Modified Files:
        src/lib/librumpuser: rumpuser_sp.c

Log Message:
Fix a race condition in the worker thread caching logic: if we got
two or more syscall requests before any worker thread ran, we might
not have enough threads to handle the requests.  In some scenarios
this could lead to a deadlock.


To generate a diff of this commit:
cvs rdiff -u -r1.38 -r1.39 src/lib/librumpuser/rumpuser_sp.c

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

Modified files:

Index: src/lib/librumpuser/rumpuser_sp.c
diff -u src/lib/librumpuser/rumpuser_sp.c:1.38 src/lib/librumpuser/rumpuser_sp.c:1.39
--- src/lib/librumpuser/rumpuser_sp.c:1.38	Fri Jan 28 19:21:28 2011
+++ src/lib/librumpuser/rumpuser_sp.c	Sun Feb  6 18:25:48 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpuser_sp.c,v 1.38 2011/01/28 19:21:28 pooka Exp $	*/
+/*      $NetBSD: rumpuser_sp.c,v 1.39 2011/02/06 18:25:48 pooka Exp $	*/
 
 /*
  * Copyright (c) 2010, 2011 Antti Kantee.  All Rights Reserved.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: rumpuser_sp.c,v 1.38 2011/01/28 19:21:28 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_sp.c,v 1.39 2011/02/06 18:25:48 pooka Exp $");
 
 #include <sys/types.h>
 #include <sys/atomic.h>
@@ -615,19 +615,18 @@
 
 	for (;;) {
 		pthread_mutex_lock(&sbamtx);
-		if (idleworker >= rumpsp_idleworker) {
+		if (__predict_false(idleworker >= rumpsp_idleworker)) {
 			nworker--;
 			pthread_mutex_unlock(&sbamtx);
 			break;
 		}
-		idleworker++;
-		while (TAILQ_EMPTY(&syslist)) {
+		if (TAILQ_EMPTY(&syslist))
+			idleworker++;
+		while (TAILQ_EMPTY(&syslist))
 			pthread_cond_wait(&sbacv, &sbamtx);
-		}
 
 		sba = TAILQ_FIRST(&syslist);
 		TAILQ_REMOVE(&syslist, sba, sba_entries);
-		idleworker--;
 		pthread_mutex_unlock(&sbamtx);
 
 		serv_handlesyscall(sba->sba_spc,
@@ -952,6 +951,7 @@
 	if (idleworker > 0) {
 		/* do we have a daemon's tool (i.e. idle threads)? */
 		pthread_cond_signal(&sbacv);
+		idleworker--;
 	} else if (nworker < rumpsp_maxworker) {
 		/*
 		 * Else, need to create one
@@ -959,8 +959,9 @@
 		 * worker to pick up the syscall)
 		 */
 		if (pthread_create(&pt, &pattr_detached,
-		    serv_syscallbouncer, NULL) == 0)
+		    serv_syscallbouncer, NULL) == 0) {
 			nworker++;
+		}
 	}
 	pthread_mutex_unlock(&sbamtx);
 }

Reply via email to