bool AntiSem::wait(MSec timeout) { if( begin_wait() ) return true; if( sem.take(timeout) ) return true; for(;;) { if( end_wait() ) return false; if( sem.take(1_msec) ) return true; // unprobable case : repeat } }
static void ioq_cb(struct ioq_fd *f) { struct afile *a = (struct afile *)f; syserr_t error; int perform = end_wait(a, &error); /* Perform actions */ if (perform & F_WANT_READ) { if (perform & F_WANT_CANCEL) { a->read.size = 0; a->read.error = error; } else { int r = read(a->fd.fd, a->read.buffer, a->read.size); if (r < 0) { a->read.size = 0; a->read.error = syserr_last(); } else { a->read.size = r; a->read.error = SYSERR_NONE; } } a->read.func(a); } if (perform & F_WANT_WRITE) { if (perform & F_WANT_CANCEL) { a->write.size = 0; a->write.error = error; } else { int r = write(a->fd.fd, a->write.buffer, a->write.size); if (r < 0) { a->read.size = 0; a->read.error = syserr_last(); } else { a->read.size = r; a->read.error = SYSERR_NONE; } } a->write.func(a); } }
NTSTATUS thread_impl_t::wait_on_handles( ULONG count, PHANDLE handles, WAIT_TYPE type, BOOLEAN alert, PLARGE_INTEGER timeout) { NTSTATUS r = STATUS_SUCCESS; Alertable = alert; WaitType = type; // iterate the array and wait on each handle for (ULONG i=0; i<count; i++) { dprintf("handle[%ld] = %08lx\n", i, (ULONG) handles[i]); object_t *any = 0; r = object_from_handle( any, handles[i], SYNCHRONIZE ); if (r < STATUS_SUCCESS) { end_wait(); return r; } sync_object_t *obj = dynamic_cast<sync_object_t*>( any ); if (!obj) { end_wait(); return STATUS_INVALID_HANDLE; } r = wait_on( obj ); if (r < STATUS_SUCCESS) { end_wait(); return r; } } // make sure we wait for a little bit every time LARGE_INTEGER t; if (timeout && timeout->QuadPart <= 0 && timeout->QuadPart> -100000LL) { t.QuadPart = -100000LL; timeout = &t; } set_timeout( timeout ); while (1) { r = check_wait(); if (r != STATUS_PENDING) break; if (alerted) { alerted = FALSE; r = STATUS_ALERTED; break; } if (timeout && has_expired()) { r = STATUS_TIMEOUT; break; } in_wait = TRUE; wait(); assert( in_wait == FALSE ); } end_wait(); set_timeout( 0 ); return r; }