public function acquire() : \Generator
{
do {
// Attempt to acquire a lock from the semaphore.
if (@msg_receive($this->queue, 0, $type, 1, $chr, false, MSG_IPC_NOWAIT, $errno)) {
// A free lock was found, so resolve with a lock object that can
// be used to release the lock.
return new Lock(function (Lock $lock) {
$this->release();
});
}
// Check for unusual errors.
if ($errno !== MSG_ENOMSG) {
throw new SemaphoreException('Failed to acquire a lock.');
}
} while (yield from Coroutine\sleep(self::LATENCY_TIMEOUT));
}