diff --git a/src/PsyncLib/Psync.php b/src/PsyncLib/Psync.php index 6b7a14e..1f67240 100644 --- a/src/PsyncLib/Psync.php +++ b/src/PsyncLib/Psync.php @@ -101,6 +101,8 @@ { // Wait for the process to finish pcntl_waitpid($p->getPid(), $status); + pcntl_signal(SIGTERM, SIG_DFL); + posix_kill($p->getPid(), SIGTERM); // Read the serialized data from shared memory $shm = $p->getShm(); @@ -126,6 +128,24 @@ return $result; } + /** + * Closes and cleans up resources associated with the given process. + * + * @param P $p The process instance to be closed. + * @return void + */ + private static function close(P $p): void + { + // Clean up the child process to prevent zombie processes + pcntl_waitpid($p->getPid(), $status); + pcntl_signal(SIGTERM, SIG_DFL); + posix_kill($p->getPid(), SIGTERM); + + $shm = $p->getShm(); + shmop_delete($shm); + unset(self::$promises[$p->getUuid()]); + } + /** * Waits for the completion of all promises and returns their results. * @@ -178,6 +198,29 @@ return $count; } + /** + * Cleans up resources associated with promises that are not completed. + * + * Iterates through a collection of promises, and for each promise that is not + * yet marked as done, calls a method to close and clean up the resource. + * + * @return int The number of promises that were closed and cleaned up. + */ + public static function clean(): int + { + $count = 0; + foreach(self::$promises as $uuid => $p) + { + if(!self::isDone($p)) + { + self::close($p); + $count++; + } + } + + return $count; + } + /** * Returns the size of the shared memory. *