Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / psy / psysh / src / ExecutionLoop / ProcessForker.php
similarity index 69%
rename from vendor/psy/psysh/src/Psy/ExecutionLoop/ForkingLoop.php
rename to vendor/psy/psysh/src/ExecutionLoop/ProcessForker.php
index f37eeae199f7497f70ba0521fcff4d522c0e3f7f..1a5bb7a949f152db8182c5a6847ba2fcf341b8a9 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * This file is part of Psy Shell.
  *
- * (c) 2012-2017 Justin Hileman
+ * (c) 2012-2018 Justin Hileman
  *
  * For the full copyright and license information, please view the LICENSE
  * file that was distributed with this source code.
 namespace Psy\ExecutionLoop;
 
 use Psy\Context;
+use Psy\Exception\BreakException;
 use Psy\Shell;
 
 /**
- * A forking version of the Psy Shell execution loop.
+ * An execution loop listener that forks the process before executing code.
  *
- * This version is preferred, as it won't die prematurely if user input includes
+ * This is awesome, as the session won't die prematurely if user input includes
  * a fatal error, such as redeclaring a class or function.
  */
-class ForkingLoop extends Loop
+class ProcessForker extends AbstractListener
 {
     private $savegame;
+    private $up;
 
     /**
-     * Run the execution loop.
+     * Process forker is supported if pcntl and posix extensions are available.
      *
-     * Forks into a master and a loop process. The loop process will handle the
-     * evaluation of all instructions, then return its state via a socket upon
-     * completion.
+     * @return bool
+     */
+    public static function isSupported()
+    {
+        return function_exists('pcntl_signal') && function_exists('posix_getpid');
+    }
+
+    /**
+     * Forks into a master and a loop process.
+     *
+     * The loop process will handle the evaluation of all instructions, then
+     * return its state via a socket upon completion.
      *
      * @param Shell $shell
      */
-    public function run(Shell $shell)
+    public function beforeRun(Shell $shell)
     {
         list($up, $down) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
 
         if (!$up) {
-            throw new \RuntimeException('Unable to create socket pair.');
+            throw new \RuntimeException('Unable to create socket pair');
         }
 
         $pid = pcntl_fork();
         if ($pid < 0) {
-            throw new \RuntimeException('Unable to start execution loop.');
+            throw new \RuntimeException('Unable to start execution loop');
         } elseif ($pid > 0) {
             // This is the main thread. We'll just wait for a while.
 
@@ -51,11 +62,11 @@ class ForkingLoop extends Loop
             fclose($up);
 
             // Wait for a return value from the loop process.
-            $read   = array($down);
+            $read   = [$down];
             $write  = null;
             $except = null;
             if (stream_select($read, $write, $except, null) === false) {
-                throw new \RuntimeException('Error waiting for execution loop.');
+                throw new \RuntimeException('Error waiting for execution loop');
             }
 
             $content = stream_get_contents($down);
@@ -65,7 +76,7 @@ class ForkingLoop extends Loop
                 $shell->setScopeVariables(@unserialize($content));
             }
 
-            return;
+            throw new BreakException('Exiting main thread');
         }
 
         // This is the child process. It's going to do all the work.
@@ -76,28 +87,26 @@ class ForkingLoop extends Loop
         // We won't be needing this one.
         fclose($down);
 
-        // Let's do some processing.
-        parent::run($shell);
-
-        // Send the scope variables back up to the main thread
-        fwrite($up, $this->serializeReturn($shell->getScopeVariables(false)));
-        fclose($up);
-
-        posix_kill(posix_getpid(), SIGKILL);
+        // Save this; we'll need to close it in `afterRun`
+        $this->up = $up;
     }
 
     /**
      * Create a savegame at the start of each loop iteration.
+     *
+     * @param Shell $shell
      */
-    public function beforeLoop()
+    public function beforeLoop(Shell $shell)
     {
         $this->createSavegame();
     }
 
     /**
      * Clean up old savegames at the end of each loop iteration.
+     *
+     * @param Shell $shell
      */
-    public function afterLoop()
+    public function afterLoop(Shell $shell)
     {
         // if there's an old savegame hanging around, let's kill it.
         if (isset($this->savegame)) {
@@ -106,6 +115,23 @@ class ForkingLoop extends Loop
         }
     }
 
+    /**
+     * After the REPL session ends, send the scope variables back up to the main
+     * thread (if this is a child thread).
+     *
+     * @param Shell $shell
+     */
+    public function afterRun(Shell $shell)
+    {
+        // We're a child thread. Send the scope variables back up to the main thread.
+        if (isset($this->up)) {
+            fwrite($this->up, $this->serializeReturn($shell->getScopeVariables(false)));
+            fclose($this->up);
+
+            posix_kill(posix_getpid(), SIGKILL);
+        }
+    }
+
     /**
      * Create a savegame fork.
      *
@@ -120,7 +146,7 @@ class ForkingLoop extends Loop
 
         $pid = pcntl_fork();
         if ($pid < 0) {
-            throw new \RuntimeException('Unable to create savegame fork.');
+            throw new \RuntimeException('Unable to create savegame fork');
         } elseif ($pid > 0) {
             // we're the savegame now... let's wait and see what happens
             pcntl_waitpid($pid, $status);
@@ -149,7 +175,7 @@ class ForkingLoop extends Loop
      */
     private function serializeReturn(array $return)
     {
-        $serializable = array();
+        $serializable = [];
 
         foreach ($return as $key => $value) {
             // No need to return magic variables
@@ -165,10 +191,11 @@ class ForkingLoop extends Loop
             try {
                 @serialize($value);
                 $serializable[$key] = $value;
-            } catch (\Exception $e) {
-                // we'll just ignore this one...
             } catch (\Throwable $e) {
+                // we'll just ignore this one...
+            } catch (\Exception $e) {
                 // and this one too...
+                // @todo remove this once we don't support PHP 5.x anymore :)
             }
         }