Skip to content

Commit

Permalink
Merge branch 'release/2.0.1'
Browse files Browse the repository at this point in the history
# Fixed

- #10: Properly detach from and cleanup shared memory.
  • Loading branch information
TheLevti committed Feb 1, 2020
2 parents c6ca782 + 6e65676 commit 3e2922b
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 7 deletions.
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.0.0] - 2019-11-29
## [2.0.1] - 2020-02-02

# Fixed

- #10: Properly detach from and cleanup shared memory.

## [2.0.0] - 2020-02-01

### Changed

Expand Down Expand Up @@ -53,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
10 changes: 10 additions & 0 deletions src/Spork/Fork.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ public function __construct($pid, SharedMemory $shm, $debug = false)
$this->name = '<anonymous>';
}

/**
* 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).
*/
Expand Down
6 changes: 5 additions & 1 deletion src/Spork/ProcessManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public function __destruct()
if (!$this->zombieOkay) {
$this->wait();
}

foreach ($this->forks as $fork) {
$fork->cleanupSharedMemory();
}
}

public function getEventDispatcher()
Expand Down Expand Up @@ -97,7 +101,6 @@ public function fork($callable)
}

if (0 === $pid) {
$currPid = posix_getpid();
// reset the list of child processes
$this->forks = [];

Expand All @@ -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()) {
Expand Down
29 changes: 25 additions & 4 deletions src/Spork/SharedMemory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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));
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 3e2922b

Please sign in to comment.