Example #1
0
 /**
  * Attempts to acquire the lock and sleeps for a time if the lock could not be acquired.
  *
  * @return \Generator
  */
 public function acquire() : \Generator
 {
     $tsl = function () {
         return $this->lock ? $this->lock = false : true;
     };
     while (!$this->lock || $this->synchronized($tsl)) {
         yield from Coroutine\sleep(self::LATENCY_TIMEOUT);
     }
     return new Lock(function () {
         $this->release();
     });
 }
Example #2
0
 /**
  * {@inheritdoc}
  */
 public function acquire() : \Generator
 {
     // Try to create the lock file. If the file already exists, someone else
     // has the lock, so set an asynchronous timer and try again.
     while (($handle = @fopen($this->fileName, 'x')) === false) {
         yield from Coroutine\sleep(self::LATENCY_TIMEOUT);
     }
     // Return a lock object that can be used to release the lock on the mutex.
     $lock = new Lock(function (Lock $lock) {
         $this->release();
     });
     fclose($handle);
     return $lock;
 }
Example #3
0
 /**
  * Uses a double locking mechanism to acquire a lock without blocking. A
  * synchronous mutex is used to make sure that the semaphore is queried one
  * at a time to preserve the integrity of the semaphore itself. Then a lock
  * count is used to check if a lock is available without blocking.
  *
  * If a lock is not available, we add the request to a queue and set a timer
  * to check again in the future.
  */
 public function acquire() : \Generator
 {
     $tsl = function () {
         // If there are no locks available or the wait queue is not empty,
         // we need to wait our turn to acquire a lock.
         if ($this->locks > 0) {
             --$this->locks;
             return false;
         }
         return true;
     };
     while ($this->locks < 1 || $this->synchronized($tsl)) {
         yield from Coroutine\sleep(self::LATENCY_TIMEOUT);
     }
     return new Lock(function () {
         $this->release();
     });
 }
Example #4
0
    /**
     * {@inheritdoc}
     */
    public function acquire()
    {
        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.
                yield new Lock(function (Lock $lock) {
                    $this->release();
                });
                return;
            }

            // Check for unusual errors.
            if ($errno !== MSG_ENOMSG) {
                throw new SemaphoreException('Failed to acquire a lock.');
            }
        } while (yield Coroutine\sleep(self::LATENCY_TIMEOUT));
    }
Example #5
0
});

Coroutine\create(function () {
    // Create a new child thread that does some blocking stuff.
    $context = Thread::spawn(function () {
        printf("\$this: %s\n", get_class($this));

        printf("Received the following from parent: %s\n", (yield $this->receive()));

        print "Sleeping for 3 seconds...\n";
        sleep(3); // Blocking call in thread.

        yield $this->send('Data sent from child.');

        print "Sleeping for 2 seconds...\n";
        sleep(2); // Blocking call in thread.

        yield 42;
    });

    print "Waiting 2 seconds to send start data...\n";
    yield Coroutine\sleep(2);

    yield $context->send('Start data');

    printf("Received the following from child: %s\n", (yield $context->receive()));
    printf("Thread ended with value %d!\n", (yield $context->join()));
})->cleanup([$timer, 'stop'])->done();

Loop\run();