static void np_tpool_destroy(Nptpool *tp) { Npsrv *srv = tp->srv; Npwthread *wt, *next; void *retval; int err, i; for(wt = tp->wthreads; wt != NULL; wt = wt->next) { wt->shutdown = 1; } xpthread_cond_broadcast(&tp->reqcond); for (i = 0, wt = tp->wthreads; wt != NULL; wt = next, i++) { next = wt->next; if ((err = pthread_join (wt->thread, &retval))) { np_uerror (err); np_logerr(srv, "%s: join thread %d", tp->name, i); } else if (retval == PTHREAD_CANCELED) { np_logmsg(srv, "%s: join thread %d: cancelled", tp->name, i); } else if (retval != NULL) { np_logmsg(srv, "%s: join thread %d: non-NULL return", tp->name, i); } free (wt); } pthread_cond_destroy (&tp->reqcond); pthread_mutex_destroy (&tp->lock); if (tp->name) free (tp->name); free (tp); }
/* Called by srv workers to transmit req->rcall->pkt. */ void np_conn_respond(Npreq *req) { int n, send; Npconn *conn = req->conn; Npsrv *srv = conn->srv; Npfcall *rc = req->rcall; Nptrans *trans = NULL; if (!rc) goto done; xpthread_mutex_lock(&conn->lock); send = conn->trans && !conn->resetting; xpthread_mutex_unlock(&conn->lock); if (send) { if ((srv->flags & SRV_FLAGS_DEBUG_9PTRACE)) _debug_trace (srv, rc); xpthread_mutex_lock(&conn->wlock); n = np_trans_write(conn->trans, rc->pkt, rc->size); conn->reqs_out++; xpthread_mutex_unlock(&conn->wlock); if (n <= 0) { /* write error */ xpthread_mutex_lock(&conn->lock); trans = conn->trans; conn->trans = NULL; xpthread_mutex_unlock(&conn->lock); } } done: _free_npfcall(req->tcall); free(req->rcall); req->tcall = NULL; req->rcall = NULL; if (conn->resetting) { xpthread_mutex_lock(&conn->srv->lock); xpthread_cond_broadcast(&conn->resetcond); xpthread_mutex_unlock(&conn->srv->lock); } if (trans) /* np_conn_read_proc will take care of resetting */ np_trans_destroy(trans); }