예제 #1
0
 /**
  * Start Forking
  *
  * @param object $ProcessObject
  * @final 
  */
 public final function Run(&$ProcessObject)
 {
     // Check for ProcessObject existence
     if (!is_object($ProcessObject) || !$ProcessObject instanceof IProcess) {
         self::RaiseError("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);
                     }
                 }
             }
             sleep(2);
             if ($iteration++ == 10) {
                 $this->Logger->debug("Goin to MPWL. PIDs(" . implode(", ", array_keys($this->PIDs)) . ")");
                 //
                 // Zomby not needed.
                 //
                 $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]);
                         }
                     }
                     $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 complete. Exiting...");
     exit;
 }
예제 #2
0
        /**
         * Start Forking
         *
         * @param object $ProcessObject
         * @final 
         */
        final public function Run(&$ProcessObject)
        {
            // Check for ProcessObject existence
            if (!is_object($ProcessObject) || !($ProcessObject instanceof IProcess))
                self::RaiseError("Invalid Proccess object", E_ERROR);    
               
            // Set class property   
            $this->ProcessObject = $ProcessObject;
            
            //Log::Log("Executing 'OnStartForking' routine", E_NOTICE);
                
            // Run routines before threading
            $this->ProcessObject->OnStartForking();  
            
            //Log::Log("'OnStartForking' successfully executed.", E_NOTICE);

            if (count($this->ProcessObject->ThreadArgs) == 0)
            {
                //Log::Log("ProcessObject::ThreadArgs is empty. Nothing to do.", E_NOTICE);
                return true;
            }
            
            //Log::Log("Executing ProcessObject::ForkThreads()", E_NOTICE);
            
            // Start Threading
            $this->ForkThreads();
            
            // Wait while threads working 
            $iteration = 1;          
            while (true)
        	{
        		if (count($this->PIDs) == 0)
        			break;

        		sleep(2);
        	    
        	    if ($iteration++ == 10)
        	    {
        	        //Log::Log("Goin to MPWL. PIDs(".implode(", ", $this->PIDs).")", E_NOTICE);
        	        
        	        //
        	        // Zomby not needed.
        	        //
        	        
        	        $pid = pcntl_wait($status, WNOHANG | WUNTRACED);
        	        if ($pid > 0)
		    		{
		    		    //Log::Log("MPWL: pcntl_wait() from child with PID# {$pid} (Exit code: {$status})", E_NOTICE);
		  
		    		    foreach((array)$this->PIDs as $kk=>$vv)
		    			{
		    				if ($vv == $pid)
		    					unset($this->PIDs[$kk]);
		    			}
		    			
		    			$this->ForkThreads();
		    		}
        	        
        	        foreach ($this->PIDs as $k=>$pid)
        	        {
        	           $res = posix_kill($pid, 0);
        	           //Log::Log("MPWL: Sending 0 signal to {$pid} = ".intval($res), E_NOTICE);
        	           
        	           if ($res === FALSE)
        	           {
        	               //Log::Log("MPWL: Deleting '{$pid}' from PIDs query", E_NOTICE);
        	               unset($this->PIDs[$k]);
        	           }
        	        }

        	        $iteration = 1;
        	    }
        	    
        	}
            
        	//Log::Log("All childs exited. Executing OnEndForking routine", E_NOTICE);
        	   
        	// Run routines after forking
            $this->ProcessObject->OnEndForking();  
            
            //Log::Log("Process complete. Exiting...", E_NOTICE);
                
            exit();
        }