static IOCtx _ioctx_incref (IOCtx ioctx) { xpthread_mutex_lock (&ioctx->lock); ioctx->refcount++; xpthread_mutex_unlock (&ioctx->lock); return ioctx; }
Path path_incref (Path path) { xpthread_mutex_lock (&path->lock); path->refcount++; xpthread_mutex_unlock (&path->lock); return path; }
static void _count_ioctx (IOCtx i, int *shared, int *unique) { for (*unique = *shared = 0; i != NULL; i = i->next) { (*unique)++; xpthread_mutex_lock (&i->lock); (*shared) += i->refcount; xpthread_mutex_unlock (&i->lock); } }
void np_user_incref(Npuser *u) { if (!u) return; xpthread_mutex_lock (&u->lock); u->refcount++; xpthread_mutex_unlock (&u->lock); }
static void np_respond(Nptpool *tp, Npreq *req, Npfcall *rc) { Npreq *freq; xpthread_mutex_lock(&req->lock); if (req->responded) { free(rc); xpthread_mutex_unlock(&req->lock); np_req_unref(req); return; } req->responded = 1; xpthread_mutex_unlock(&req->lock); xpthread_mutex_lock(&tp->lock); np_srv_remove_workreq(tp, req); for(freq = req->flushreq; freq != NULL; freq = freq->flushreq) np_srv_remove_workreq(tp, freq); xpthread_mutex_unlock(&tp->lock); xpthread_mutex_lock(&req->lock); req->rcall = rc; if (req->rcall) { np_set_tag(req->rcall, req->tag); if (req->fid != NULL) { np_fid_decref(req->fid); req->fid = NULL; } np_conn_respond(req); } for(freq = req->flushreq; freq != NULL; freq = freq->flushreq) { xpthread_mutex_lock(&freq->lock); freq->rcall = np_create_rflush(); np_set_tag(freq->rcall, freq->tag); np_conn_respond(freq); xpthread_mutex_unlock(&freq->lock); np_req_unref(freq); } xpthread_mutex_unlock(&req->lock); np_req_unref(req); }
static int _get_one_file (Path path, char *s, DynStr *ds) { int unique, shared; xpthread_mutex_lock (&path->lock); _count_ioctx (path->ioctx, &shared, &unique); aspf (&ds->s, &ds->len, "%d %d %d %s\n", path->refcount, shared, unique, s); xpthread_mutex_unlock (&path->lock); return 0; }
static int next_inum(void) { static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static int i = 1; int ret; xpthread_mutex_lock (&lock); ret = i++; xpthread_mutex_unlock (&lock); return ret; }
static int _ioctx_decref (IOCtx ioctx) { int n; xpthread_mutex_lock (&ioctx->lock); n = --ioctx->refcount; xpthread_mutex_unlock (&ioctx->lock); return n; }
/* Clear all state associated with conn out of the srv. * No more I/O is possible; we have disassociated the trans from the conn. */ static void np_conn_reset(Npconn *conn) { int reqslen; Npsrv *srv; Npreq *preqs, **reqs; xpthread_mutex_lock(&conn->lock); conn->resetting = 1; xpthread_mutex_unlock(&conn->lock); xpthread_mutex_lock(&conn->srv->lock); srv = conn->srv; preqs = _get_waiting_reqs (conn); if (_get_working_reqs (conn, &reqs, &reqslen) < 0) { xpthread_mutex_unlock(&conn->srv->lock); goto error; } xpthread_mutex_unlock(&conn->srv->lock); _flush_waiting_reqs (preqs); _flush_working_reqs (reqs, reqslen); xpthread_mutex_lock(&srv->lock); while (_count_working_reqs (conn, 1) > 0) xpthread_cond_wait(&conn->resetcond, &srv->lock); xpthread_mutex_unlock(&srv->lock); xpthread_mutex_lock(&conn->lock); if (conn->fidpool) { np_fidpool_destroy(conn->fidpool); conn->fidpool = NULL; } conn->resetting = 0; xpthread_mutex_unlock(&conn->lock); _free_working_reqs (reqs, reqslen); return; error: return; }
/* refcount++ */ Npfid * np_fid_incref (Npfid *f) { NP_ASSERT(f != NULL); NP_ASSERT(f->magic == FID_MAGIC); xpthread_mutex_lock (&f->lock); f->refcount++; xpthread_mutex_unlock (&f->lock); return f; }
static void np_respond(Nptpool *tp, Npreq *req, Npfcall *rc) { xpthread_mutex_lock(&tp->srv->lock); np_srv_remove_workreq(tp, req); xpthread_mutex_unlock(&tp->srv->lock); xpthread_mutex_lock(&req->lock); req->rcall = rc; if (req->rcall) { np_set_tag(req->rcall, req->tag); if (req->fid != NULL) { np_fid_decref(req->fid); req->fid = NULL; } np_conn_respond(req); } xpthread_mutex_unlock(&req->lock); np_req_unref(req); }
void np_usercache_flush (Npsrv *srv) { Npusercache *uc = srv->usercache; Npuser *u; xpthread_mutex_lock (&uc->lock); u = uc->users; while (u) u = _usercache_del (srv, NULL, u); xpthread_mutex_unlock (&uc->lock); }
/* increment nonce and return new value */ uint32_t nonce32(void) { #ifdef HAVE_ATOMIC_H return atomic_add_32_nv(&seq, 2); #else xpthread_mutex_lock(&seq_mutex); seq += 2; xpthread_mutex_unlock(&seq_mutex); return seq; #endif /* else !HAVE_ATOMIC_H */ }
void np_fid_decref_bynum (Npconn *conn, u32 fid) { Npfidpool *pool = conn->fidpool; int hash = fid % pool->size; int refcount = 0; Npfid *f; xpthread_mutex_lock (&pool->lock); if ((f = _lookup_fid (&pool->htable[hash], fid))) { xpthread_mutex_lock (&f->lock); refcount = --f->refcount; xpthread_mutex_unlock (&f->lock); if (refcount == 0) { _unlink_fid (&pool->htable[hash], f); } } xpthread_mutex_unlock (&pool->lock); if (f && refcount == 0) (void) _destroy_fid (f); }
int np_srv_add_conn(Npsrv *srv, Npconn *conn) { xpthread_mutex_lock(&srv->lock); conn->srv = srv; conn->next = srv->conns; srv->conns = conn; srv->conncount++; srv->connhistory++; xpthread_cond_signal(&srv->conncountcond); xpthread_mutex_unlock(&srv->lock); return 1; }
/* Find a fid, then refcount++ */ Npfid * np_fid_find (Npconn *conn, u32 fid) { Npfidpool *pool = conn->fidpool; int hash = fid % pool->size; Npfid *f; xpthread_mutex_lock (&pool->lock); if ((f = _lookup_fid (&pool->htable[hash], fid))) np_fid_incref (f); xpthread_mutex_unlock (&pool->lock); return f; }
static char * _ctl_get_tpools (void *a) { Npsrv *srv = (Npsrv *)a; Nptpool *tp; Npreq *req; char *s = NULL; int n, len = 0; xpthread_mutex_lock(&srv->lock); for (tp = srv->tpool; tp != NULL; tp = tp->next) { xpthread_mutex_lock(&tp->lock); xpthread_mutex_lock(&tp->stats.lock); tp->stats.name = tp->name; tp->stats.numfids = tp->refcount; tp->stats.numreqs = 0; for (req = tp->reqs_first; req != NULL; req = req->next) tp->stats.numreqs++; for (req = tp->workreqs; req != NULL; req = req->next) tp->stats.numreqs++; n = np_encode_tpools_str (&s, &len, &tp->stats); xpthread_mutex_unlock(&tp->stats.lock); xpthread_mutex_unlock(&tp->lock); if (n < 0) { np_uerror (ENOMEM); goto error_unlock; } } xpthread_mutex_unlock(&srv->lock); return s; error_unlock: xpthread_mutex_unlock(&srv->lock); if (s) free(s); return NULL; }
Npuser * np_uname2user (Npsrv *srv, char *uname) { Npusercache *uc = srv->usercache; Npuser *u = NULL; xpthread_mutex_lock (&uc->lock); if (!(u = _usercache_lookup (srv, uname, P9_NONUNAME))) if ((u = _real_lookup_byname (srv, uname))) _usercache_add (srv, u); xpthread_mutex_unlock (&uc->lock); if (u) np_user_incref (u); return u; }
Npuser * np_uid2user (Npsrv *srv, uid_t uid) { Npusercache *uc = srv->usercache; Npuser *u = NULL; xpthread_mutex_lock (&uc->lock); if (!(u = _usercache_lookup (srv, NULL, uid))) if ((u = _real_lookup_byuid (srv, uid))) _usercache_add (srv, u); xpthread_mutex_unlock (&uc->lock); if (u) np_user_incref (u); return u; }
void np_conn_respond(Npreq *req) { int n; Npconn *conn = req->conn; Npsrv *srv = conn->srv; Npfcall *rc = req->rcall; _debug_trace (srv, rc); xpthread_mutex_lock(&conn->wlock); n = np_trans_send(conn->trans, rc); xpthread_mutex_unlock(&conn->wlock); if (n < 0) np_logerr (srv, "send to '%s'", conn->client_id); }
void np_user_decref(Npuser *u) { int n; if (!u) return; xpthread_mutex_lock (&u->lock); n = --u->refcount; xpthread_mutex_unlock (&u->lock); if (n > 0) return; _free_user (u); }
int np_fidpool_count(Npfidpool *pool) { int i; Npfid *f; int count = 0; xpthread_mutex_lock(&pool->lock); for(i = 0; i < pool->size; i++) { for (f = pool->htable[i]; f != NULL; f = f->next) { NP_ASSERT(f->magic == FID_MAGIC); count++; } } xpthread_mutex_unlock(&pool->lock); return count; }
int np_srv_add_conn(Npsrv *srv, Npconn *conn) { int ret; ret = 0; xpthread_mutex_lock(&srv->lock); np_conn_incref(conn); conn->srv = srv; conn->next = srv->conns; srv->conns = conn; ret = 1; srv->conncount++; srv->connhistory++; xpthread_cond_signal(&srv->conncountcond); xpthread_mutex_unlock(&srv->lock); return ret; }
void np_srv_add_req(Npsrv *srv, Npreq *req) { Nptpool *tp = NULL; if (req->fid) tp = req->fid->tpool; if (!tp) tp = srv->tpool; xpthread_mutex_lock(&tp->lock); req->prev = tp->reqs_last; if (tp->reqs_last) tp->reqs_last->next = req; tp->reqs_last = req; if (!tp->reqs_first) tp->reqs_first = req; xpthread_mutex_unlock(&tp->lock); xpthread_cond_signal(&tp->reqcond); }
static int npc_rpc(Npcfsys *fs, Npfcall *tc, Npfcall **rcp) { Npfcall *rc = NULL; u16 tag = P9_NOTAG; int n, ret = -1; if (!fs->trans) { np_uerror(ECONNABORTED); goto done; } if (tc->type != P9_TVERSION) tag = npc_get_id(fs->tagpool); np_set_tag(tc, tag); xpthread_mutex_lock(&fs->lock); n = np_trans_send (fs->trans, tc); if (n >= 0) n = np_trans_recv(fs->trans, &rc, fs->msize); xpthread_mutex_unlock(&fs->lock); if (n < 0) goto done; if (rc == NULL) { np_uerror (EPROTO); /* premature EOF */ goto done; } if (tc->tag != rc->tag) { np_uerror (EPROTO); /* unmatched response */ goto done; } if (rc->type == P9_RLERROR) { np_uerror (rc->u.rlerror.ecode); goto done; } *rcp = rc; ret = 0; done: if (tag != P9_NOTAG) npc_put_id(fs->tagpool, tag); if (ret < 0 && rc != NULL) free (rc); return ret; }
int ioctx_close (Npfid *fid, int seterrno) { Fid *f = fid->aux; int n; int rc = 0; NP_ASSERT (f->ioctx != NULL); xpthread_mutex_lock (&f->path->lock); n = _ioctx_decref (f->ioctx); if (n == 0) _unlink_ioctx (&f->path->ioctx, f->ioctx); xpthread_mutex_unlock (&f->path->lock); if (n == 0) rc = _ioctx_close_destroy (f->ioctx, seterrno); f->ioctx = NULL; return rc; }
void np_conn_decref(Npconn *conn) { xpthread_mutex_lock(&conn->lock); assert(conn->refcount > 0); conn->refcount--; if (conn->refcount) { xpthread_mutex_unlock(&conn->lock); return; } if (conn->fidpool) { np_fidpool_destroy(conn->fidpool); conn->fidpool = NULL; } xpthread_mutex_unlock(&conn->lock); pthread_mutex_destroy(&conn->lock); pthread_cond_destroy(&conn->resetcond); free(conn); }
int np_fidpool_destroy(Npfidpool *pool) { int i; Npfid *f; int unclunked = 0; xpthread_mutex_lock(&pool->lock); for(i = 0; i < pool->size; i++) { f = pool->htable[i]; while (f != NULL) { f = _destroy_fid (f); unclunked++; } } xpthread_mutex_unlock (&pool->lock); pthread_mutex_destroy (&pool->lock); free(pool); return unclunked; }
u32 npc_get_id(Npcpool *p) { int i, n; u32 ret; u8 *pt; xpthread_mutex_lock(&p->lock); again: for(i = 0; i < p->msize; i++) if (p->map[i] != 0xFF) break; if (i>=p->msize && p->msize*8<p->maxid) { n = p->msize + 32; if (n*8 > p->maxid) n = p->maxid/8 + 1; pt = realloc(p->map, n); if (pt) { memset(pt + p->msize, 0, n - p->msize); p->map = pt; i = p->msize; p->msize = n; } } if (i >= p->msize) { pthread_cond_wait(&p->cond, &p->lock); goto again; } ret = m2id[p->map[i]]; p->map[i] |= 1 << ret; ret += i * 8; xpthread_mutex_unlock(&p->lock); return ret; }
void np_tpool_select (Npreq *req) { Npsrv *srv = req->conn->srv; Nptpool *tp = NULL; NP_ASSERT (srv->tpool != NULL); if (!req->fid || req->fid->tpool) return; xpthread_mutex_lock (&srv->lock); if ((srv->flags & SRV_FLAGS_TPOOL_SINGLE) || !req->fid->aname || *req->fid->aname != '/') { tp = srv->tpool; } if (!tp) { for (tp = srv->tpool; tp != NULL; tp = tp->next) { if (!strcmp (req->fid->aname, tp->name)) break; } } if (!tp) { tp = np_tpool_create(srv, req->fid->aname); if (tp) { NP_ASSERT (srv->tpool); /* default tpool */ tp->next = srv->tpool->next; srv->tpool->next = tp; } else np_logerr (srv, "np_tpool_create %s", req->fid->aname); } if (tp) { np_tpool_incref (tp); req->fid->tpool = tp; } xpthread_mutex_unlock (&srv->lock); }