int dill_msleep(int64_t deadline) { /* Return ECANCELED if shutting down. */ int rc = dill_canblock(); if(dill_slow(rc < 0)) return -1; /* Actual waiting. */ struct dill_tmclause tmcl; dill_timer(&tmcl, 1, deadline); int id = dill_wait(); if(dill_slow(id < 0)) return -1; return 0; }
int dill_msleep(int64_t deadline, const char *where) { /* Return ECANCELED if shutting down. */ int rc = dill_canblock(); if(dill_slow(rc < 0)) return -1; /* Trivial case. No waiting, but we do want a context switch. */ if(dill_slow(deadline == 0)) return yield(); /* Actual waiting. */ struct dill_tmcl tmcl; if(deadline > 0) dill_timer(&tmcl, 1, deadline); int id = dill_wait(where); if(dill_slow(id < 0)) return -1; dill_assert(id == 1); return 0; }
int dill_fdout(int fd, int64_t deadline) { /* Return ECANCELED if shutting down. */ int rc = dill_canblock(); if(dill_slow(rc < 0)) return -1; /* Start waiting for the fd. */ struct dill_fdclause fdcl; rc = dill_pollset_out(&fdcl, 1, fd); if(dill_slow(rc < 0)) return -1; /* Optionally, start waiting for a timer. */ struct dill_tmclause tmcl; dill_timer(&tmcl, 2, deadline); /* Block. */ int id = dill_wait(); if(dill_slow(id < 0)) return -1; if(dill_slow(id == 2)) {errno = ETIMEDOUT; return -1;} return 0; }
int dill_bundle_wait(int h, int64_t deadline) { int rc = dill_canblock(); if(dill_slow(rc < 0)) return -1; struct dill_bundle *self = dill_hquery(h, dill_bundle_type); if(dill_slow(!self)) return -1; /* If there are no coroutines in the bundle succeed immediately. */ if(dill_list_empty(&self->crs)) return 0; /* Otherwise wait for all coroutines to finish. */ struct dill_clause cl; self->waiter = &cl; dill_waitfor(&cl, 0, NULL); struct dill_tmclause tmcl; dill_timer(&tmcl, 1, deadline); int id = dill_wait(); self->waiter = NULL; if(dill_slow(id < 0)) return -1; if(dill_slow(id == 1)) {errno = ETIMEDOUT; return -1;} dill_assert(id == 0); return 0; }
int dill_fdout(int fd, int64_t deadline, const char *where) { /* TODO: deadline == 0? */ /* Return ECANCELED if shutting down. */ int rc = dill_canblock(); if(dill_slow(rc < 0)) return -1; /* Start waiting for the fd. */ struct dill_clause fdcl; rc = dill_out(&fdcl, 1, fd); if(dill_slow(rc < 0)) return -1; /* Optionally, start waiting for a timer. */ struct dill_tmcl tmcl; if(deadline > 0) dill_timer(&tmcl, 2, deadline); /* Block. */ int id = dill_wait(where); if(dill_slow(id < 0)) return -1; if(dill_slow(id == 2)) {errno = ETIMEDOUT; return -1;} dill_assert(id == 1); return 0; }