PHP   111
shm php
Guest on 25th April 2022 01:35:09 AM


  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c)  The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Andrey Hristov <andrey@php.net>                             |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Ping.php,v 1.20 mj Exp $
  20.  
  21. /**************************TODO*******************************************
  22. 1) To add phpdoc documentation
  23. 2) to add methods for setting debug mode
  24. 3) adding a root superclass ?
  25. 4) better error throwing
  26. **************************TODO*******************************************/
  27.  
  28. /********************** TEST CASE ********************
  29. error_reporting(E_ALL);
  30. require_once 'shm.php';
  31.  
  32. $code_protector = & new Shm_Load_Protector("backends", 5);
  33. $code_protector->_debug = 1;
  34. if ($code_protector->increaseLoad());
  35.         sleep(5);
  36.         $code_protector->decreaseLoad();
  37. } else {
  38.         printf('Too many processes');
  39. }
  40. *****************************************************/
  41.  
  42.  
  43. class Shm_SharedObject
  44. {
  45.     function Shm_SharedObject()
  46.     {
  47.  
  48.     }// Shm_SharedObject
  49.  
  50.     function _memSegSpot($str)
  51.     {
  52.         $str = str_pad($str, 4, "Z");     // Z = 5a
  53.         $out = '';
  54.         for ($a = 0; $a < 4; $a++) {
  55.             $out1 = substr($str, $a , 1); // walk through
  56.             $out .= dechex(ord($out1));   // ord returns dec, we need hex for shared memory segments
  57.         }// for
  58.         return hexdec("0x".$out);         // prepend it with 0x
  59.     }// _memSegSpot
  60. }// class Shm_SharedObject
  61.  
  62. class Shm_Semaphore extends Shm_SharedObject
  63. {
  64.     var $_sem_name      = NULL;
  65.     var $_sem_id        = NULL;
  66.     var $_max_acquire   = NULL;
  67.     var $_perm          = NULL;
  68.  
  69.  
  70.     function Shm_Semaphore($sem_name, $max_acquire = 1, $perm='666')
  71.     {
  72.         parent::Shm_SharedObject();
  73.         $this->_sem_name = $this->_memSegSpot(substr($sem_name,0,4));
  74.         $this->_max_acquire = $max_acquire;
  75.         $this->_perm = $perm;
  76.     }// Shm_Semaphore
  77.  
  78.     function acquire()
  79.     {
  80.         $this->_sem_id = sem_get($this->_sem_name, $this->_max_acquire, OctDec($this->_perm));//only matters the first  time
  81.         if (!sem_acquire($this->_sem_id)) {
  82.             printf("cannot acquire semaphore<br>\n");
  83.             return false;
  84.         }// if
  85.         return true;
  86.     }// acquire
  87.  
  88.     function release()
  89.     {
  90.                 if (is_resource($this->_sem_id)) {
  91.                         return sem_release($this->_sem_id);
  92.                 } else {
  93.                         printf("Semaphore was not acquired\n");
  94.                         return FALSE;
  95.                 }
  96.     }// release
  97.  
  98.     function destroy() {
  99.                 if (is_resource($this->_sem_id)) {
  100.                        
  101.                         $r = sem_remove($this->_sem_id);
  102.                         $this->_sem_id = NULL;
  103.                         return $r;
  104.                 } else {
  105.                         printf("Sem ID is not resource\n");
  106.                         return FALSE;
  107.                 }
  108.     }
  109. }// class Shm_Semaphore
  110.  
  111. class Shm_Var extends Shm_SharedObject
  112. {
  113.     var $_debug = false;
  114.  
  115.     var $_key = 1;
  116.     var $_shm_name      = NULL;
  117.     var $_shm_id        = NULL;
  118.     var $_memory_size   = NULL;
  119.     var $_perm          = NULL;
  120.  
  121.     function Shm_Var($shm_name, $memory_size, $perm)
  122.     {
  123.         $this->_shm_name = (int)$this->_memSegSpot(substr($shm_name,0,4));
  124. //      $this->_shm_name = ftok('/home/andrey/test/phpconf/shm1.php','T');
  125.         $this->_debug && var_dump($this->_shm_name);
  126.         $this->_memory_size = $memory_size;
  127.         $this->_perm = $perm;
  128.         $this->_shm_id = shm_attach($this->_shm_name, $this->_memory_size, OctDec($this->_perm));
  129.     }// Shm_Var
  130.  
  131.     function getVar()
  132.     {
  133.         return @shm_get_var($this->_shm_id, $this->_key);
  134.     }// getVar
  135.  
  136.     function putVar($val)
  137.     {
  138.         return shm_put_var($this->_shm_id, $this->_key, $val);
  139.     }// putVar
  140. }// class Shm_Var
  141.  
  142.  
  143. class Shm_Message_Queue extends Shm_SharedObject
  144. {
  145.     var $_debug = false;
  146.  
  147.     var $_key                           = 1;
  148.     var $_shm_name              = NULL;
  149.     var $_msg_queue_id          = NULL;
  150.     var $_memory_size           = NULL;
  151.     var $_perm                  = NULL;
  152.         var $_send_options              = array('serialize'=> TRUE, 'blocking' => TRUE, 'message_type' => 1);
  153.         var $_receive_options   = array('unserialize'=> TRUE, 'desired_message_type' => 1, 'flags' => 0, 'max_size' => 16384);
  154.         var $_received_msg              = NULL;
  155.         var $_received_msg_type = 0;
  156.         var $_err_code                  = 0;
  157.  
  158.         function Shm_Message_Queue($shm_name, $size = 16384, $perm = '666')
  159.         {
  160.                 $this->_shm_name = (int)$this->_memSegSpot(substr($shm_name,0,4));
  161. //              var_dump("Created queue at address [$shm_name]: [".strtoupper(dechex($this->_shm_name))."]");
  162.                 $this->_debug && var_dump($this->shm_name);
  163.                 $this->_perm = $perm;
  164.                 $this->_memory_size = $size;
  165.                 $this->_msg_queue_id = msg_get_queue($this->_shm_name, OctDec($this->_perm));
  166.                 if ($this->_msg_queue_id) {
  167.                         msg_set_queue ($this->_msg_queue_id, array ('msg_qbytes'=> $size));
  168.                         $this->_receive_options['max_size'] = $size;
  169.                 }
  170.         }// Shm_Message_Queue
  171.         function setSendOptions($options)
  172.         {
  173.                 foreach ($options as $k => $v) {
  174.                         if (array_key_exists($k, $this->_send_options)) {
  175.                                 $this->_send_options[$k] = $v;
  176.                         }      
  177.                 }
  178.         }
  179.  
  180.         function setReceiveOptions($options)
  181.         {
  182.                 foreach ($options as $k => $v) {
  183.                         if (array_key_exists($k, $this->_receive_options)) {
  184.                                 $this->_receive_options[$k] = $v;
  185.                         }      
  186.                 }
  187.         }
  188.  
  189.         function send($message, $options = array())
  190.         {
  191.                 $so = &$this->_send_options;
  192.                 $err_code = 0;
  193. //              echo(__METHOD__.":Sending : on [0x".strtoupper(dechex((int)$this->_shm_name))."][\n".print_r($message,1));
  194.                 msg_send($this->_msg_queue_id,
  195.                                         array_key_exists('message_type', $options)?
  196.                                                 (int) $options['message_type']
  197.                                                 :
  198.                                                 (int) $so['message_type'],
  199.                                         $message,
  200.                                         array_key_exists('serialize', $options)?
  201.                                                 (bool) $options['serialize']
  202.                                                 :
  203.                                                 (bool) $so['serialize'],
  204.                                         array_key_exists('blocking', $options)?
  205.                                                 (bool) $options['blocking']
  206.                                                 :
  207.                                                 (bool) $so['blocking'],
  208.                                         $err_code
  209.                         );
  210. /*
  211.                 var_dump(
  212.                                 $this->_msg_queue_id,
  213.                                         array_key_exists('message_type', $options)?
  214.                                                 (int) $options['message_type']
  215.                                                 :
  216.                                                 (int) $so['message_type'],
  217.                                         $message,
  218.                                         array_key_exists('serialize', $options)?
  219.                                                 (bool) $options['serialize']
  220.                                                 :
  221.                                                 (bool) $so['serialize'],
  222.                                         array_key_exists('blocking', $options)?
  223.                                                 (bool) $options['blocking']
  224.                                                 :
  225.                                                 (bool) $so['blocking'],
  226.                                         $err_code                      
  227.                 );
  228. */
  229.                 if ($err_code) {
  230.                         $this->_err_code = $err_code;
  231.                         return FALSE;
  232.                 }
  233.                 return TRUE;
  234.         }
  235.  
  236.         function receive($options = array())
  237.         {
  238.                 $so = &$this->_receive_options;
  239.                 $err_code = 0;
  240.                 $real_msg_type = 0;
  241. //              echo(__METHOD__.":Waiting for : on [0x".strtoupper(dechex((int)$this->_shm_name))."]\n");
  242. /*
  243.                 var_dump("Waiting for",
  244.                                 $this->_msg_queue_id,
  245.                                         array_key_exists('desired_message_type', $options)?
  246.                                                 (int) $options['desired_message_type']
  247.                                                 :
  248.                                                 (int) $so['desired_message_type'],
  249.                                         $real_msg_type,
  250.                                         array_key_exists('max_size', $options)?
  251.                                                 (int) $options['max_size']
  252.                                                 :
  253.                                                 (int) $so['max_size'],
  254.                                         $message,
  255.                                         array_key_exists('unserialize', $options)?
  256.                                                 (bool) $options['unserialize']
  257.                                                 :
  258.                                                 (bool) $so['unserialize'],
  259.                                         array_key_exists('flags', $options)?
  260.                                                 (bool) $options['flags']
  261.                                                 :
  262.                                                 (bool) $so['flags'],
  263.                                         $err_code
  264.  
  265.  
  266.                 );
  267. */
  268.                 msg_receive($this->_msg_queue_id,
  269.                                         array_key_exists('desired_message_type', $options)?
  270.                                                 (int) $options['desired_message_type']
  271.                                                 :
  272.                                                 (int) $so['desired_message_type'],
  273.                                         $real_msg_type,
  274.                                         array_key_exists('max_size', $options)?
  275.                                                 (int) $options['max_size']
  276.                                                 :
  277.                                                 (int) $so['max_size'],
  278.                                         $message,
  279.                                         array_key_exists('unserialize', $options)?
  280.                                                 (bool) $options['unserialize']
  281.                                                 :
  282.                                                 (bool) $so['unserialize'],
  283.                                         array_key_exists('flags', $options)?
  284.                                                 (bool) $options['flags']
  285.                                                 :
  286.                                                 (bool) $so['flags'],
  287.                                         $err_code
  288.                         );
  289. //              echo(__METHOD__.":Received : on [0x".strtoupper(dechex((int)$this->_shm_name))."]\n".print_r($message,1));
  290.                 if ($err_code) {
  291.                         $this->_err_code = $err_code;
  292.                         return FALSE;
  293.                 }
  294.  
  295.                 $this->_received_msg            = $message;
  296.                 $this->_received_msg_type       = $real_msg_type;
  297.                 return TRUE;
  298.         }
  299.        
  300.         function getRecvMsg()
  301.         {
  302.                 return $this->_received_msg;
  303.         }
  304.  
  305.         function getErrorCode()
  306.         {
  307.                 return $this->_err_code;
  308.         }
  309.        
  310.         function getRecvMsgType()
  311.         {
  312.                 return $this->_received_msg_type;
  313.         }
  314.  
  315. }// class Shm_Message_Queue
  316.  
  317.  
  318. class Shm_Protected_Var
  319. {
  320.     var $_debug = false;
  321.  
  322.     var $_sem           = NULL;
  323.     var $_shm_var       = NULL;
  324.     var $_cached_val    = NULL;
  325.     var $_in_section    = false;
  326.  
  327.     function Shm_Protected_Var($name, $size)
  328.     {
  329.         $sname = substr($name,0,4);
  330.         $this->_debug && printf("NAME=[%s]\n", $sname);
  331.         $this->_sem = & new Shm_Semaphore($sname, 1, '666');
  332.         $this->_shm_var = & new Shm_Var($sname, $size, '666');
  333.     }// Shm_Protected_Var
  334.  
  335.     function startSection()
  336.     {
  337.         if ($this->_in_section === true) {
  338.             printf("Already in critical section\n");
  339.             return false;
  340.         }// if
  341.         $this->_sem->acquire();
  342.         $this->_in_section = true;
  343.  
  344.         return true;
  345.     }// startSection
  346.  
  347.     function endSection()
  348.     {
  349.         if ($this->_in_section === false) {
  350.             printf("Not in critical section\n");
  351.             return false;
  352.         }// if
  353.         $this->_in_section = FALSE;
  354.         $this->_sem->release();
  355.  
  356.         return true;
  357.     }// endSection
  358.  
  359.  
  360.     function setVal($val)
  361.     {
  362.         if ($this->_in_section === false) {
  363.             printf("Not in critical section\n");
  364.             return false;
  365.         }// if
  366.         $this->_cached_val = $val;
  367.         $this->_shm_var->putVar($this->_cached_val);
  368.  
  369.         return true;
  370.     }// setVal
  371.  
  372.     function getVal()
  373.     {
  374.         if ($this->_in_section === false) {
  375.             printf("Not in critical section\n");
  376.             return false;
  377.         }// if
  378.         return $this->_shm_var->getVar();
  379.     }// getVal
  380. }// class CProtectedShmVar
  381.  
  382. class Shm_Load_Protector
  383. {
  384.     var $_running_processes = NULL;
  385.  
  386.     var $_debug = false;
  387.  
  388.     function Shm_Load_Protector($code_name, $max_processes)
  389.     {
  390.  
  391.         $this->_max_processes = $max_processes;
  392.         $this->_running_processes = & new Shm_Protected_Var($code_name, 1024);
  393.     }// Shm_Load_Protector
  394.  
  395.     function increaseLoad()
  396.     {
  397.         $this->_running_processes->startSection();
  398.         $val = $this->_running_processes->getVal();
  399.         $this->_debug && printf("[RUNNING_PROCESSES=%d]\n", (int)$val);flush();
  400.         $this->_debug && printf("[MAX_RUNNING_PROCESSES=%d]\n", (int) $this->_max_processes);flush();
  401.         if ($val === false) {
  402.             $val = 0;
  403.         } else if ($val >= $this->_max_processes) {
  404.             $this->_running_processes->endSection();
  405.             return false;
  406.         }// if
  407.         $val = (int)$val + 1;
  408.         $this->_running_processes->setVal($val);
  409.         $val = $this->_running_processes->getVal();
  410.         $this->_debug && printf("[RUNNING_PROCESSES=%d]\n", (int)$val);flush();
  411.         $this->_running_processes->endSection();
  412.  
  413.         return true;
  414.     }// increaseLoad
  415.  
  416.     function decreaseLoad()
  417.     {
  418.         $this->_running_processes->startSection();
  419.         $val = $this->_running_processes->getVal();
  420.         $this->_debug && printf("[RUNNING_PROCESSES=%d]\n", (int)$val);flush();
  421.         $val--;
  422.         $this->_debug && printf("[RUNNING_PROCESSES=%d]\n", (int)$val);flush();
  423.         $this->_running_processes->setVal($val);
  424.         $this->_running_processes->endSection();
  425.     }// decreaseLoad
  426.  
  427.     function nullCounterValue()
  428.     {
  429.         $this->_running_processes->startSection();
  430.         $this->_running_processes->setVal(0);
  431.         $this->_running_processes->endSection();
  432.     }// null_counter_value
  433.  
  434.     function getCounterValue()
  435.     {
  436.         $this->_running_processes->startSection();
  437.         $v = $this->_running_processes->getVal(0);
  438.         $this->_running_processes->endSection();
  439.  
  440.         return $v;
  441.     }// getCounterValue
  442. }// class Shm_Load_Protector
  443. ?>

Raw Paste

Login or Register to edit or fork this paste. It's free.