From 426c1a650c4b626200c9aa0d5ead45ac5396862c Mon Sep 17 00:00:00 2001 From: Petr Levtonov Date: Sat, 1 Feb 2020 23:50:11 +0100 Subject: [PATCH 1/2] #10: Properly detach from and cleanup shared memory --- CHANGELOG.md | 4 ++++ src/Spork/Fork.php | 10 ++++++++++ src/Spork/ProcessManager.php | 6 +++++- src/Spork/SharedMemory.php | 29 +++++++++++++++++++++++++---- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27f5c88..007da25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +# Fixed + +- #10: Properly detach from and cleanup shared memory. + ## [2.0.0] - 2019-11-29 ### Changed diff --git a/src/Spork/Fork.php b/src/Spork/Fork.php index fcb22ed..d132af4 100644 --- a/src/Spork/Fork.php +++ b/src/Spork/Fork.php @@ -36,6 +36,16 @@ public function __construct($pid, SharedMemory $shm, $debug = false) $this->name = ''; } + /** + * Clean up shared memory when not needed any longer. + * + * @return void + */ + public function cleanupSharedMemory(): void + { + $this->shm->cleanup(); + } + /** * Assign a name to the current fork (useful for debugging). */ diff --git a/src/Spork/ProcessManager.php b/src/Spork/ProcessManager.php index b7190d8..117237f 100644 --- a/src/Spork/ProcessManager.php +++ b/src/Spork/ProcessManager.php @@ -53,6 +53,10 @@ public function __destruct() if (!$this->zombieOkay) { $this->wait(); } + + foreach ($this->forks as $fork) { + $fork->cleanupSharedMemory(); + } } public function getEventDispatcher() @@ -97,7 +101,6 @@ public function fork($callable) } if (0 === $pid) { - $currPid = posix_getpid(); // reset the list of child processes $this->forks = []; @@ -106,6 +109,7 @@ public function fork($callable) $message = new ExitMessage(); // phone home on shutdown + $currPid = posix_getpid(); register_shutdown_function(function () use ($currPid, $shm, $message): void { // Do not execute this function in child processes. if ($currPid !== posix_getpid()) { diff --git a/src/Spork/SharedMemory.php b/src/Spork/SharedMemory.php index d8ab150..6414def 100644 --- a/src/Spork/SharedMemory.php +++ b/src/Spork/SharedMemory.php @@ -48,6 +48,21 @@ public function __construct($pid = null, $signal = null) $this->signal = $signal; } + /** + * Clean up shared memory when not needed any longer. + * + * @return void + */ + public function cleanup(): void + { + if (false === ($shmId = @shmop_open($this->pid, 'a', 0, 0))) { + return; + } + + shmop_delete($shmId); + shmop_close($shmId); + } + /** * Reads all messages from shared memory. * @@ -62,18 +77,21 @@ public function receive() /** @var string|false $sharedMemory */ $sharedMemory = shmop_read($shmId, 0, 0); if (false === $sharedMemory) { + shmop_close($shmId); + throw new ProcessControlException(sprintf( 'Not able to read from shared memory segment for PID: %d', $this->pid )); - } + } elseif (false === shmop_delete($shmId)) { + shmop_close($shmId); - if (false === shmop_delete($shmId)) { throw new ProcessControlException(sprintf( 'Not able to delete shared memory segment for PID: %d', $this->pid )); } + shmop_close($shmId); return unserialize($this->strFromMem($sharedMemory)); @@ -103,19 +121,22 @@ public function send($message, $signal = null, $pause = 500) $termMsgsLen = strlen($terminatedMsgs); // Write new serialized message to shared memory - $shmId = shmop_open($this->pid, 'c', 0644, $termMsgsLen); - if (!is_resource($shmId)) { + if (false === ($shmId = @shmop_open($this->pid, 'c', 0644, $termMsgsLen))) { throw new ProcessControlException(sprintf( 'Not able to create shared memory segment for PID: %d', $this->pid )); } elseif (shmop_write($shmId, $terminatedMsgs, 0) !== $termMsgsLen) { + shmop_close($shmId); + throw new ProcessControlException(sprintf( 'Not able to write to shared memory segment for PID: %d.', $this->pid )); } + shmop_close($shmId); + if (false === $signal) { return; } From 6e65676a7b4af4ac28f98a2f070a0008ee3743e6 Mon Sep 17 00:00:00 2001 From: Petr Levtonov Date: Sun, 2 Feb 2020 00:00:56 +0100 Subject: [PATCH 2/2] Updated CHANGELOG.md --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 007da25..7d93f9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.0.1] - 2020-02-02 + # Fixed - #10: Properly detach from and cleanup shared memory. -## [2.0.0] - 2019-11-29 +## [2.0.0] - 2020-02-01 ### Changed @@ -57,7 +59,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added progress callbacks to Deferred. - Added serializable objects for exit and error messages. -[Unreleased]: https://github.com/TheLevti/spork/compare/0.3.0...HEAD +[Unreleased]: https://github.com/TheLevti/spork/compare/2.0.1...HEAD +[2.0.1]: https://github.com/TheLevti/spork/releases/2.0.1 [2.0.0]: https://github.com/TheLevti/spork/releases/2.0.0 [1.0.0]: https://github.com/TheLevti/spork/releases/1.0.0 [0.3.0]: https://github.com/TheLevti/spork/releases/0.3.0