diff --git a/src/Mutex.php b/src/Mutex.php new file mode 100644 index 0000000..7c6a4f2 --- /dev/null +++ b/src/Mutex.php @@ -0,0 +1,45 @@ +lock_name = $lock_name; + } + + public function lock( + float $timeout = INF /* microseconds */ + ): bool { + $timepass = 0; + + while ($timepass <= $timeout) { + $mkdir = @mkdir("/dev/shm/{$this->lock_name}"); + + if ($mkdir) { + return true; + } + + $timepass += 100000; + + usleep(100000); // check every 0.1s + } + + // throw exception here because lock was expected to success + // client api should not have to check and handle this + throw new \Exception('PU2991: unable to get lock'); + } + + public function unlock(): void + { + $rmdir = rmdir("/dev/shm/{$this->lock_name}"); + + if (! $rmdir) { + throw new \Exception('PU2992: unable unlock'); + } + } +} diff --git a/tests/MutexTest.php b/tests/MutexTest.php new file mode 100644 index 0000000..837c2d5 --- /dev/null +++ b/tests/MutexTest.php @@ -0,0 +1,23 @@ +assertFalse(file_exists('/dev/shm/'.$lock_name)); + + $mutex = new Mutex($lock_name); + $mutex->lock(0); + + $this->assertTrue(file_exists('/dev/shm/'.$lock_name)); + + $mutex->unlock(); + + $this->assertFalse(file_exists('/dev/shm/'.$lock_name)); + } +}