Beispiel #1
0
 /**
  * Start Forking
  *
  * @param ProcessInterface $ProcessObject
  * @final
  */
 public final function Run($ProcessObject)
 {
     // Check for ProcessObject existence
     if (!$ProcessObject instanceof ProcessInterface) {
         throw new \Exception("Invalid Proccess object", E_ERROR);
     }
     // Set class property
     $this->ProcessObject = $ProcessObject;
     $pid = posix_getpid();
     if ($this->PIDDir) {
         $this->Logger->debug("Touch process PID file {$pid}");
         @touch("{$this->PIDDir}/{$pid}");
     }
     $this->Logger->debug("Executing 'OnStartForking' routine");
     // Run routines before threading
     $this->ProcessObject->OnStartForking();
     $this->Logger->debug("'OnStartForking' successfully executed.");
     if (count($this->ProcessObject->ThreadArgs) != 0) {
         // Add handlers to signals
         $this->SignalHandler->SetSignalHandlers();
         $this->Logger->debug("Executing ProcessObject::ForkThreads()");
         // Start Threading
         $this->ForkThreads();
         // Wait while threads working
         $iteration = 1;
         while (true) {
             if (count($this->PIDs) == 0) {
                 break;
             }
             if ($this->ChildProcessExecTimeLimit != 0) {
                 foreach ($this->PIDs as $ipid => $ipid_info) {
                     if ($ipid_info['start_time'] + $this->ChildProcessExecTimeLimit < time()) {
                         $this->Logger->error(sprintf(_("Maximum execution time of %s seconds exceeded in %s. Killing process..."), $this->ChildProcessExecTimeLimit, get_class($this->ProcessObject) . "(Child PID: {$ipid_info['pid']})"));
                         posix_kill($ipid, SIGKILL);
                     }
                 }
             }
             if ($iteration++ == 10) {
                 $this->Logger->debug("Goin to MPWL. PIDs(" . implode(", ", array_keys($this->PIDs)) . ")");
                 // Zomby does not need
                 $pid = 1;
                 while ($pid > 0) {
                     $pid = pcntl_wait($status, WNOHANG | WUNTRACED);
                     if ($pid > 0) {
                         $this->Logger->debug("MPWL: pcntl_wait() from child with PID# {$pid} (Exit code: {$status})");
                         foreach ((array) $this->PIDs as $ipid => $ipid_info) {
                             if ($ipid == $pid) {
                                 if ($this->PIDDir) {
                                     $this->Logger->debug("Delete thread PID file {$pid}");
                                     @unlink($this->PIDDir . "/" . $pid);
                                 }
                                 unset($this->PIDs[$ipid]);
                             }
                         }
                     }
                 }
                 sleep(2);
                 $this->ForkThreads();
                 foreach ($this->PIDs as $ipid => $ipid_info) {
                     $res = posix_kill($ipid, 0);
                     $this->Logger->debug("MPWL: Sending 0 signal to {$ipid} = " . intval($res));
                     if ($res === false) {
                         $this->Logger->debug("MPWL: Deleting '{$ipid}' from PIDs queue");
                         if ($this->PIDDir) {
                             $this->Logger->debug("Delete thread PID file {$ipid}");
                             @unlink($this->PIDDir . "/" . $ipid);
                         }
                         unset($this->PIDs[$ipid]);
                     }
                 }
                 $iteration = 1;
             }
         }
     } else {
         $this->Logger->debug("ProcessObject::ThreadArgs is empty. Nothing to do.");
     }
     $pid = posix_getpid();
     if ($this->PIDDir) {
         $this->Logger->debug("Delete Process PID file {$pid}");
         @unlink("{$this->PIDDir}/{$pid}");
     }
     $this->Logger->debug("All childs exited. Executing OnEndForking routine");
     // Run routines after forking
     $this->ProcessObject->OnEndForking();
     $this->Logger->debug("Main process completed. Exiting...");
     exit;
 }