PHP Classes
Icontem

File: daemon.class.php


  Search   All class groups All class groups   Latest entries Latest entries   Top 10 charts Top 10 charts   Newsletter Newsletter   Blog Blog   Forums Forums   Help FAQ Help FAQ  
  Login   Register  
Recommend this page to a friend! ReTweet ReTweet Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Grigori Kochanov  >  Daemon Emulation  >  daemon.class.php  
File: daemon.class.php
Role: Class source
Content type: text/plain
Description: The class that allows to make script a daemon process
Class: Daemon Emulation
Create and manage daemon processes
 

Contents

Class file image Download
<?php
/* This code is writed by Grigori A. Kochanov.
* The script can be used, modified and redistributed freely 
* under the terms and conditions of the BSD public license.
*
* Requirements:  PHP 5 CLI compiled with --enable-pcntl, POSIX functions not disabled
* UNIX-style systems only
*
* version: 1
*/

class Daemon{

//show demonstration messages
const DEBUG_MODE true;

//exit if sleeping more then MAX_SLEEP_HOURS
const MAX_SLEEP_HOURS 6;

//path to the pid file
const PID_FILE_PATH='daemon.pid';

//service parameters
const i_sleep 1;
const 
i_run 2;
const 
i_exit 3;
private $role;
private $child_pid;

/**
 * Checks the configuration, register signal handler and start the multi-process daemon emulation
 *
 */
public function __construct(){
    
//check the PHP configuration
    
if (!defined('SIGHUP')){
        
trigger_error('PHP is compiled without --enable-pcntl directive',E_USER_ERROR);
    }
    
//check if the pid file is writable
    
if (file_exists(self::PID_FILE_PATH ) && !is_writable(self::PID_FILE_PATH) ||
        !
file_exists(self::PID_FILE_PATH ) && !is_writable(dirname(self::PID_FILE_PATH))
    ){
        
trigger_error('can not open PID file '.self::PID_FILE_PATH.' for writing'E_USER_ERROR);
    }
    
    
// tick required as of PHP 4.3.0
    
declare(ticks 2);

    
// setup signal handlers
    
pcntl_signal(SIGTERM,array($this,'sigTermHandler'));
    
pcntl_signal(SIGCONT,array($this,'sigContHandler'));
    
pcntl_signal(SIGALRM,array($this,'sigAlrmHandler'));
    
    
//register the shutdown function to waken the child
    
register_shutdown_function(array($this,'wakeUpChild'));

    
//the parent will work
    
$this->role self::i_run;
    
    if (
self::DEBUG_MODE){
        echo 
"Root PID: ".posix_getpid()."\n";
    }
    do{
        
//child sleeps
        
if ($this->role == self::i_sleep ){
            if (
self::DEBUG_MODE){
                echo 
'process '$pid," will sleep\n";
            }
            
sleep(0xFFFFFFFF);
        }
        
        
//if we are asked to exit - let's do it
        
if ($this->role == self::i_exit ){
            @
unlink(self::PID_FILE_PATH );
            exit;
        }
        if (
$this->role == self::i_run){
            
//spawn a child and continue the work
            
$this->child_pid pcntl_fork();
            
$pid posix_getpid();
            if (!
$this->child_pid){
                
//it's a child - go to bed
                
$this->role self::i_sleep;
                
pcntl_alarm(3600*self::MAX_SLEEP_HOURS); // max time to sleep, then exit
            
}
        }
    }while (
$this->role == self::i_sleep);

    
//write the PID
    
file_put_contents(self::PID_FILE_PATH,$pid);

    if (
self::DEBUG_MODE){
        echo 
'process ',$pid" continues opertions\n";
    }
}

/**
 * Catch the SIGTERM signal
 *
 */
private function sigTermHandler(){
    if (
self::DEBUG_MODE){
        echo 
"SIGTERM CAUGHT\n";
    }
    
// I was asked to exit - pass the call to the child and remove the PID file
    
if ($this->child_pid){
        
posix_kill($this->child_pidSIGTERM);
        @
unlink(self::PID_FILE_PATH );
    }
    exit;
}

/**
 * Catch the SIGCONT signal
 *
 */
private function sigContHandler(){
    
// I am waken up to run
    
$this->role self::i_run;
}

/**
 * Catch the SIGALRM signal
 *
 */
private function sigAlrmHandler(){
    
//time is out
    
$this->role self::i_exit;
}

/**
 * Send the signal to a child to wake him up to continue the work
 *
 */
public function wakeUpChild(){
    if (
$this->child_pid){
        
posix_kill($this->child_pidSIGCONT);
    }
}

/**
 * Send the SIGTERM to the process and the child
 *
 */
public function terminate(){
    
posix_kill(posix_getpid(), SIGTERM);
}

//end of the class
}

?>

 
  Advertise on this site Advertise on this site   Site map Site map   Statistics Statistics   Site tips Site tips   Privacy policy Privacy policy   Contact Contact  

For more information send a message to :
info at phpclasses dot org.
Copyright (c) Icontem 1999-2009 PHP Classes - PHP Class Scripts
  PHP Book Reviews - Reviews of books and other products