-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
172 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
|
||
namespace Amp\Sync\Internal; | ||
|
||
use Amp\Delayed; | ||
use Amp\Promise; | ||
use Amp\Sync\Lock; | ||
use function Amp\call; | ||
|
||
class MutexStorage extends \Threaded { | ||
const LATENCY_TIMEOUT = 10; | ||
|
||
/** @var bool */ | ||
private $locked = false; | ||
|
||
/** | ||
* @return \Amp\Promise | ||
*/ | ||
public function acquire(): Promise { | ||
return call(function () { | ||
$tsl = function () { | ||
if ($this->locked) { | ||
return true; | ||
} | ||
|
||
$this->locked = true; | ||
return false; | ||
}; | ||
|
||
while ($this->locked || $this->synchronized($tsl)) { | ||
yield new Delayed(self::LATENCY_TIMEOUT); | ||
} | ||
|
||
return new Lock(0, function () { | ||
$this->locked = false; | ||
}); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
|
||
namespace Amp\Sync\Internal; | ||
|
||
use Amp\Delayed; | ||
use Amp\Promise; | ||
use Amp\Sync\Lock; | ||
use function Amp\call; | ||
|
||
class SemaphoreStorage extends \Threaded { | ||
const LATENCY_TIMEOUT = 10; | ||
|
||
/** | ||
* Creates a new semaphore with a given number of locks. | ||
* | ||
* @param int $locks The maximum number of locks that can be acquired from the semaphore. | ||
*/ | ||
public function __construct(int $locks) { | ||
foreach (\range(0, $locks - 1) as $lock) { | ||
$this[] = $lock; | ||
} | ||
} | ||
|
||
/** | ||
* @return \Amp\Promise | ||
*/ | ||
public function acquire(): Promise { | ||
/** | ||
* 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. | ||
*/ | ||
return call(function () { | ||
$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->count()) { | ||
return null; | ||
} | ||
|
||
return $this->shift(); | ||
}; | ||
|
||
while (!$this->count() || ($id = $this->synchronized($tsl)) === null) { | ||
yield new Delayed(self::LATENCY_TIMEOUT); | ||
} | ||
|
||
return new Lock($id, function (Lock $lock) { | ||
$id = $lock->getId(); | ||
$this->synchronized(function () use ($id) { | ||
$this[] = $id; | ||
}); | ||
}); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters