--- rpc/svc.c.sav 2015-11-15 18:49:51.101297000 -0500 +++ rpc/svc.c 2015-11-16 20:16:19.698413000 -0500 @@ -1129,6 +1129,7 @@ svc_run_internal(SVCGROUP *grp, bool_t i if (grp->sg_state == SVCPOOL_THREADWANTED) { grp->sg_state = SVCPOOL_THREADSTARTING; grp->sg_lastcreatetime = time_uptime; + grp->sg_threadcount++; mtx_unlock(&grp->sg_lock); svc_new_thread(grp); mtx_lock(&grp->sg_lock); @@ -1303,7 +1304,6 @@ svc_new_thread(SVCGROUP *grp) SVCPOOL *pool = grp->sg_pool; struct thread *td; - grp->sg_threadcount++; kthread_add(svc_thread_start, grp, pool->sp_proc, &td, 0, 0, "%s: service", pool->sp_name); } @@ -1338,10 +1338,21 @@ svc_run(SVCPOOL *pool) /* Starting threads */ for (g = 0; g < pool->sp_groupcount; g++) { grp = &pool->sp_groups[g]; - for (i = ((g == 0) ? 1 : 0); i < grp->sg_minthreads; i++) + for (i = ((g == 0) ? 1 : 0); i < grp->sg_minthreads; i++) { + /* + * Although this code is single threaded, acquire + * the mutex, since svc_new_thread() will create + * threads that are manipulating sg_threadcount. + */ + mtx_lock(&grp->sg_lock); + grp->sg_threadcount++; + mtx_unlock(&grp->sg_lock); svc_new_thread(grp); + } } + mtx_lock(&pool->sp_groups[0].sg_lock); pool->sp_groups[0].sg_threadcount++; + mtx_unlock(&pool->sp_groups[0].sg_lock); svc_run_internal(&pool->sp_groups[0], TRUE); /* Waiting for threads to stop. */