static int docvwait(kcondvar_t *cv, kmutex_t *mtx, struct timespec *ts) { struct lwp *l = curlwp; int rv; if (__predict_false(l->l_flag & LW_RUMP_QEXIT)) { /* * yield() here, someone might want the cpu * to set a condition. otherwise we'll just * loop forever. */ yield(); return EINTR; } UNLOCKED(mtx, false); l->l_private = cv; rv = 0; if (ts) { if (rumpuser_cv_timedwait(RUMPCV(cv), RUMPMTX(mtx), ts->tv_sec, ts->tv_nsec)) rv = EWOULDBLOCK; } else { rumpuser_cv_wait(RUMPCV(cv), RUMPMTX(mtx)); } LOCKED(mtx, false); /* * Check for QEXIT. if so, we need to wait here until we * are allowed to exit. */ if (__predict_false(l->l_flag & LW_RUMP_QEXIT)) { struct proc *p = l->l_proc; UNLOCKED(mtx, false); mutex_exit(mtx); /* drop and retake later */ mutex_enter(p->p_lock); while ((p->p_sflag & PS_RUMP_LWPEXIT) == 0) { /* avoid recursion */ rumpuser_cv_wait(RUMPCV(&p->p_waitcv), RUMPMTX(p->p_lock)); } KASSERT(p->p_sflag & PS_RUMP_LWPEXIT); mutex_exit(p->p_lock); /* ok, we can exit and remove "reference" to l->private */ mutex_enter(mtx); LOCKED(mtx, false); rv = EINTR; } l->l_private = NULL; return rv; }
void mutex_exit(kmutex_t *mtx) { UNLOCKED(mtx, false); rumpuser_mutex_exit(RUMPMTX(mtx)); }
void rw_downgrade(krwlock_t *rw) { rumpuser_rw_downgrade(RUMPRW(rw)); UNLOCKED(rw, 0); WANTLOCK(rw, 1); LOCKED(rw, 1); }
static void bufferevent_run_deferred_callbacks_unlocked(struct deferred_cb *_, void *arg) { struct bufferevent_private *bufev_private = arg; struct bufferevent *bufev = &bufev_private->bev; BEV_LOCK(bufev); #define UNLOCKED(stmt) \ do { BEV_UNLOCK(bufev); stmt; BEV_LOCK(bufev); } while(0) if ((bufev_private->eventcb_pending & BEV_EVENT_CONNECTED) && bufev->errorcb) { /* The "connected" happened before any reads or writes, so send it first. */ bufferevent_event_cb errorcb = bufev->errorcb; void *cbarg = bufev->cbarg; bufev_private->eventcb_pending &= ~BEV_EVENT_CONNECTED; UNLOCKED(errorcb(bufev, BEV_EVENT_CONNECTED, cbarg)); } if (bufev_private->readcb_pending && bufev->readcb) { bufferevent_data_cb readcb = bufev->readcb; void *cbarg = bufev->cbarg; bufev_private->readcb_pending = 0; UNLOCKED(readcb(bufev, cbarg)); } if (bufev_private->writecb_pending && bufev->writecb) { bufferevent_data_cb writecb = bufev->writecb; void *cbarg = bufev->cbarg; bufev_private->writecb_pending = 0; UNLOCKED(writecb(bufev, cbarg)); } if (bufev_private->eventcb_pending && bufev->errorcb) { bufferevent_event_cb errorcb = bufev->errorcb; void *cbarg = bufev->cbarg; short what = bufev_private->eventcb_pending; int err = bufev_private->errno_pending; bufev_private->eventcb_pending = 0; bufev_private->errno_pending = 0; EVUTIL_SET_SOCKET_ERROR(err); UNLOCKED(errorcb(bufev,what,cbarg)); } _bufferevent_decref_and_unlock(bufev); #undef UNLOCKED }
int rw_tryupgrade(krwlock_t *rw) { int rv; rv = rumpuser_rw_tryupgrade(RUMPRW(rw)); if (rv == 0) { UNLOCKED(rw, 1); WANTLOCK(rw, 0); LOCKED(rw, 0); } return rv == 0; }
void rw_exit(krwlock_t *rw) { #ifdef LOCKDEBUG bool shared = !rw_write_held(rw); if (shared) KASSERT(rw_read_held(rw)); UNLOCKED(rw, shared); #endif rumpuser_rw_exit(RUMPRW(rw)); }