Changes of Revision 6
[-] | Changed | php-pecl-APCu.changes |
1
2 ------------------------------------------------------------------- 3 +Sun Jun 15 08:10:20 UTC 2014 - cs@linux-administrator.com 4 + 5 +- update to release 4.0.6 6 + 7 +------------------------------------------------------------------- 8 Wed Jun 11 18:52:10 UTC 2014 - cs@linux-administrator.com 9 10 - update to release 4.0.5 11 |
||
[-] | Changed | php-pecl-APCu.spec ^ |
10 1
2 3 Summary: APCu - APC User Cache 4 Name: php-pecl-APCu 5 -Version: 4.0.5 6 +Version: 4.0.6 7 Release: 1%{?dist} 8 License: PHP 9 Group: Development/Languages 10 |
||
[+] | Deleted | apcu-4.0.4.tgz/apcu-4.0.4/apc.h ^ |
@@ -1,180 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2006-2011 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Daniel Cowgill <dcowgill@communityconnect.com> | - | George Schlossnagle <george@omniti.com> | - | Rasmus Lerdorf <rasmus@php.net> | - | Arun C. Murthy <arunc@yahoo-inc.com> | - | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> | - +----------------------------------------------------------------------+ - - This software was contributed to PHP by Community Connect Inc. in 2002 - and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1. - Future revisions and derivatives of this source code must acknowledge - Community Connect Inc. as the original contributor of this module by - leaving this note intact in the source code. - - All other licensing and usage conditions are those of the PHP Group. - - */ - -/* $Id: apc.h 328292 2012-11-09 07:05:17Z laruence $ */ - -#ifndef APC_H -#define APC_H - -/* - * This module defines utilities and helper functions used elsewhere in APC. - */ -#ifdef PHP_WIN32 -# define PHP_APCU_API __declspec(dllexport) -#elif defined(__GNUC__) && __GNUC__ >= 4 -# define PHP_APCU_API __attribute__ ((visibility("default"))) -#else -# define PHP_APCU_API -#endif - -/* Commonly needed C library headers. */ -#include <assert.h> -#include <errno.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -/* UNIX headers (needed for struct stat) */ -#include <sys/types.h> -#include <sys/stat.h> -#ifndef PHP_WIN32 -#include <unistd.h> -#endif - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "php.h" -#include "main/php_streams.h" - -/* typedefs for extensible memory allocators */ -typedef void* (*apc_malloc_t)(size_t TSRMLS_DC); -typedef void (*apc_free_t) (void * TSRMLS_DC); - -/* wrappers for memory allocation routines */ -PHP_APCU_API void* apc_emalloc(size_t n TSRMLS_DC); -PHP_APCU_API void* apc_erealloc(void* p, size_t n TSRMLS_DC); -PHP_APCU_API void* apc_php_malloc(size_t n TSRMLS_DC); -PHP_APCU_API void apc_php_free(void* p TSRMLS_DC); -PHP_APCU_API void apc_efree(void* p TSRMLS_DC); -PHP_APCU_API char* apc_estrdup(const char* s TSRMLS_DC); -PHP_APCU_API void* apc_xstrdup(const char* s, apc_malloc_t f TSRMLS_DC); -PHP_APCU_API void* apc_xmemcpy(const void* p, size_t n, apc_malloc_t f TSRMLS_DC); - -/* console display functions */ -PHP_APCU_API void apc_error(const char *format TSRMLS_DC, ...); -PHP_APCU_API void apc_warning(const char *format TSRMLS_DC, ...); -PHP_APCU_API void apc_notice(const char *format TSRMLS_DC, ...); -PHP_APCU_API void apc_debug(const char *format TSRMLS_DC, ...); - -/* string and text manipulation */ -PHP_APCU_API char* apc_append(const char* s, const char* t TSRMLS_DC); -PHP_APCU_API char* apc_substr(const char* s, int start, int length TSRMLS_DC); -PHP_APCU_API char** apc_tokenize(const char* s, char delim TSRMLS_DC); - -/* apc_crc32: returns the CRC-32 checksum of the first len bytes in buf */ -PHP_APCU_API unsigned int apc_crc32(const unsigned char* buf, unsigned int len); - -/* apc_flip_hash flips keys and values for faster searching */ -PHP_APCU_API HashTable* apc_flip_hash(HashTable *hash); - -#define APC_NEGATIVE_MATCH 1 -#define APC_POSITIVE_MATCH 2 - -#define apc_time() \ - (APCG(use_request_time) ? (time_t) sapi_get_request_time(TSRMLS_C) : time(0)); - -#if defined(__GNUC__) -# define APC_UNUSED __attribute__((unused)) -# define APC_USED __attribute__((used)) -# define APC_ALLOC __attribute__((malloc)) -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) -# define APC_HOTSPOT __attribute__((hot)) -# else -# define APC_HOTSPOT -# endif -#else -# define APC_UNUSED -# define APC_USED -# define APC_ALLOC -# define APC_HOTSPOT -#endif - -/* -* Serializer API -*/ -#define APC_SERIALIZER_ABI "0" -#define APC_SERIALIZER_CONSTANT "\000apc_register_serializer-" APC_SERIALIZER_ABI - -#define APC_SERIALIZER_NAME(module) module##_apc_serializer -#define APC_UNSERIALIZER_NAME(module) module##_apc_unserializer - -#define APC_SERIALIZER_ARGS unsigned char **buf, size_t *buf_len, const zval *value, void *config TSRMLS_DC -#define APC_UNSERIALIZER_ARGS zval **value, unsigned char *buf, size_t buf_len, void *config TSRMLS_DC - -typedef int (*apc_serialize_t)(APC_SERIALIZER_ARGS); -typedef int (*apc_unserialize_t)(APC_UNSERIALIZER_ARGS); - -/* {{{ struct definition: apc_serializer_t */ -typedef struct apc_serializer_t { - const char* name; - apc_serialize_t serialize; - apc_unserialize_t unserialize; - void* config; -} apc_serializer_t; -/* }}} */ - -/* {{{ _apc_register_serializer - registers the serializer using the given name and paramters */ -PHP_APCU_API int _apc_register_serializer(const char* name, - apc_serialize_t serialize, - apc_unserialize_t unserialize, - void *config TSRMLS_DC); /* }}} */ - -/* {{{ apc_get_serializers - fetches the list of serializers */ -PHP_APCU_API apc_serializer_t* apc_get_serializers(TSRMLS_D); /* }}} */ - -/* {{{ apc_find_serializer - finds a previously registered serializer by name */ -PHP_APCU_API apc_serializer_t* apc_find_serializer(const char* name TSRMLS_DC); /* }}} */ - -/* {{{ default serializers */ -PHP_APCU_API int APC_SERIALIZER_NAME(php) (APC_SERIALIZER_ARGS); -PHP_APCU_API int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS); /* }}} */ - -/* {{{ eval serializers */ -PHP_APCU_API int APC_SERIALIZER_NAME(eval) (APC_SERIALIZER_ARGS); -PHP_APCU_API int APC_UNSERIALIZER_NAME(eval) (APC_UNSERIALIZER_ARGS); /* }}} */ - -#endif - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker - * vim<600: expandtab sw=4 ts=4 sts=4 - */ | ||
[+] | Deleted | apcu-4.0.4.tgz/apcu-4.0.4/apc.php ^ |
@@ -1,1146 +0,0 @@ -<?php -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2006-2011 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Ralf Becker <beckerr@php.net> | - | Rasmus Lerdorf <rasmus@php.net> | - | Ilia Alshanetsky <ilia@prohost.org> | - +----------------------------------------------------------------------+ - - All other licensing and usage conditions are those of the PHP Group. - - */ - -$VERSION='$Id$'; - -////////// READ OPTIONAL CONFIGURATION FILE //////////// -if (file_exists("apc.conf.php")) include("apc.conf.php"); -//////////////////////////////////////////////////////// - -////////// BEGIN OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////// - -defaults('USE_AUTHENTICATION',1); // Use (internal) authentication - best choice if - // no other authentication is available - // If set to 0: - // There will be no further authentication. You - // will have to handle this by yourself! - // If set to 1: - // You need to change ADMIN_PASSWORD to make - // this work! -defaults('ADMIN_USERNAME','apc'); // Admin Username -defaults('ADMIN_PASSWORD','password'); // Admin Password - CHANGE THIS TO ENABLE!!! - -// (beckerr) I'm using a clear text password here, because I've no good idea how to let -// users generate a md5 or crypt password in a easy way to fill it in above - -//defaults('DATE_FORMAT', "d.m.Y H:i:s"); // German -defaults('DATE_FORMAT', 'Y/m/d H:i:s'); // US - -defaults('GRAPH_SIZE',200); // Image size - -//defaults('PROXY', 'tcp://127.0.0.1:8080'); - -////////// END OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////// - - -// "define if not defined" -function defaults($d,$v) { - if (!defined($d)) define($d,$v); // or just @define(...) -} - -// rewrite $PHP_SELF to block XSS attacks -// -$PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],''), ENT_QUOTES, 'UTF-8') : ''; -$time = time(); -$host = php_uname('n'); -if($host) { $host = '('.$host.')'; } -if (isset($_SERVER['SERVER_ADDR'])) { - $host .= ' ('.$_SERVER['SERVER_ADDR'].')'; -} - -// operation constants -define('OB_HOST_STATS',1); -define('OB_USER_CACHE',2); -define('OB_VERSION_CHECK',3); - -// check validity of input variables -$vardom=array( - 'OB' => '/^\d+$/', // operational mode switch - 'CC' => '/^[01]$/', // clear cache requested - 'DU' => '/^.*$/', // Delete User Key - 'SH' => '/^[a-z0-9]+$/', // shared object description - - 'IMG' => '/^[123]$/', // image to generate - 'LO' => '/^1$/', // login requested - - 'COUNT' => '/^\d+$/', // number of line displayed in list - 'SCOPE' => '/^[AD]$/', // list view scope - 'SORT1' => '/^[AHSMCDTZ]$/', // first sort key - 'SORT2' => '/^[DA]$/', // second sort key - 'AGGR' => '/^\d+$/', // aggregation by dir level - 'SEARCH' => '~^[a-zA-Z0-9/_.-]*$~' // aggregation by dir level -); - -// cache scope -$scope_list=array( - 'A' => 'cache_list', - 'D' => 'deleted_list' -); - -// handle POST and GET requests -if (empty($_REQUEST)) { - if (!empty($_GET) && !empty($_POST)) { - $_REQUEST = array_merge($_GET, $_POST); - } else if (!empty($_GET)) { - $_REQUEST = $_GET; - } else if (!empty($_POST)) { - $_REQUEST = $_POST; - } else { - $_REQUEST = array(); - } -} - -// check parameter syntax -foreach($vardom as $var => $dom) { - if (!isset($_REQUEST[$var])) { - $MYREQUEST[$var]=NULL; - } else if (!is_array($_REQUEST[$var]) && preg_match($dom.'D',$_REQUEST[$var])) { - $MYREQUEST[$var]=$_REQUEST[$var]; - } else { - $MYREQUEST[$var]=$_REQUEST[$var]=NULL; - } -} - -// check parameter sematics -if (empty($MYREQUEST['SCOPE'])) $MYREQUEST['SCOPE']="A"; -if (empty($MYREQUEST['SORT1'])) $MYREQUEST['SORT1']="H"; -if (empty($MYREQUEST['SORT2'])) $MYREQUEST['SORT2']="D"; -if (empty($MYREQUEST['OB'])) $MYREQUEST['OB']=OB_HOST_STATS; -if (!isset($MYREQUEST['COUNT'])) $MYREQUEST['COUNT']=20; -if (!isset($scope_list[$MYREQUEST['SCOPE']])) $MYREQUEST['SCOPE']='A'; - -$MY_SELF= - "$PHP_SELF". - "?SCOPE=".$MYREQUEST['SCOPE']. - "&SORT1=".$MYREQUEST['SORT1']. - "&SORT2=".$MYREQUEST['SORT2']. - "&COUNT=".$MYREQUEST['COUNT']; -$MY_SELF_WO_SORT= - "$PHP_SELF". - "?SCOPE=".$MYREQUEST['SCOPE']. - "&COUNT=".$MYREQUEST['COUNT']; - -// authentication needed? -// -if (!USE_AUTHENTICATION) { - $AUTHENTICATED=1; -} else { - $AUTHENTICATED=0; - if (ADMIN_PASSWORD!='password' && ($MYREQUEST['LO'] == 1 || isset($_SERVER['PHP_AUTH_USER']))) { - - if (!isset($_SERVER['PHP_AUTH_USER']) || - !isset($_SERVER['PHP_AUTH_PW']) || - $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME || - $_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) { - Header("WWW-Authenticate: Basic realm=\"APC Login\""); - Header("HTTP/1.0 401 Unauthorized"); - - echo <<<EOB - <html><body> - <h1>Rejected!</h1> - <big>Wrong Username or Password!</big><br/> <br/> - <big><a href='$PHP_SELF?OB={$MYREQUEST['OB']}'>Continue...</a></big> - </body></html> -EOB; - exit; - - } else { - $AUTHENTICATED=1; - } - } -} - -// clear cache -if ($AUTHENTICATED && isset($MYREQUEST['CC']) && $MYREQUEST['CC']) { - apcu_clear_cache(); -} - -if ($AUTHENTICATED && !empty($MYREQUEST['DU'])) { - apcu_delete($MYREQUEST['DU']); -} - -if(!function_exists('apcu_cache_info')) { - echo "No cache info available. APC does not appear to be running."; - exit; -} - -$cache = apcu_cache_info(); - -$mem=apcu_sma_info(); - -// don't cache this page -// -header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1 -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); // HTTP/1.0 - -function duration($ts) { - global $time; - $years = (int)((($time - $ts)/(7*86400))/52.177457); - $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400)); - $weeks = (int)(($rem)/(7*86400)); - $days = (int)(($rem)/86400) - $weeks*7; - $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24; - $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60; - $str = ''; - if($years==1) $str .= "$years year, "; - if($years>1) $str .= "$years years, "; - if($weeks==1) $str .= "$weeks week, "; - if($weeks>1) $str .= "$weeks weeks, "; - if($days==1) $str .= "$days day,"; - if($days>1) $str .= "$days days,"; - if($hours == 1) $str .= " $hours hour and"; - if($hours>1) $str .= " $hours hours and"; - if($mins == 1) $str .= " 1 minute"; - else $str .= " $mins minutes"; - return $str; -} - -// create graphics -// -function graphics_avail() { - return extension_loaded('gd'); -} -if (isset($MYREQUEST['IMG'])) -{ - if (!graphics_avail()) { - exit(0); - } - - function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) { - $r=$diameter/2; - $w=deg2rad((360+$start+($end-$start)/2)%360); - - - if (function_exists("imagefilledarc")) { - // exists only if GD 2.0.1 is avaliable - imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE); - imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE); - imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED); - } else { - imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2); - imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); - imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); - imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); - imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); - imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2); - } - if ($text) { - if ($placeindex>0) { - imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1); - imagestring($im,4,$diameter, $placeindex*12,$text,$color1); - - } else { - imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1); - } - } - } - - function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$text,$placeindex=0) { - $r=$diameter/2; - $w=deg2rad((360+$start+($end-$start)/2)%360); - - if ($placeindex>0) { - imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1); - imagestring($im,4,$diameter, $placeindex*12,$text,$color1); - - } else { - imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1); - } - } - - function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') { - global $col_black; - $x1=$x+$w-1; - $y1=$y+$h-1; - - imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black); - if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2); - else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2); - imagerectangle($im, $x, $y1, $x1, $y, $color1); - if ($text) { - if ($placeindex>0) { - - if ($placeindex<16) - { - $px=5; - $py=$placeindex*12+6; - imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2); - imageline($im,$x,$y+$h/2,$px+90,$py,$color2); - imagestring($im,2,$px,$py-6,$text,$color1); - - } else { - if ($placeindex<31) { - $px=$x+40*2; - $py=($placeindex-15)*12+6; - } else { - $px=$x+40*2+100*intval(($placeindex-15)/15); - $py=($placeindex%15)*12+6; - } - imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2); - imageline($im,$x+$w,$y+$h/2,$px,$py,$color2); - imagestring($im,2,$px+2,$py-6,$text,$color1); - } - } else { - imagestring($im,4,$x+5,$y1-16,$text,$color1); - } - } - } - - - $size = GRAPH_SIZE; // image size - if ($MYREQUEST['IMG']==3) - $image = imagecreate(2*$size+150, $size+10); - else - $image = imagecreate($size+50, $size+10); - - $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); - $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); - $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); - $col_black = imagecolorallocate($image, 0, 0, 0); - imagecolortransparent($image,$col_white); - - switch ($MYREQUEST['IMG']) { - - case 1: - $s=$mem['num_seg']*$mem['seg_size']; - $a=$mem['avail_mem']; - $x=$y=$size/2; - $fuzz = 0.000001; - - // This block of code creates the pie chart. It is a lot more complex than you - // would expect because we try to visualize any memory fragmentation as well. - $angle_from = 0; - $string_placement=array(); - for($i=0; $i<$mem['num_seg']; $i++) { - $ptr = 0; - $free = $mem['block_lists'][$i]; - uasort($free, 'block_sort'); - foreach($free as $block) { - if($block['offset']!=$ptr) { // Used block - $angle_to = $angle_from+($block['offset']-$ptr)/$s; - if(($angle_to+$fuzz)>1) $angle_to = 1; - if( ($angle_to*360) - ($angle_from*360) >= 1) { - fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red); - if (($angle_to-$angle_from)>0.05) { - array_push($string_placement, array($angle_from,$angle_to)); - } - } - $angle_from = $angle_to; - } - $angle_to = $angle_from+($block['size'])/$s; - if(($angle_to+$fuzz)>1) $angle_to = 1; - if( ($angle_to*360) - ($angle_from*360) >= 1) { - fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_green); - if (($angle_to-$angle_from)>0.05) { - array_push($string_placement, array($angle_from,$angle_to)); - } - } - $angle_from = $angle_to; - $ptr = $block['offset']+$block['size']; - } - if ($ptr < $mem['seg_size']) { // memory at the end - $angle_to = $angle_from + ($mem['seg_size'] - $ptr)/$s; - if(($angle_to+$fuzz)>1) $angle_to = 1; - fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red); - if (($angle_to-$angle_from)>0.05) { - array_push($string_placement, array($angle_from,$angle_to)); - } - } - } - foreach ($string_placement as $angle) { - text_arc($image,$x,$y,$size,$angle[0]*360,$angle[1]*360,$col_black,bsize($s*($angle[1]-$angle[0]))); - } - break; - - case 2: - $s=$cache['nhits']+$cache['nmisses']; - $a=$cache['nhits']; - - fill_box($image, 30,$size,50,$s ? (-$a*($size-21)/$s) : 0,$col_black,$col_green,sprintf("%.1f%%",$s ? $cache['nhits']*100/$s : 0)); - fill_box($image,130,$size,50,$s ? -max(4,($s-$a)*($size-21)/$s) : 0,$col_black,$col_red,sprintf("%.1f%%",$s ? $cache['nmisses']*100/$s : 0)); - break; - - case 3: - $s=$mem['num_seg']*$mem['seg_size']; - $a=$mem['avail_mem']; - $x=130; - $y=1; - $j=1; - - // This block of code creates the bar chart. It is a lot more complex than you - // would expect because we try to visualize any memory fragmentation as well. - for($i=0; $i<$mem['num_seg']; $i++) { - $ptr = 0; - $free = $mem['block_lists'][$i]; - uasort($free, 'block_sort'); - foreach($free as $block) { - if($block['offset']!=$ptr) { // Used block - $h=(GRAPH_SIZE-5)*($block['offset']-$ptr)/$s; - if ($h>0) { - $j++; - if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($block['offset']-$ptr),$j); - else fill_box($image,$x,$y,50,$h,$col_black,$col_red); - } - $y+=$h; - } - $h=(GRAPH_SIZE-5)*($block['size'])/$s; - if ($h>0) { - $j++; - if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_green,bsize($block['size']),$j); - else fill_box($image,$x,$y,50,$h,$col_black,$col_green); - } - $y+=$h; - $ptr = $block['offset']+$block['size']; - } - if ($ptr < $mem['seg_size']) { // memory at the end - $h = (GRAPH_SIZE-5) * ($mem['seg_size'] - $ptr) / $s; - if ($h > 0) { - fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($mem['seg_size']-$ptr),$j++); - } - } - } - break; - - case 4: - $s=$cache['nhits']+$cache['nmisses']; - $a=$cache['nhits']; - - fill_box($image, 30,$size,50,$s ? -$a*($size-21)/$s : 0,$col_black,$col_green,sprintf("%.1f%%", $s ? $cache['nhits']*100/$s : 0)); - fill_box($image,130,$size,50,$s ? -max(4,($s-$a)*($size-21)/$s) : 0,$col_black,$col_red,sprintf("%.1f%%", $s ? $cache['nmisses']*100/$s : 0)); - break; - } - - header("Content-type: image/png"); - imagepng($image); - exit; -} - -// pretty printer for byte values -// -function bsize($s) { - foreach (array('','K','M','G') as $i => $k) { - if ($s < 1024) break; - $s/=1024; - } - return sprintf("%5.1f %sBytes",$s,$k); -} - -// sortable table header in "scripts for this host" view -function sortheader($key,$name,$extra='') { - global $MYREQUEST, $MY_SELF_WO_SORT; - - if ($MYREQUEST['SORT1']==$key) { - $MYREQUEST['SORT2'] = $MYREQUEST['SORT2']=='A' ? 'D' : 'A'; - } - return "<a class=sortable href=\"$MY_SELF_WO_SORT$extra&SORT1=$key&SORT2=".$MYREQUEST['SORT2']."\">$name</a>"; - -} - -// create menu entry -function menu_entry($ob,$title) { - global $MYREQUEST,$MY_SELF; - if ($MYREQUEST['OB']!=$ob) { - return "<li><a href=\"$MY_SELF&OB=$ob\">$title</a></li>"; - } else if (empty($MYREQUEST['SH'])) { - return "<li><span class=active>$title</span></li>"; - } else { - return "<li><a class=\"child_active\" href=\"$MY_SELF&OB=$ob\">$title</a></li>"; - } -} - -function put_login_link($s="Login") -{ - global $MY_SELF,$MYREQUEST,$AUTHENTICATED; - // needs ADMIN_PASSWORD to be changed! - // - if (!USE_AUTHENTICATION) { - return; - } else if (ADMIN_PASSWORD=='password') - { - print <<<EOB - <a href="#" onClick="javascript:alert('You need to set a password at the top of apc.php before this will work!');return false";>$s</a> -EOB; - } else if ($AUTHENTICATED) { - print <<<EOB - '{$_SERVER['PHP_AUTH_USER']}' logged in! -EOB; - } else{ - print <<<EOB - <a href="$MY_SELF&LO=1&OB={$MYREQUEST['OB']}">$s</a> -EOB; - } -} - -function block_sort($array1, $array2) -{ - if ($array1['offset'] > $array2['offset']) { - return 1; - } else { - return -1; - } -} - - -?> -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head><title>APCu INFO <?php echo $host ?></title> -<style><!-- -body { background:white; font-size:100.01%; margin:0; padding:0; } -body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; } -* html body {font-size:0.8em} -* html p {font-size:0.8em} -* html td {font-size:0.8em} -* html th {font-size:0.8em} -* html input {font-size:0.8em} -* html submit {font-size:0.8em} -td { vertical-align:top } -a { color:black; font-weight:none; text-decoration:none; } -a:hover { text-decoration:underline; } -div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; } - - -div.head div.login { - position:absolute; - right: 1em; - top: 1.2em; - color:white; - width:6em; - } -div.head div.login a { - position:absolute; - right: 0em; - background:rgb(119,123,180); - border:solid rgb(102,102,153) 2px; - color:white; - font-weight:bold; - padding:0.1em 0.5em 0.1em 0.5em; - text-decoration:none; - } -div.head div.login a:hover { - background:rgb(193,193,244); - } - -h1.apc { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; } -* html h1.apc { margin-bottom:-7px; } -h1.apc a:hover { text-decoration:none; color:rgb(90,90,90); } -h1.apc div.logo span.logo { - background:rgb(119,123,180); - color:black; - border-right: solid black 1px; - border-bottom: solid black 1px; - font-style:italic; - font-size:1em; - padding-left:1.2em; - padding-right:1.2em; - text-align:right; - } -h1.apc div.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; } -h1.apc div.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; } -h1.apc div.copy { color:black; font-size:0.4em; position:absolute; right:1em; } -hr.apc { - background:white; - border-bottom:solid rgb(102,102,153) 1px; - border-style:none; - border-top:solid rgb(102,102,153) 10px; - height:12px; - margin:0; - margin-top:1px; - padding:0; -} - -ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;} -ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%} -ol.menu a { - background:rgb(153,153,204); - border:solid rgb(102,102,153) 2px; - color:white; - font-weight:bold; - margin-right:0em; - padding:0.1em 0.5em 0.1em 0.5em; - text-decoration:none; - margin-left: 5px; - } -ol.menu a.child_active { - background:rgb(153,153,204); - border:solid rgb(102,102,153) 2px; - color:white; - font-weight:bold; - margin-right:0em; - padding:0.1em 0.5em 0.1em 0.5em; - text-decoration:none; - border-left: solid black 5px; - margin-left: 0px; - } -ol.menu span.active { - background:rgb(153,153,204); - border:solid rgb(102,102,153) 2px; - color:black; - font-weight:bold; - margin-right:0em; - padding:0.1em 0.5em 0.1em 0.5em; - text-decoration:none; - border-left: solid black 5px; - } -ol.menu span.inactive { - background:rgb(193,193,244); - border:solid rgb(182,182,233) 2px; - color:white; - font-weight:bold; - margin-right:0em; - padding:0.1em 0.5em 0.1em 0.5em; - text-decoration:none; - margin-left: 5px; - } -ol.menu a:hover { - background:rgb(193,193,244); - text-decoration:none; - } - - -div.info { - background:rgb(204,204,204); - border:solid rgb(204,204,204) 1px; - margin-bottom:1em; - } -div.info h2 { - background:rgb(204,204,204); - color:black; - font-size:1em; - margin:0; - padding:0.1em 1em 0.1em 1em; - } -div.info table { - border:solid rgb(204,204,204) 1px; - border-spacing:0; - width:100%; - } -div.info table th { - background:rgb(204,204,204); - color:white; - margin:0; - padding:0.1em 1em 0.1em 1em; - } -div.info table th a.sortable { color:black; } -div.info table tr.tr-0 { background:rgb(238,238,238); } -div.info table tr.tr-1 { background:rgb(221,221,221); } -div.info table td { padding:0.3em 1em 0.3em 1em; } -div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; } -div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; } -div.info table td h3 { - color:black; - font-size:1.1em; - margin-left:-0.3em; - } - -div.graph { margin-bottom:1em } -div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; } -div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; } -div.graph table td.td-0 { background:rgb(238,238,238); } -div.graph table td.td-1 { background:rgb(221,221,221); } -div.graph table td { padding:0.2em 1em 0.4em 1em; } - -div.div1,div.div2 { margin-bottom:1em; width:35em; } -div.div3 { position:absolute; left:40em; top:1em; width:580px; } -//div.div3 { position:absolute; left:37em; top:1em; right:1em; } - -div.sorting { margin:1.5em 0em 1.5em 2em } -.center { text-align:center } -.aright { position:absolute;right:1em } -.right { text-align:right } -.ok { color:rgb(0,200,0); font-weight:bold} -.failed { color:rgb(200,0,0); font-weight:bold} - -span.box { - border: black solid 1px; - border-right:solid black 2px; - border-bottom:solid black 2px; - padding:0 0.5em 0 0.5em; - margin-right:1em; -} -span.green { background:#60F060; padding:0 0.5em 0 0.5em} -span.red { background:#D06030; padding:0 0.5em 0 0.5em } - -div.authneeded { - background:rgb(238,238,238); - border:solid rgb(204,204,204) 1px; - color:rgb(200,0,0); - font-size:1.2em; - font-weight:bold; - padding:2em; - text-align:center; - } - -input { - background:rgb(153,153,204); - border:solid rgb(102,102,153) 2px; - color:white; - font-weight:bold; - margin-right:1em; - padding:0.1em 0.5em 0.1em 0.5em; - } -//--> -</style> -</head> -<body> -<div class="head"> - <h1 class="apc"> - <div class="logo"><span class="logo"><a href="http://pecl.php.net/package/APCu">APCu</a></span></div> - <div class="nameinfo">User Cache</div> - </h1> - <div class="login"> - <?php put_login_link(); ?> - </div> - <hr class="apc"> -</div> - -<?php -// Display main Menu -echo <<<EOB - <ol class=menu> - <li><a href="$MY_SELF&OB={$MYREQUEST['OB']}&SH={$MYREQUEST['SH']}">Refresh Data</a></li> -EOB; -echo - menu_entry(OB_HOST_STATS,'View Host Stats'), - menu_entry(OB_USER_CACHE,'User Cache Entries'), - menu_entry(OB_VERSION_CHECK,'Version Check'); - -if ($AUTHENTICATED) { - echo <<<EOB - <li><a class="aright" href="$MY_SELF&CC=1&OB={$MYREQUEST['OB']}" onClick="javascript:return confirm('Are you sure?');">Clear Cache</a></li> -EOB; -} -echo <<<EOB - </ol> -EOB; - - -// CONTENT -echo <<<EOB - <div class=content> -EOB; - -// MAIN SWITCH STATEMENT - -switch ($MYREQUEST['OB']) { -// ----------------------------------------------- -// Host Stats -// ----------------------------------------------- -case OB_HOST_STATS: - $mem_size = $mem['num_seg']*$mem['seg_size']; - $mem_avail= $mem['avail_mem']; - $mem_used = $mem_size-$mem_avail; - $seg_size = bsize($mem['seg_size']); - $req_rate_user = sprintf("%.2f", $cache['nhits'] ? (($cache['nhits']+$cache['nmisses'])/($time-$cache['stime'])) : 0); - $hit_rate_user = sprintf("%.2f", $cache['nhits'] ? (($cache['nhits'])/($time-$cache['stime'])) : 0); - $miss_rate_user = sprintf("%.2f", $cache['nmisses'] ? (($cache['nmisses'])/($time-$cache['stime'])) : 0); - $insert_rate_user = sprintf("%.2f", $cache['ninserts'] ? (($cache['ninserts'])/($time-$cache['stime'])) : 0); - $apcversion = phpversion('apcu'); - $phpversion = phpversion(); - $number_vars = $cache['nentries']; - $size_vars = bsize($cache['mem_size']); - $i=0; - echo <<< EOB - <div class="info div1"><h2>General Cache Information</h2> - <table cellspacing=0><tbody> - <tr class=tr-0><td class=td-0>APCu Version</td><td>$apcversion</td></tr> - <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr> -EOB; - - if(!empty($_SERVER['SERVER_NAME'])) - echo "<tr class=tr-0><td class=td-0>APCu Host</td><td>{$_SERVER['SERVER_NAME']} $host</td></tr>\n"; - if(!empty($_SERVER['SERVER_SOFTWARE'])) - echo "<tr class=tr-1><td class=td-0>Server Software</td><td>{$_SERVER['SERVER_SOFTWARE']}</td></tr>\n"; - - echo <<<EOB - <tr class=tr-0><td class=td-0>Shared Memory</td><td>{$mem['num_seg']} Segment(s) with $seg_size - <br/> ({$cache['memory_type']} memory) - </td></tr> -EOB; - echo '<tr class=tr-1><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$cache['stime']),'</td></tr>'; - echo '<tr class=tr-0><td class=td-0>Uptime</td><td>',duration($cache['stime']),'</td></tr>'; - echo '<tr class=tr-1><td class=td-0>File Upload Support</td><td>',$cache['file_upload_progress'],'</td></tr>'; - echo <<<EOB - </tbody></table> - </div> - - <div class="info div1"><h2>Cache Information</h2> - <table cellspacing=0> - <tbody> - <tr class=tr-0><td class=td-0>Cached Variables</td><td>$number_vars ($size_vars)</td></tr> - <tr class=tr-1><td class=td-0>Hits</td><td>{$cache['nhits']}</td></tr> - <tr class=tr-0><td class=td-0>Misses</td><td>{$cache['nmisses']}</td></tr> - <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate_user cache requests/second</td></tr> - <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate_user cache requests/second</td></tr> - <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate_user cache requests/second</td></tr> - <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate_user cache requests/second</td></tr> - <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache['nexpunges']}</td></tr> - </tbody> - </table> - </div> - - <div class="info div2"><h2>Runtime Settings</h2><table cellspacing=0><tbody> -EOB; - - $j = 0; - foreach (ini_get_all('apcu') as $k => $v) { - echo "<tr class=tr-$j><td class=td-0>",$k,"</td><td>",str_replace(',',',<br />',$v['local_value']),"</td></tr>\n"; - $j = 1 - $j; - } - - if($mem['num_seg']>1 || $mem['num_seg']==1 && count($mem['block_lists'][0])>1) - $mem_note = "Memory Usage<br /><font size=-2>(multiple slices indicate fragments)</font>"; - else - $mem_note = "Memory Usage"; - - echo <<< EOB - </tbody></table> - </div> - - <div class="graph div3"><h2>Host Status Diagrams</h2> - <table cellspacing=0><tbody> -EOB; - $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10); -echo <<<EOB - <tr> - <td class=td-0>$mem_note</td> - <td class=td-1>Hits & Misses</td> - </tr> -EOB; - - echo - graphics_avail() ? - '<tr>'. - "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF?IMG=1&$time\"></td>". - "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF?IMG=2&$time\"></td></tr>\n" - : "", - '<tr>', - '<td class=td-0><span class="green box"> </span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n", - '<td class=td-1><span class="green box"> </span>Hits: ',$cache['nhits'].@sprintf(" (%.1f%%)",$cache['nhits']*100/($cache['nhits']+$cache['nmisses'])),"</td>\n", - '</tr>', - '<tr>', - '<td class=td-0><span class="red box"> </span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n", - '<td class=td-1><span class="red box"> </span>Misses: ',$cache['nmisses'].@sprintf(" (%.1f%%)",$cache['nmisses']*100/($cache['nhits']+$cache['nmisses'])),"</td>\n"; - echo <<< EOB - </tr> - </tbody></table> - - <br/> - <h2>Detailed Memory Usage and Fragmentation</h2> - <table cellspacing=0><tbody> - <tr> - <td class=td-0 colspan=2><br/> -EOB; - - // Fragementation: (freeseg - 1) / total_seg - $nseg = $freeseg = $fragsize = $freetotal = 0; - for($i=0; $i<$mem['num_seg']; $i++) { - $ptr = 0; - foreach($mem['block_lists'][$i] as $block) { - if ($block['offset'] != $ptr) { - ++$nseg; - } - $ptr = $block['offset'] + $block['size']; - /* Only consider blocks <5M for the fragmentation % */ - if($block['size']<(5*1024*1024)) $fragsize+=$block['size']; - $freetotal+=$block['size']; - } - $freeseg += count($mem['block_lists'][$i]); - } - - if ($freeseg > 1) { - $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize/$freetotal)*100,bsize($fragsize),bsize($freetotal),$freeseg); - } else { - $frag = "0%"; - } - - if (graphics_avail()) { - $size='width='.(2*GRAPH_SIZE+150).' height='.(GRAPH_SIZE+10); - echo <<<EOB - <img alt="" $size src="$PHP_SELF?IMG=3&$time"> -EOB; - } - echo <<<EOB - </br>Fragmentation: $frag - </td> - </tr> -EOB; - if(isset($mem['adist'])) { - foreach($mem['adist'] as $i=>$v) { - $cur = pow(2,$i); $nxt = pow(2,$i+1)-1; - if($i==0) $range = "1"; - else $range = "$cur - $nxt"; - echo "<tr><th align=right>$range</th><td align=right>$v</td></tr>\n"; - } - } - echo <<<EOB - </tbody></table> - </div> -EOB; - - break; - - -// ----------------------------------------------- -// User Cache Entries -// ----------------------------------------------- -case OB_USER_CACHE: - if (!$AUTHENTICATED) { - echo '<div class="error">You need to login to see the user values here!<br/> <br/>'; - put_login_link("Login now!"); - echo '</div>'; - break; - } - $fieldname='key'; - $fieldheading='User Entry Label'; - $fieldkey='key'; - - $cols=6; - echo <<<EOB - <div class=sorting><form>Scope: - <input type=hidden name=OB value={$MYREQUEST['OB']}> - <select name=SCOPE> -EOB; - echo - "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>", - "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>", - "</select>", - ", Sorting:<select name=SORT1>", - "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Hits</option>", - "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Size</option>", - "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">$fieldheading</option>", - "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Last accessed</option>", - "<option value=M",$MYREQUEST['SORT1']=='M' ? " selected":"",">Last modified</option>", - "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Created at</option>", - "<option value=D",$MYREQUEST['SORT1']=='D' ? " selected":"",">Deleted at</option>"; - if($fieldname=='info') echo - "<option value=D",$MYREQUEST['SORT1']=='T' ? " selected":"",">Timeout</option>"; - echo - '</select>', - '<select name=SORT2>', - '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>', - '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>', - '</select>', - '<select name=COUNT onChange="form.submit()">', - '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>', - '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>', - '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>', - '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>', - '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>', - '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>', - '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>', - '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>', - '</select>', - ' Search: <input name=SEARCH value="',$MYREQUEST['SEARCH'],'" type=text size=25/>', - ' <input type=submit value="GO!">', - '</form></div>'; - - if (isset($MYREQUEST['SEARCH'])) { - // Don't use preg_quote because we want the user to be able to specify a - // regular expression subpattern. - $MYREQUEST['SEARCH'] = '/'.str_replace('/', '\\/', $MYREQUEST['SEARCH']).'/i'; - if (preg_match($MYREQUEST['SEARCH'], 'test') === false) { - echo '<div class="error">Error: enter a valid regular expression as a search query.</div>'; - break; - } - } - - echo - '<div class="info"><table cellspacing=0><tbody>', - '<tr>', - '<th>',sortheader('S',$fieldheading, "&OB=".$MYREQUEST['OB']),'</th>', - '<th>',sortheader('H','Hits', "&OB=".$MYREQUEST['OB']),'</th>', - '<th>',sortheader('Z','Size', "&OB=".$MYREQUEST['OB']),'</th>', - '<th>',sortheader('A','Last accessed',"&OB=".$MYREQUEST['OB']),'</th>', - '<th>',sortheader('M','Last modified',"&OB=".$MYREQUEST['OB']),'</th>', - '<th>',sortheader('C','Created at', "&OB=".$MYREQUEST['OB']),'</th>'; - - if($fieldname=='info') { - $cols+=2; - echo '<th>',sortheader('T','Timeout',"&OB=".$MYREQUEST['OB']),'</th>'; - } - echo '<th>',sortheader('D','Deleted at',"&OB=".$MYREQUEST['OB']),'</th></tr>'; - - // builds list with alpha numeric sortable keys - // - $list = array(); - - foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $i => $entry) { - switch($MYREQUEST['SORT1']) { - case 'A': $k=sprintf('%015d-',$entry['atime']); break; - case 'H': $k=sprintf('%015d-',$entry['nhits']); break; - case 'Z': $k=sprintf('%015d-',$entry['mem_size']); break; - case 'M': $k=sprintf('%015d-',$entry['mtime']); break; - case 'C': $k=sprintf('%015d-',$entry['ctime']); break; - case 'T': $k=sprintf('%015d-',$entry['ttl']); break; - case 'D': $k=sprintf('%015d-',$entry['dtime']); break; - case 'S': $k=$entry["key"]; break; - } - if (!$AUTHENTICATED) { - // hide all path entries if not logged in - $list[$k.$entry[$fieldname]]=preg_replace('/^.*(\\/|\\\\)/','*hidden*/',$entry); - } else { - $list[$k.$entry[$fieldname]]=$entry; - } - } - - if ($list) { - // sort list - // - switch ($MYREQUEST['SORT2']) { - case "A": krsort($list); break; - case "D": ksort($list); break; - } - - // output list - $i=0; - foreach($list as $k => $entry) { - if(!$MYREQUEST['SEARCH'] || preg_match($MYREQUEST['SEARCH'], $entry[$fieldname]) != 0) { - $sh=md5($entry["key"]); - $field_value = htmlentities(strip_tags($entry[$fieldname],''), ENT_QUOTES, 'UTF-8'); - echo - '<tr class=tr-',$i%2,'>', - "<td class=td-0><a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&SH=",$sh,"\">",$field_value,'</a></td>', - '<td class="td-n center">',$entry['nhits'],'</td>', - '<td class="td-n right">',$entry['mem_size'],'</td>', - '<td class="td-n center">',date(DATE_FORMAT,$entry['atime']),'</td>', - '<td class="td-n center">',date(DATE_FORMAT,$entry['mtime']),'</td>', - '<td class="td-n center">',date(DATE_FORMAT,$entry['ctime']),'</td>'; - - if($fieldname=='info') { - if($entry['ttl']) - echo '<td class="td-n center">'.$entry['ttl'].' seconds</td>'; - else - echo '<td class="td-n center">None</td>'; - } - if ($entry['dtime']) { - - echo '<td class="td-last center">', date(DATE_FORMAT,$entry['dtime']), '</td>'; - } else if ($MYREQUEST['OB'] == OB_USER_CACHE) { - - echo '<td class="td-last center">'; - echo '[<a href="', $MY_SELF, '&OB=', $MYREQUEST['OB'], '&DU=', urlencode($entry[$fieldkey]), '">Delete Now</a>]'; - echo '</td>'; - } else { - echo '<td class="td-last center"> </td>'; - } - echo '</tr>'; - if ($sh == $MYREQUEST["SH"]) { - echo '<tr>'; - echo '<td colspan="7"><pre>'.print_r(apcu_fetch($entry['key']), 1).'</pre></td>'; - echo '</tr>'; - } - $i++; - if ($i == $MYREQUEST['COUNT']) - break; - } - } - - } else { - echo '<tr class=tr-0><td class="center" colspan=',$cols,'><i>No data</i></td></tr>'; - } - echo <<< EOB - </tbody></table> -EOB; - - if ($list && $i < count($list)) { - echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>'; - } - - echo <<< EOB - </div> -EOB; - break; - -// ----------------------------------------------- -// Version check -// ----------------------------------------------- -case OB_VERSION_CHECK: - echo <<<EOB - <div class="info"><h2>APCu Version Information</h2> - <table cellspacing=0><tbody> - <tr> - <th></th> - </tr> -EOB; - if (defined('PROXY')) { - $ctxt = stream_context_create( array( 'http' => array( 'proxy' => PROXY, 'request_fulluri' => True ) ) ); - $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apcu.rss", False, $ctxt); - } else { - $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apcu.rss"); - } - if (!$rss) { - echo '<tr class="td-last center"><td>Unable to fetch version information.</td></tr>'; - } else { - $apcversion = phpversion('apc'); - - preg_match('!<title>APCu ([0-9.]+)</title>!', $rss, $match); - echo '<tr class="tr-0 center"><td>'; - if (version_compare($apcversion, $match[1], '>=')) { - echo '<div class="ok">You are running the latest version of APCu ('.$apcversion.')</div>'; - $i = 3; - } else { - echo '<div class="failed">You are running an older version of APCu ('.$apcversion.'), - newer version '.$match[1].' is available at <a href="http://pecl.php.net/package/APCu/'.$match[1].'"> - http://pecl.php.net/package/APCu/'.$match[1].'</a> - </div>'; - $i = -1; - } - echo '</td></tr>'; - echo '<tr class="tr-0"><td><h3>Change Log:</h3><br/>'; - - preg_match_all('!<(title|description)>([^<]+)</\\1>!', $rss, $match); - next($match[2]); next($match[2]); - - while (list(,$v) = each($match[2])) { - list(,$ver) = explode(' ', $v, 2); - if ($i < 0 && version_compare($apcversion, $ver, '>=')) { - break; - } else if (!$i--) { - break; - } - echo "<b><a href=\"http://pecl.php.net/package/APCu/$ver\">".htmlspecialchars($v, ENT_QUOTES, 'UTF-8')."</a></b><br><blockquote>"; - echo nl2br(htmlspecialchars(current($match[2]), ENT_QUOTES, 'UTF-8'))."</blockquote>"; - next($match[2]); - } - echo '</td></tr>'; - } - echo <<< EOB - </tbody></table> - </div> -EOB; - break; - -} - -echo <<< EOB - </div> -EOB; - -?> - -<!-- <?php echo "\nBased on APCGUI By R.Becker\n$VERSION\n"?> --> -</body> -</html> | ||
[+] | Deleted | apcu-4.0.4.tgz/apcu-4.0.4/apc_bin.c ^ |
@@ -1,558 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2006-2011 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Brian Shire <shire@php.net> | - | Xinchen Hui <laruence@php.net> | - +----------------------------------------------------------------------+ - - */ - -/* $Id: apc_bin.c 328828 2012-12-18 15:18:39Z remi $ */ - -/* Creates an architecture specific binary output to a string or file containing - * the current cache contents. This is accomplished via the apc_copy_* functions and - * "swizzling" pointers to achieve position independence. - */ - -#include "apc_globals.h" -#include "apc_bin.h" -#include "apc_php.h" -#include "apc_sma.h" -#include "apc_pool.h" -#include "apc_cache.h" - -#include "ext/standard/md5.h" - -/* in apc_cache.c */ -extern zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC); - -#define APC_BINDUMP_DEBUG 0 - -#if APC_BINDUMP_DEBUG - -#define SWIZZLE(bd, ptr) \ - do { \ - if((long)bd < (long)ptr && (ulong)ptr < ((long)bd + bd->size)) { \ - printf("SWIZZLE: %x ~> ", ptr); \ - ptr = (void*)((long)(ptr) - (long)(bd)); \ - printf("%x in %s on line %d", ptr, __FILE__, __LINE__); \ - } else if((long)ptr > bd->size) { /* not swizzled */ \ - apc_error("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d" TSRMLS_CC, (long)bd, ptr, ((long)bd + bd->size), __FILE__, __LINE__); \ - return; \ - } \ - printf("\n"); \ - } while(0); - -#define UNSWIZZLE(bd, ptr) \ - do { \ - printf("UNSWIZZLE: %x -> ", ptr); \ - ptr = (void*)((long)(ptr) + (long)(bd)); \ - printf("%x in %s on line %d \n", ptr, __FILE__, __LINE__); \ - } while(0); - -#else /* !APC_BINDUMP_DEBUG */ - -#define SWIZZLE(bd, ptr) \ - do { \ - if((long)bd < (long)ptr && (ulong)ptr < ((long)bd + bd->size)) { \ - ptr = (void*)((long)(ptr) - (long)(bd)); \ - } else if((ulong)ptr > bd->size) { /* not swizzled */ \ - apc_error("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d" TSRMLS_CC, (long)bd, ptr, ((long)bd + bd->size), __FILE__, __LINE__); \ - return NULL; \ - } \ - } while(0); - -#define UNSWIZZLE(bd, ptr) \ - do { \ - ptr = (void*)((long)(ptr) + (long)(bd)); \ - } while(0); - -#endif - -static void *apc_bd_alloc(size_t size TSRMLS_DC); -static void apc_bd_free(void *ptr TSRMLS_DC); -static void *apc_bd_alloc_ex(void *ptr_new, size_t size TSRMLS_DC); - -typedef void (*apc_swizzle_cb_t)(apc_bd_t *bd, zend_llist *ll, void *ptr TSRMLS_DC); - -#if APC_BINDUMP_DEBUG -#define apc_swizzle_ptr(bd, ctxt, ll, ptr) _apc_swizzle_ptr(bd, ctxt, ll, (void*)ptr, __FILE__, __LINE__ TSRMLS_CC) -#else -#define apc_swizzle_ptr(bd, ctxt, ll, ptr) _apc_swizzle_ptr(bd, ctxt, ll, (void*)ptr, NULL, 0 TSRMLS_CC) -#endif - -static void _apc_swizzle_ptr(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, void **ptr, const char* file, int line TSRMLS_DC); -static void apc_swizzle_hashtable(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, HashTable *ht, apc_swizzle_cb_t swizzle_cb, int is_ptr TSRMLS_DC); -static void apc_swizzle_zval(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, zval *zv TSRMLS_DC); - -static apc_bd_t* apc_swizzle_bd(apc_bd_t* bd, zend_llist *ll TSRMLS_DC); -static int apc_unswizzle_bd(apc_bd_t *bd, int flags TSRMLS_DC); - -/* {{{ apc_bd_alloc - * callback for copy_* functions */ -static void *apc_bd_alloc(size_t size TSRMLS_DC) { - return apc_bd_alloc_ex(NULL, size TSRMLS_CC); -} /* }}} */ - -/* {{{ apc_bd_free - * callback for copy_* functions */ -static void apc_bd_free(void *ptr TSRMLS_DC) { - size_t *size; - if(zend_hash_index_find(&APCG(apc_bd_alloc_list), (ulong)ptr, (void**)&size) == FAILURE) { - apc_error("apc_bd_free could not free pointer (not found in list: %x)" TSRMLS_CC, ptr); - return; - } - APCG(apc_bd_alloc_ptr) = (void*)((size_t)APCG(apc_bd_alloc_ptr) - *size); - zend_hash_index_del(&APCG(apc_bd_alloc_list), (ulong)ptr); -} /* }}} */ - -/* {{{ apc_bd_alloc_ex - * set ranges or allocate a block of data from an already (e)malloc'd range. - * if ptr_new is not NULL, it will reset the pointer to start at ptr_new, - * with a range of size. If ptr_new is NULL, returns the next available - * block of given size. - */ -static void *apc_bd_alloc_ex(void *ptr_new, size_t size TSRMLS_DC) { - void *rval; - - rval = APCG(apc_bd_alloc_ptr); - if(ptr_new != NULL) { /* reset ptrs */ - APCG(apc_bd_alloc_ptr) = ptr_new; - APCG(apc_bd_alloc_ubptr) = (void*)((unsigned char *) ptr_new + size); - } else { /* alloc block */ - APCG(apc_bd_alloc_ptr) = (void*)((size_t)APCG(apc_bd_alloc_ptr) + size); -#if APC_BINDUMP_DEBUG - apc_notice("apc_bd_alloc: rval: 0x%x ptr: 0x%x ubptr: 0x%x size: %d" TSRMLS_CC, rval, APCG(apc_bd_alloc_ptr), APCG(apc_bd_alloc_ubptr), size); -#endif - if(APCG(apc_bd_alloc_ptr) > APCG(apc_bd_alloc_ubptr)) { - apc_error("Exceeded bounds check in apc_bd_alloc_ex by %d bytes." TSRMLS_CC, (unsigned char *) APCG(apc_bd_alloc_ptr) - (unsigned char *) APCG(apc_bd_alloc_ubptr)); - return NULL; - } - zend_hash_index_update(&APCG(apc_bd_alloc_list), (ulong)rval, &size, sizeof(size_t), NULL); - } - - return rval; -} /* }}} */ - -/* {{{ _apc_swizzle_ptr */ -static void _apc_swizzle_ptr(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, void **ptr, const char* file, int line TSRMLS_DC) { - if(*ptr) { - if((long)bd < (long)*ptr && (ulong)*ptr < ((long)bd + bd->size)) { - zend_llist_add_element(ll, &ptr); -#if APC_BINDUMP_DEBUG - printf("[%06d] apc_swizzle_ptr: %x -> %x ", zend_llist_count(ll), ptr, *ptr); - printf(" in %s on line %d \n", file, line); -#endif - } else if((ulong)ptr > bd->size) { - apc_error("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d" TSRMLS_CC, (long)bd, *ptr, ((long)bd + bd->size), file, line); \ - return; - } - } -} /* }}} */ - -/* {{{ apc_swizzle_hashtable */ -static void apc_swizzle_hashtable(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, HashTable *ht, apc_swizzle_cb_t swizzle_cb, int is_ptr TSRMLS_DC) { - uint i; - Bucket **bp, **bp_prev; - - bp = &ht->pListHead; - while(*bp) { - bp_prev = bp; - bp = &(*bp)->pListNext; - if(is_ptr) { - swizzle_cb(bd, ll, *(void**)(*bp_prev)->pData TSRMLS_CC); - apc_swizzle_ptr(bd, ctxt, ll, (*bp_prev)->pData); - } else { - swizzle_cb(bd, ll, (void**)(*bp_prev)->pData TSRMLS_CC); - } -#ifdef ZEND_ENGINE_2_4 - if ((*bp_prev)->nKeyLength) { - if (IS_INTERNED((*bp_prev)->arKey)) { - /* we should dump that internal string out */ - char *tmp = apc_bd_alloc((*bp_prev)->nKeyLength TSRMLS_CC); - memcpy(tmp, (*bp_prev)->arKey, (*bp_prev)->nKeyLength); - (*bp_prev)->arKey = tmp; - } - apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->arKey); - } -#endif - apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->pData); - if((*bp_prev)->pDataPtr) { - apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->pDataPtr); - } - if((*bp_prev)->pListLast) { - apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->pListLast); - } - if((*bp_prev)->pNext) { - apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->pNext); - } - if((*bp_prev)->pLast) { - apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->pLast); - } - apc_swizzle_ptr(bd, ctxt, ll, bp_prev); - } - for(i=0; i < ht->nTableSize; i++) { - if(ht->arBuckets[i]) { - apc_swizzle_ptr(bd, ctxt, ll, &ht->arBuckets[i]); - } - } - apc_swizzle_ptr(bd, ctxt, ll, &ht->pListTail); - - apc_swizzle_ptr(bd, ctxt, ll, &ht->arBuckets); -} /* }}} */ - -/* {{{ apc_swizzle_zval */ -static void apc_swizzle_zval(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, zval *zv TSRMLS_DC) { - - if(ctxt->copied.nTableSize) { - if(zend_hash_index_exists(&ctxt->copied, (ulong)zv)) { - return; - } - zend_hash_index_update(&ctxt->copied, (ulong)zv, (void**)&zv, sizeof(zval*), NULL); - } - - switch(Z_TYPE_P(zv) & IS_CONSTANT_TYPE_MASK) { - case IS_NULL: - case IS_LONG: - case IS_DOUBLE: - case IS_BOOL: - case IS_RESOURCE: - /* nothing to do */ - break; - case IS_CONSTANT: - case IS_STRING: - apc_swizzle_ptr(bd, ctxt, ll, &zv->value.str.val); - break; - case IS_ARRAY: - case IS_CONSTANT_ARRAY: - apc_swizzle_hashtable(bd, ctxt, ll, zv->value.ht, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC); - apc_swizzle_ptr(bd, ctxt, ll, &zv->value.ht); - break; - case IS_OBJECT: - break; - default: - assert(0); /* shouldn't happen */ - } -} /* }}} */ - -/* {{{ apc_swizzle_bd */ -static apc_bd_t* apc_swizzle_bd(apc_bd_t* bd, zend_llist *ll TSRMLS_DC) { - unsigned int i; - int count; - PHP_MD5_CTX context; - unsigned char digest[16]; - register php_uint32 crc; - void ***ptr; - void ***ptr_list; - - count = zend_llist_count(ll); - ptr_list = emalloc(count * sizeof(void**)); - ptr = zend_llist_get_first(ll); - for(i=0; i < count; i++) { -#if APC_BINDUMP_DEBUG - printf("[%06d] ", i+1); -#endif - SWIZZLE(bd, **ptr); /* swizzle ptr */ - if((long)bd < (long)*ptr && (ulong)*ptr < ((long)bd + bd->size)) { /* exclude ptrs that aren't actually included in the ptr list */ -#if APC_BINDUMP_DEBUG - printf("[------] "); -#endif - SWIZZLE(bd, *ptr); /* swizzle ptr list */ - ptr_list[i] = *ptr; - } - ptr = zend_llist_get_next(ll); - } - SWIZZLE(bd, bd->entries); - - if(count > 0) { - bd = erealloc(bd, bd->size + (count * sizeof(void**))); - bd->num_swizzled_ptrs = count; - bd->swizzled_ptrs = (void***)((unsigned char *)bd + bd->size -2); /* extra -1 for null termination */ - bd->size += count * sizeof(void**); - memcpy(bd->swizzled_ptrs, ptr_list, count * sizeof(void**)); - SWIZZLE(bd, bd->swizzled_ptrs); - } else { - bd->num_swizzled_ptrs = 0; - bd->swizzled_ptrs = NULL; - } - ((unsigned char*)bd)[((bd->size >= 1) ? (bd->size-1) : 0)] = 0; /* silence null termination for zval strings */ - efree(ptr_list); - bd->swizzled = 1; - - /* Generate MD5/CRC32 checksum */ - memset(bd->md5, 0, 16); - bd->crc=0; - - PHP_MD5Init(&context); - PHP_MD5Update(&context, (const unsigned char*)bd, bd->size); - PHP_MD5Final(digest, &context); - crc = apc_crc32((unsigned char*)bd, bd->size); - - memmove(bd->md5, digest, 16); - bd->crc = crc; - - return bd; -} /* }}} */ - -/* {{{ apc_unswizzle_bd */ -static int apc_unswizzle_bd(apc_bd_t *bd, int flags TSRMLS_DC) { - unsigned int i; - unsigned char md5_orig[16]; - unsigned char digest[16]; - PHP_MD5_CTX context; - register php_uint32 crc; - php_uint32 crc_orig; - - /* Verify the md5 or crc32 before we unswizzle */ - memmove(md5_orig, bd->md5, 16); - memset(bd->md5, 0, 16); - crc_orig = bd->crc; - bd->crc=0; - - if(flags & APC_BIN_VERIFY_MD5) { - PHP_MD5Init(&context); - PHP_MD5Update(&context, (const unsigned char*)bd, bd->size); - PHP_MD5Final(digest, &context); - if(memcmp(md5_orig, digest, 16)) { - apc_error("MD5 checksum of binary dump failed." TSRMLS_CC); - return -1; - } - } - if(flags & APC_BIN_VERIFY_CRC32) { - crc = apc_crc32((unsigned char*)bd, bd->size); - if(crc_orig != crc) { - apc_error("CRC32 checksum of binary dump failed." TSRMLS_CC); - return -1; - } - } - memcpy(bd->md5, md5_orig, 16); /* add back md5 checksum */ - bd->crc = crc_orig; - - UNSWIZZLE(bd, bd->entries); - UNSWIZZLE(bd, bd->swizzled_ptrs); - for(i=0; i < bd->num_swizzled_ptrs; i++) { - if(bd->swizzled_ptrs[i]) { - UNSWIZZLE(bd, bd->swizzled_ptrs[i]); - if(*bd->swizzled_ptrs[i] && (*bd->swizzled_ptrs[i] < (void*)bd)) { - UNSWIZZLE(bd, *bd->swizzled_ptrs[i]); - } - } - } - - bd->swizzled=0; - - return 0; -} /* }}} */ - -/* {{{ apc_bin_checkfilter */ -static int apc_bin_checkfilter(HashTable *filter, const char *key, uint key_len) { - zval **zptr; - - if(filter == NULL) { - return 1; - } - - if(zend_hash_find(filter, (char*)key, key_len, (void**)&zptr) == SUCCESS) { - if(Z_TYPE_PP(zptr) == IS_LONG && Z_LVAL_PP(zptr) == 0) { - return 0; - } - } else { - return 0; - } - - - return 1; -} /* }}} */ - -/* {{{ apc_bin_dump */ -PHP_APCU_API apc_bd_t* apc_bin_dump(apc_cache_t* cache, HashTable *user_vars TSRMLS_DC) { - apc_cache_slot_t *sp; - apc_bd_entry_t *ep; - int i, count=0; - apc_bd_t *bd; - zend_llist ll; - size_t size=0; - apc_context_t ctxt; - void *pool_ptr; - - zend_llist_init(&ll, sizeof(void*), NULL, 0); - zend_hash_init(&APCG(apc_bd_alloc_list), 0, NULL, NULL, 0); - - /* flip the hash for faster filter checking */ - user_vars = apc_flip_hash(user_vars); - - APC_RLOCK(cache->header); - - /* get size and entry counts */ - for(i=0; i < cache->nslots; i++) { - sp = cache->slots[i]; - for(; sp != NULL; sp = sp->next) { - if(apc_bin_checkfilter(user_vars, sp->key.str, sp->key.len)) { - size += sizeof(apc_bd_entry_t*) + sizeof(apc_bd_entry_t); - size += sp->value->mem_size - (sizeof(apc_cache_entry_t)); - count++; - } - } - } - - size += sizeof(apc_bd_t) +1; /* +1 for null termination */ - bd = emalloc(size); - bd->size = (unsigned int)size; - pool_ptr = emalloc(sizeof(apc_pool)); - apc_bd_alloc_ex(pool_ptr, sizeof(apc_pool) TSRMLS_CC); - - ctxt.serializer = cache->serializer; - ctxt.pool = apc_pool_create(APC_UNPOOL, apc_bd_alloc, apc_bd_free, NULL, NULL TSRMLS_CC); /* ideally the pool wouldn't be alloc'd as part of this */ - if (!ctxt.pool) { /* TODO need to cleanup */ - apc_warning("Unable to allocate memory for pool." TSRMLS_CC); - return NULL; - } - - ctxt.copy = APC_COPY_OTHER; /* avoid stupid ALLOC_ZVAL calls here, hack */ - apc_bd_alloc_ex((void*)((long)bd + sizeof(apc_bd_t)), bd->size - sizeof(apc_bd_t) -1 TSRMLS_CC); - bd->num_entries = count; - bd->entries = apc_bd_alloc_ex(NULL, sizeof(apc_bd_entry_t) * count TSRMLS_CC); - - /* User entries */ - zend_hash_init(&ctxt.copied, 0, NULL, NULL, 0); - count = 0; - for(i=0; i < cache->nslots; i++) { - sp = cache->slots[i]; - for(; sp != NULL; sp = sp->next) { - if(apc_bin_checkfilter(user_vars, sp->key.str, sp->key.len)) { - ep = &bd->entries[count]; - - /* copy key with current pool */ - ep->key.str = apc_pmemcpy(sp->key.str, sp->key.len, ctxt.pool TSRMLS_CC); - ep->key.len = sp->key.len; - - if ((Z_TYPE_P(sp->value->val) == IS_ARRAY && cache->serializer) - || Z_TYPE_P(sp->value->val) == IS_OBJECT) { - /* avoiding hash copy, hack */ - uint type = Z_TYPE_P(sp->value->val); - Z_TYPE_P(sp->value->val) = IS_STRING; - ep->val.val = apc_copy_zval(NULL, sp->value->val, &ctxt TSRMLS_CC); - - Z_TYPE_P(ep->val.val) = IS_OBJECT; - sp->value->val->type = type; - } else if (Z_TYPE_P(sp->value->val) == IS_ARRAY && !cache->serializer) { - /* this is a little complicated, we have to unserialize it first, then serialize it again */ - zval *garbage; - ctxt.copy = APC_COPY_OUT; - garbage = apc_copy_zval(NULL, sp->value->val, &ctxt TSRMLS_CC); - ctxt.copy = APC_COPY_IN; - ep->val.val = apc_copy_zval(NULL, garbage, &ctxt TSRMLS_CC); - ep->val.val->type = IS_OBJECT; - /* a memleak can not be avoided: zval_ptr_dtor(&garbage); */ - ctxt.copy = APC_COPY_OTHER; - } else { - ep->val.val = apc_copy_zval(NULL, sp->value->val, &ctxt TSRMLS_CC); - } - ep->val.ttl = sp->value->ttl; - - /* swizzle pointers */ - zend_hash_clean(&ctxt.copied); - if (ep->val.val->type == IS_OBJECT) { - apc_swizzle_ptr(bd, &ctxt, &ll, &bd->entries[count].val.val->value.str.val); - } else { - apc_swizzle_zval(bd, &ctxt, &ll, bd->entries[count].val.val TSRMLS_CC); - } - apc_swizzle_ptr(bd, &ctxt, &ll, &bd->entries[count].val.val); - apc_swizzle_ptr(bd, &ctxt, &ll, &bd->entries[count].key.str); - - count++; - } - } - } - zend_hash_destroy(&ctxt.copied); - ctxt.copied.nTableSize=0; - - /* append swizzle pointer list to bd */ - bd = apc_swizzle_bd(bd, &ll TSRMLS_CC); - zend_llist_destroy(&ll); - zend_hash_destroy(&APCG(apc_bd_alloc_list)); - - APC_RUNLOCK(cache->header); - - if(user_vars) { - zend_hash_destroy(user_vars); - efree(user_vars); - } - - efree(pool_ptr); - - return bd; -} /* }}} */ - -/* {{{ apc_bin_load */ -PHP_APCU_API int apc_bin_load(apc_cache_t* cache, apc_bd_t *bd, int flags TSRMLS_DC) { - apc_bd_entry_t *ep; - uint i; - apc_context_t ctxt; - - if (bd->swizzled) { - if(apc_unswizzle_bd(bd, flags TSRMLS_CC) < 0) { - return -1; - } - } - - for(i = 0; i < bd->num_entries; i++) { - ctxt.pool = apc_pool_create(APC_SMALL_POOL, (apc_malloc_t) apc_sma_malloc, (apc_free_t) apc_sma_free, apc_sma_protect, apc_sma_unprotect TSRMLS_CC); - if (!ctxt.pool) { /* TODO need to cleanup previous pools */ - apc_warning("Unable to allocate memory for pool." TSRMLS_CC); - goto failure; - } - ep = &bd->entries[i]; - { - zval *data; - uint use_copy = 0; - switch (Z_TYPE_P(ep->val.val)) { - case IS_OBJECT: - ctxt.copy = APC_COPY_OUT; - data = apc_copy_zval(NULL, ep->val.val, &ctxt TSRMLS_CC); - use_copy = 1; - break; - default: - data = ep->val.val; - break; - } - ctxt.copy = APC_COPY_IN; - - apc_cache_store( - cache, ep->key.str, ep->key.len, data, ep->val.ttl, 0 TSRMLS_CC); - - if (use_copy) { - zval_ptr_dtor(&data); - } - } - } - - return 0; - -failure: - apc_pool_destroy(ctxt.pool TSRMLS_CC); - apc_warning("Unable to allocate memory for apc binary load/dump functionality." TSRMLS_CC); - - HANDLE_UNBLOCK_INTERRUPTIONS(); - return -1; -} /* }}} */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: expandtab sw=4 ts=4 sts=4 fdm=marker - * vim<600: expandtab sw=4 ts=4 sts=4 - */ | ||
[+] | Deleted | apcu-4.0.4.tgz/apcu-4.0.4/apc_cache.c ^ |
@@ -1,1713 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2006-2011 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http:www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Daniel Cowgill <dcowgill@communityconnect.com> | - | Rasmus Lerdorf <rasmus@php.net> | - | Arun C. Murthy <arunc@yahoo-inc.com> | - | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> | - +----------------------------------------------------------------------+ - - This software was contributed to PHP by Community Connect Inc. in 2002 - and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1. - Future revisions and derivatives of this source code must acknowledge - Community Connect Inc. as the original contributor of this module by - leaving this note intact in the source code. - - All other licensing and usage conditions are those of the PHP Group. - - */ - -/* $Id: apc_cache.c 328743 2012-12-12 07:58:32Z ab $ */ - -#include "apc_cache.h" -#include "apc_sma.h" -#include "apc_globals.h" -#include "php_scandir.h" -#include "SAPI.h" -#include "TSRM.h" -#include "php_main.h" -#include "ext/standard/md5.h" -#include "ext/standard/php_var.h" -#include "ext/standard/php_smart_str.h" - -typedef void* (*ht_copy_fun_t)(void*, void*, apc_context_t* TSRMLS_DC); -typedef int (*ht_check_copy_fun_t)(Bucket*, va_list); - -#define CHECK(p) { if ((p) == NULL) return NULL; } - -static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC); -static HashTable* my_copy_hashtable_ex(HashTable*, HashTable* TSRMLS_DC, ht_copy_fun_t, int, apc_context_t*, ht_check_copy_fun_t, ...); -#define my_copy_hashtable( dst, src, copy_fn, holds_ptr, ctxt) \ - my_copy_hashtable_ex(dst, src TSRMLS_CC, copy_fn, holds_ptr, ctxt, NULL) - -/* {{{ make_prime */ -static int const primes[] = { - 257, /* 256 */ - 521, /* 512 */ - 1031, /* 1024 */ - 2053, /* 2048 */ - 3079, /* 3072 */ - 4099, /* 4096 */ - 5147, /* 5120 */ - 6151, /* 6144 */ - 7177, /* 7168 */ - 8209, /* 8192 */ - 9221, /* 9216 */ -10243, /* 10240 */ -11273, /* 11264 */ -12289, /* 12288 */ -13313, /* 13312 */ -14341, /* 14336 */ -15361, /* 15360 */ -16411, /* 16384 */ -17417, /* 17408 */ -18433, /* 18432 */ -19457, /* 19456 */ -0 /* sentinel */ -}; - -static int make_prime(int n) -{ - int *k = (int*)primes; - while(*k) { - if((*k) > n) return *k; - k++; - } - return *(k-1); -} -/* }}} */ - -/* {{{ make_slot */ -apc_cache_slot_t* make_slot(apc_cache_t* cache, apc_cache_key_t *key, apc_cache_entry_t* value, apc_cache_slot_t* next, time_t t TSRMLS_DC) -{ - apc_cache_slot_t* p = NULL; - - /* allocate slot */ - if ((p = value->pool->palloc(value->pool, sizeof(apc_cache_slot_t) TSRMLS_CC))) { - - /* copy identifier */ - char* strkey = (char*) apc_pmemcpy( - key->str, key->len, - value->pool TSRMLS_CC - ); - - if (strkey) { - /* set idenfieir */ - key->str = strkey; - - /* set slot data */ - p->key = key[0]; - p->value = value; - - /* set slot relation */ - p->next = next; - - /* set slot defaults */ - p->nhits = 0; - p->ctime = t; - p->atime = t; - p->dtime = 0; - } - } - - return p; -} -/* }}} */ - -/* {{{ free_slot */ -static void free_slot(apc_cache_slot_t* slot TSRMLS_DC) -{ - /* destroy slot pool */ - apc_pool_destroy( - slot->value->pool TSRMLS_CC); -} -/* }}} */ - -/* {{{ apc_cache_hash_slot - Note: These calculations can and should be done outside of a lock */ -static void apc_cache_hash_slot(apc_cache_t* cache, - char *str, - zend_uint len, - zend_ulong* hash, - zend_ulong* slot) { - (*hash) = zend_inline_hash_func(str, len); - (*slot) = (*hash) % (cache->nslots); -} /* }}} */ - -/* {{{ apc_cache_remove_slot */ -PHP_APCU_API void apc_cache_remove_slot(apc_cache_t* cache, apc_cache_slot_t** slot TSRMLS_DC) -{ - apc_cache_slot_t* dead = *slot; - - /* think here is safer */ - *slot = (*slot)->next; - - /* adjust header info */ - if (cache->header->mem_size) - cache->header->mem_size -= dead->value->mem_size; - - if (cache->header->nentries) - cache->header->nentries--; - - /* remove if there are no references */ - if (dead->value->ref_count <= 0) { - free_slot(dead TSRMLS_CC); - } else { - /* add to gc if there are still refs */ - dead->next = cache->header->gc; - dead->dtime = time(0); - cache->header->gc = dead; - } -} -/* }}} */ - -/* {{{ apc_cache_gc */ -PHP_APCU_API void apc_cache_gc(apc_cache_t* cache TSRMLS_DC) -{ - /* This function scans the list of removed cache entries and deletes any - * entry whose reference count is zero or that has been on the gc - * list for more than cache->gc_ttl seconds - * (we issue a warning in the latter case). - */ - if (!cache || !cache->header->gc) { - return; - } - - { - apc_cache_slot_t** slot = &cache->header->gc; - - while (*slot != NULL) { - time_t now = time(0); - time_t gc_sec = cache->gc_ttl ? (now - (*slot)->dtime) : 0; - - if (!(*slot)->value->ref_count || gc_sec > (time_t)cache->gc_ttl) { - apc_cache_slot_t* dead = *slot; - - /* good ol' whining */ - if (dead->value->ref_count > 0) { - apc_debug( - "GC cache entry '%s' was on gc-list for %d seconds" TSRMLS_CC, - dead->key.str, gc_sec - ); - } - - /* set next slot */ - *slot = dead->next; - - /* free slot */ - free_slot( - dead TSRMLS_CC); - - /* next */ - continue; - - } else { - slot = &(*slot)->next; - } - } - } -} -/* }}} */ - -/* {{{ php serializer */ -PHP_APCU_API int APC_SERIALIZER_NAME(php) (APC_SERIALIZER_ARGS) -{ - smart_str strbuf = {0}; - php_serialize_data_t var_hash; - PHP_VAR_SERIALIZE_INIT(var_hash); - php_var_serialize(&strbuf, (zval**)&value, &var_hash TSRMLS_CC); - PHP_VAR_SERIALIZE_DESTROY(var_hash); - if(strbuf.c) { - *buf = (unsigned char*)strbuf.c; - *buf_len = strbuf.len; - smart_str_0(&strbuf); - return 1; - } - return 0; -} /* }}} */ - -/* {{{ php unserializer */ -PHP_APCU_API int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS) -{ - const unsigned char *tmp = buf; - php_unserialize_data_t var_hash; - PHP_VAR_UNSERIALIZE_INIT(var_hash); - if(!php_var_unserialize(value, &tmp, buf + buf_len, &var_hash TSRMLS_CC)) { - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - zval_dtor(*value); - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %ld bytes", (long)(tmp - buf), (long)buf_len); - (*value)->type = IS_NULL; - return 0; - } - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - return 1; -} /* }}} */ - -/* {{{ apc_cache_create */ -PHP_APCU_API apc_cache_t* apc_cache_create(apc_sma_t* sma, apc_serializer_t* serializer, int size_hint, int gc_ttl, int ttl, long smart, zend_bool defend TSRMLS_DC) { - apc_cache_t* cache; - int cache_size; - int nslots; - - /* calculate number of slots */ - nslots = make_prime(size_hint > 0 ? size_hint : 2000); - - /* allocate pointer by normal means */ - cache = (apc_cache_t*) apc_emalloc(sizeof(apc_cache_t) TSRMLS_CC); - - /* calculate cache size for shm allocation */ - cache_size = sizeof(apc_cache_header_t) + nslots*sizeof(apc_cache_slot_t*); - - /* allocate shm */ - cache->shmaddr = sma->smalloc(cache_size TSRMLS_CC); - if(!cache->shmaddr) { - apc_error("Unable to allocate shared memory for cache structures. (Perhaps your shared memory size isn't large enough?). " TSRMLS_CC); - return NULL; - } - - /* zero shm */ - memset(cache->shmaddr, 0, cache_size); - - /* set default header */ - cache->header = (apc_cache_header_t*) cache->shmaddr; - - cache->header->nhits = 0; - cache->header->nmisses = 0; - cache->header->nentries = 0; - cache->header->nexpunges = 0; - cache->header->gc = NULL; - cache->header->stime = time(NULL); - cache->header->state |= APC_CACHE_ST_NONE; - - /* set cache options */ - cache->slots = (apc_cache_slot_t**) (((char*) cache->shmaddr) + sizeof(apc_cache_header_t)); - cache->sma = sma; - cache->serializer = serializer; - cache->nslots = nslots; - cache->gc_ttl = gc_ttl; - cache->ttl = ttl; - cache->smart = smart; - cache->defend = defend; - - /* header lock */ - CREATE_LOCK(&cache->header->lock); - - /* zero slots */ - memset(cache->slots, 0, sizeof(apc_cache_slot_t*)*nslots); - - return cache; -} /* }}} */ - -/* {{{ apc_cache_store */ -PHP_APCU_API zend_bool apc_cache_store(apc_cache_t* cache, char *strkey, zend_uint keylen, const zval *val, const zend_uint ttl, const zend_bool exclusive TSRMLS_DC) { - apc_cache_entry_t *entry; - apc_cache_key_t key; - time_t t; - apc_context_t ctxt={0,}; - zend_bool ret = 0; - - t = apc_time(); - - /* initialize a context suitable for making an insert */ - if (apc_cache_make_context(cache, &ctxt, APC_CONTEXT_SHARE, APC_SMALL_POOL, APC_COPY_IN, 0 TSRMLS_CC)) { - - /* initialize the key for insertion */ - if (apc_cache_make_key(&key, strkey, keylen TSRMLS_CC)) { - - /* run cache defense */ - if (!apc_cache_defense(cache, &key TSRMLS_CC)) { - - /* initialize the entry for insertion */ - if ((entry = apc_cache_make_entry(&ctxt, &key, val, ttl TSRMLS_CC))) { - - /* execute an insertion */ - if (apc_cache_insert(cache, key, entry, &ctxt, t, exclusive TSRMLS_CC)) { - ret = 1; - } - } - } - } - - /* in any case of failure the context should be destroyed */ - if (!ret) { - apc_cache_destroy_context(&ctxt TSRMLS_CC); - } - } - - return ret; -} /* }}} */ - -/* {{{ data_unserialize */ -static zval* data_unserialize(const char *filename TSRMLS_DC) -{ - zval* retval; - long len = 0; - struct stat sb; - char *contents, *tmp; - FILE *fp; - php_unserialize_data_t var_hash = {0,}; - - if(VCWD_STAT(filename, &sb) == -1) { - return NULL; - } - - fp = fopen(filename, "rb"); - - len = sizeof(char)*sb.st_size; - - tmp = contents = malloc(len); - - if(!contents) { - fclose(fp); - return NULL; - } - - if(fread(contents, 1, len, fp) < 1) { - fclose(fp); - free(contents); - return NULL; - } - - MAKE_STD_ZVAL(retval); - - PHP_VAR_UNSERIALIZE_INIT(var_hash); - - /* I wish I could use json */ - if(!php_var_unserialize(&retval, (const unsigned char**)&tmp, (const unsigned char*)(contents+len), &var_hash TSRMLS_CC)) { - fclose(fp); - zval_ptr_dtor(&retval); - return NULL; - } - - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - - free(contents); - fclose(fp); - - return retval; -} - -static int apc_load_data(apc_cache_t* cache, const char *data_file TSRMLS_DC) -{ - char *p; - char key[MAXPATHLEN] = {0,}; - unsigned int key_len; - zval *data; - - p = strrchr(data_file, DEFAULT_SLASH); - - if(p && p[1]) { - strlcpy(key, p+1, sizeof(key)); - p = strrchr(key, '.'); - - if(p) { - p[0] = '\0'; - key_len = strlen(key)+1; - - data = data_unserialize(data_file TSRMLS_CC); - if(data) { - apc_cache_store(cache, key, key_len, data, 0, 1 TSRMLS_CC); - } - return 1; - } - } - - return 0; -} - -/* {{{ apc_cache_preload shall load the prepared data files in path into the specified cache */ -PHP_APCU_API zend_bool apc_cache_preload(apc_cache_t* cache, const char *path TSRMLS_DC) -{ -#ifndef ZTS - zend_bool result = 0; - char file[MAXPATHLEN]={0,}; - int ndir, i; - char *p = NULL; - struct dirent **namelist = NULL; - - if ((ndir = php_scandir(path, &namelist, 0, php_alphasort)) > 0) { - for (i = 0; i < ndir; i++) { - /* check for extension */ - if (!(p = strrchr(namelist[i]->d_name, '.')) - || (p && strcmp(p, ".data"))) { - free(namelist[i]); - continue; - } - - snprintf(file, MAXPATHLEN, "%s%c%s", - path, DEFAULT_SLASH, namelist[i]->d_name); - - if(apc_load_data(cache, file TSRMLS_CC)) { - result = 1; - } - free(namelist[i]); - } - free(namelist); - } - return result; -#else - apc_error("Cannot load data from apc.preload_path=%s in thread-safe mode" TSRMLS_CC, path); - return 0; -#endif -} /* }}} */ - -/* {{{ apc_cache_release */ -PHP_APCU_API void apc_cache_release(apc_cache_t* cache, apc_cache_entry_t* entry TSRMLS_DC) -{ - entry->ref_count--; -} -/* }}} */ - -/* {{{ apc_cache_destroy */ -PHP_APCU_API void apc_cache_destroy(apc_cache_t* cache TSRMLS_DC) -{ - if (!cache) { - return; - } - - /* destroy lock */ - DESTROY_LOCK(&cache->header->lock); - - /* XXX this is definitely a leak, but freeing this causes all the apache - children to freeze. It might be because the segment is shared between - several processes. To figure out is how to free this safely. */ - /*apc_sma_free(cache->shmaddr);*/ - apc_efree(cache TSRMLS_CC); -} -/* }}} */ - -/* {{{ apc_cache_real_expunge */ -PHP_APCU_API void apc_cache_real_expunge(apc_cache_t* cache TSRMLS_DC) { - /* increment counter */ - cache->header->nexpunges++; - - /* expunge */ - { - zend_ulong i; - - for (i = 0; i < cache->nslots; i++) { - apc_cache_slot_t* p = cache->slots[i]; - while (p) { - apc_cache_remove_slot(cache, &p TSRMLS_CC); - } - cache->slots[i] = NULL; - } - } - - /* set new time so counters make sense */ - cache->header->stime = apc_time(); - - /* reset counters */ - cache->header->ninserts = 0; - cache->header->nentries = 0; - cache->header->nhits = 0; - cache->header->nmisses = 0; - - /* resets lastkey */ - memset(&cache->header->lastkey, 0, sizeof(apc_cache_key_t)); -} /* }}} */ - -/* {{{ apc_cache_clear */ -PHP_APCU_API void apc_cache_clear(apc_cache_t* cache TSRMLS_DC) -{ - /* check there is a cache and it is not busy */ - if(!cache || apc_cache_busy(cache TSRMLS_CC)) { - return; - } - - /* lock header */ - APC_LOCK(cache->header); - - /* set busy */ - cache->header->state |= APC_CACHE_ST_BUSY; - - /* expunge cache */ - apc_cache_real_expunge(cache TSRMLS_CC); - - /* set info */ - cache->header->stime = apc_time(); - cache->header->nexpunges = 0; - - /* unset busy */ - cache->header->state &= ~APC_CACHE_ST_BUSY; - - /* unlock header */ - APC_UNLOCK(cache->header); -} -/* }}} */ - -/* {{{ apc_cache_default_expunge */ -PHP_APCU_API void apc_cache_default_expunge(apc_cache_t* cache, size_t size TSRMLS_DC) -{ - time_t t; - size_t suitable = 0L; - size_t available = 0L; - - t = apc_time(); - - /* check there is a cache, and it is not busy */ - if(!cache || apc_cache_busy(cache TSRMLS_CC)) { - return; - } - - /* get the lock for header */ - APC_LOCK(cache->header); - - /* update state in header */ - cache->header->state |= APC_CACHE_ST_BUSY; - - /* make suitable selection */ - suitable = (cache->smart > 0L) ? (size_t) (cache->smart * size) : (size_t) (cache->sma->size/2); - - /* gc */ - apc_cache_gc(cache TSRMLS_CC); - - /* get available */ - available = cache->sma->get_avail_mem(); - - /* perform expunge processing */ - if(!cache->ttl) { - - /* check it is necessary to expunge */ - if (available < suitable) { - apc_cache_real_expunge(cache TSRMLS_CC); - } - } else { - apc_cache_slot_t **slot; - - /* check that expunge is necessary */ - if (available < suitable) { - zend_ulong i; - - /* look for junk */ - for (i = 0; i < cache->nslots; i++) { - slot = &cache->slots[i]; - while (*slot) { - /* - * Entry TTL has precedence over cache TTL - */ - if((*slot)->value->ttl) { - if((time_t) ((*slot)->ctime + (*slot)->value->ttl) < t) { - apc_cache_remove_slot(cache, slot TSRMLS_CC); - continue; - } - } else if(cache->ttl) { - if((time_t) ((*slot)->ctime + cache->ttl) < t) { - apc_cache_remove_slot(cache, slot TSRMLS_CC); - continue; - } - } - - /* grab next slot */ - slot = &(*slot)->next; - } - } - - /* if the cache now has space, then reset last key */ - if (cache->sma->get_avail_size(size)) { - /* wipe lastkey */ - memset(&cache->header->lastkey, 0, sizeof(apc_cache_key_t)); - } else { - /* with not enough space left in cache, we are forced to expunge */ - apc_cache_real_expunge(cache TSRMLS_CC); - } - } - } - - /* we are done */ - cache->header->state &= ~APC_CACHE_ST_BUSY; - - /* unlock header */ - APC_UNLOCK(cache->header); -} -/* }}} */ - -/* {{{ apc_cache_make_context */ -PHP_APCU_API zend_bool apc_cache_make_context(apc_cache_t* cache, - apc_context_t* context, - apc_context_type context_type, - apc_pool_type pool_type, - apc_copy_type copy_type, - uint force_update TSRMLS_DC) { - switch (context_type) { - case APC_CONTEXT_SHARE: { - return apc_cache_make_context_ex( - context, - cache->serializer, - (apc_malloc_t) cache->sma->smalloc, - cache->sma->sfree, - cache->sma->protect, - cache->sma->unprotect, - pool_type, copy_type, force_update TSRMLS_CC - ); - } break; - - case APC_CONTEXT_NOSHARE: { - return apc_cache_make_context_ex( - context, - cache->serializer, - apc_php_malloc, apc_php_free, NULL, NULL, - pool_type, copy_type, force_update TSRMLS_CC - ); - } break; - - case APC_CONTEXT_NONE: - /* never used, just to make gcc warning free */ - break; - } - - return 0; -} /* }}} */ - -/* {{{ apc_cache_make_context_ex */ -PHP_APCU_API zend_bool apc_cache_make_context_ex(apc_context_t* context, - apc_serializer_t* serializer, - apc_malloc_t _malloc, - apc_free_t _free, - apc_protect_t _protect, - apc_unprotect_t _unprotect, - apc_pool_type pool_type, - apc_copy_type copy_type, - uint force_update TSRMLS_DC) { - /* attempt to create the pool */ - context->pool = apc_pool_create( - pool_type, _malloc, _free, _protect, _unprotect TSRMLS_CC - ); - - if (!context->pool) { - apc_warning("Unable to allocate memory for pool." TSRMLS_CC); - return 0; - } - - /* set context information */ - context->serializer = serializer; - context->copy = copy_type; - context->force_update = force_update; - - /* set this to avoid memory errors */ - memset(&context->copied, 0, sizeof(HashTable)); - - return 1; -} /* }}} */ - -/* {{{ apc_context_destroy */ -PHP_APCU_API zend_bool apc_cache_destroy_context(apc_context_t* context TSRMLS_DC) { - if (!context->pool) { - return 0; - } - - apc_pool_destroy(context->pool TSRMLS_CC); - - return 1; -} /* }}} */ - -/* {{{ apc_cache_insert */ -PHP_APCU_API zend_bool apc_cache_insert(apc_cache_t* cache, - apc_cache_key_t key, - apc_cache_entry_t* value, - apc_context_t* ctxt, - time_t t, - zend_bool exclusive TSRMLS_DC) -{ - zend_bool result = 0; - - /* at least */ - if (!value) { - return result; - } - - /* check we are able to deal with this request */ - if (!cache || apc_cache_busy(cache TSRMLS_CC)) { - return result; - } - - /* lock header */ - APC_LOCK(cache->header); - - /* process deleted list */ - apc_cache_gc(cache TSRMLS_CC); - - /* make the insertion */ - { - apc_cache_slot_t** slot; - - /* - * select appropriate slot ... - */ - slot = &cache->slots[key.h % cache->nslots]; - - while (*slot) { - - /* check for a match by hash and string */ - if (((*slot)->key.h == key.h) && (!memcmp((*slot)->key.str, key.str, key.len))) { - - /* - * At this point we have found the user cache entry. If we are doing - * an exclusive insert (apc_add) we are going to bail right away if - * the user entry already exists and it has no ttl, or - * there is a ttl and the entry has not timed out yet. - */ - if(exclusive) { - if (!(*slot)->value->ttl || (time_t) ((*slot)->ctime + (*slot)->value->ttl) >= t) { - goto nothing; - } - } - apc_cache_remove_slot(cache, slot TSRMLS_CC); - break; - } else - - /* - * This is a bit nasty. The idea here is to do runtime cleanup of the linked list of - * slot entries so we don't always have to skip past a bunch of stale entries. We check - * for staleness here and get rid of them by first checking to see if the cache has a global - * access ttl on it and removing entries that haven't been accessed for ttl seconds and secondly - * we see if the entry has a hard ttl on it and remove it if it has been around longer than its ttl - */ - if((cache->ttl && (time_t)(*slot)->atime < (t - (time_t)cache->ttl)) || - ((*slot)->value->ttl && (time_t) ((*slot)->ctime + (*slot)->value->ttl) < t)) { - apc_cache_remove_slot(cache, slot TSRMLS_CC); - continue; - } - - /* set next slot */ - slot = &(*slot)->next; - } - - if ((*slot = make_slot(cache, &key, value, *slot, t TSRMLS_CC)) != NULL) { - /* set value size from pool size */ - value->mem_size = ctxt->pool->size; - - cache->header->mem_size += ctxt->pool->size; - cache->header->nentries++; - cache->header->ninserts++; - } else { - goto nothing; - } - } - - /* unlock and return succesfull */ - APC_UNLOCK(cache->header); - - return 1; - - /* bail */ -nothing: - APC_UNLOCK(cache->header); - - return 0; -} -/* }}} */ - -/* {{{ apc_cache_find */ -PHP_APCU_API apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, char *strkey, zend_uint keylen, time_t t TSRMLS_DC) -{ - /* check we are able to deal with the request */ - if(!cache || apc_cache_busy(cache TSRMLS_CC)) { - return NULL; - } - - /* we only declare a volatile we need */ - { - apc_cache_slot_t** slot; - zend_ulong h, s; - - volatile apc_cache_entry_t* value = NULL; - - /* calculate hash and slot */ - apc_cache_hash_slot(cache, strkey, keylen, &h, &s); - - /* read lock header */ - APC_RLOCK(cache->header); - - /* find head */ - slot = &cache->slots[s]; - - while (*slot) { - /* check for a matching key by has and identifier */ - if ((h == (*slot)->key.h) && !memcmp((*slot)->key.str, strkey, keylen)) { - - /* Check to make sure this entry isn't expired by a hard TTL */ - if((*slot)->value->ttl && (time_t) ((*slot)->ctime + (*slot)->value->ttl) < t) { - /* increment misses on cache */ - cache->header->nmisses++; - - /* unlock header */ - APC_RUNLOCK(cache->header); - - return NULL; - } - - /* Otherwise we are fine, increase counters and return the cache entry */ - (*slot)->nhits++; - (*slot)->value->ref_count++; - (*slot)->atime = t; - - /* set cache num hits */ - cache->header->nhits++; - - /* grab value */ - value = (*slot)->value; - - /* unlock header */ - APC_RUNLOCK(cache->header); - - return (apc_cache_entry_t*)value; - } - - /* next */ - slot = &(*slot)->next; - } - - /* not found, so increment misses */ - cache->header->nmisses++; - - /* unlock header */ - APC_RUNLOCK(cache->header); - } - - return NULL; -} -/* }}} */ - -/* {{{ apc_cache_fetch */ -PHP_APCU_API zend_bool apc_cache_fetch(apc_cache_t* cache, char* strkey, zend_uint keylen, time_t t, zval **dst TSRMLS_DC) -{ - apc_cache_entry_t *entry; - zend_bool ret = 0; - - /* find the entry */ - if ((entry = apc_cache_find(cache, strkey, keylen, t TSRMLS_CC))) { - /* context for copying out */ - apc_context_t ctxt = {0, }; - - /* create unpool context */ - if (apc_cache_make_context(cache, &ctxt, APC_CONTEXT_NOSHARE, APC_UNPOOL, APC_COPY_OUT, 0 TSRMLS_CC)) { - - /* copy to destination */ - apc_cache_fetch_zval(&ctxt, *dst, entry->val TSRMLS_CC); - - /* release entry */ - apc_cache_release( - cache, entry TSRMLS_CC); - - /* destroy context */ - apc_cache_destroy_context(&ctxt TSRMLS_CC ); - - /* set result */ - ret = 1; - } - } - - return ret; -} /* }}} */ - -/* {{{ apc_cache_exists */ -PHP_APCU_API apc_cache_entry_t* apc_cache_exists(apc_cache_t* cache, char *strkey, zend_uint keylen, time_t t TSRMLS_DC) -{ - if(apc_cache_busy(cache TSRMLS_CC)) - { - /* cache cleanup in progress */ - return NULL; - } - - /* we only declare volatiles we need */ - { - apc_cache_slot_t** slot; - - volatile apc_cache_entry_t* value = NULL; - zend_ulong h, s; - - /* get hash and slot */ - apc_cache_hash_slot(cache, strkey, keylen, &h, &s); - - /* read lock header */ - APC_RLOCK(cache->header); - - /* find head */ - slot = &cache->slots[s]; - - while (*slot) { - /* check for match by hash and identifier */ - if ((h == (*slot)->key.h) && - !memcmp((*slot)->key.str, strkey, keylen)) { - - /* Check to make sure this entry isn't expired by a hard TTL */ - if((*slot)->value->ttl && (time_t) ((*slot)->ctime + (*slot)->value->ttl) < t) { - /* marked as a miss */ - cache->header->nmisses++; - - /* unlock header */ - APC_RUNLOCK(cache->header); - - return NULL; - } - - /* Return the cache entry ptr */ - value = (*slot)->value; - - /* unlock header */ - APC_RUNLOCK(cache->header); - - return (apc_cache_entry_t*)value; - } - - slot = &(*slot)->next; - } - - /* unlock header */ - APC_RUNLOCK(cache->header); - } - - return NULL; -} -/* }}} */ - -/* {{{ apc_cache_update */ -PHP_APCU_API zend_bool apc_cache_update(apc_cache_t* cache, char *strkey, zend_uint keylen, apc_cache_updater_t updater, void* data TSRMLS_DC) -{ - apc_cache_slot_t** slot; - - zend_bool retval = 0; - zend_ulong h, s; - - if(apc_cache_busy(cache TSRMLS_CC)) - { - /* cannot service request right now */ - return 0; - } - - /* calculate hash */ - apc_cache_hash_slot(cache, strkey, keylen, &h, &s); - - /* lock header */ - APC_LOCK(cache->header); - - /* find head */ - slot = &cache->slots[s]; - - while (*slot) { - /* check for a match by hash and identifier */ - if ((h == (*slot)->key.h) && - !memcmp((*slot)->key.str, strkey, keylen)) { - /* attempt to perform update */ - switch(Z_TYPE_P((*slot)->value->val) & ~IS_CONSTANT_INDEX) { - case IS_ARRAY: - case IS_CONSTANT_ARRAY: - case IS_OBJECT: - { - if(cache->serializer) { - retval = 0; - break; - } else { - /* fall through */ - } - } - /* fall through */ - default: - { - /* executing update */ - retval = updater( - cache, (*slot)->value, data); - - /* set modified time */ - (*slot)->key.mtime = apc_time(); - } - break; - } - /* unlock header */ - APC_UNLOCK(cache->header); - - return retval; - } - - /* set next slot */ - slot = &(*slot)->next; - } - - /* unlock header */ - APC_UNLOCK(cache->header); - - return 0; -} -/* }}} */ - -/* {{{ apc_cache_delete */ -PHP_APCU_API zend_bool apc_cache_delete(apc_cache_t* cache, char *strkey, zend_uint keylen TSRMLS_DC) -{ - apc_cache_slot_t** slot; - - zend_ulong h, s; - - if (!cache) { - return 1; - } - - /* calculate hash and slot */ - apc_cache_hash_slot(cache, strkey, keylen, &h, &s); - - /* lock cache */ - APC_LOCK(cache->header); - - /* find head */ - slot = &cache->slots[s]; - - while (*slot) { - /* check for a match by hash and identifier */ - if ((h == (*slot)->key.h) && - !memcmp((*slot)->key.str, strkey, keylen)) { - /* executing removal */ - apc_cache_remove_slot( - cache, slot TSRMLS_CC); - goto deleted; - } - - /* continue locking */ - slot = &(*slot)->next; - } - - /* unlock header */ - APC_UNLOCK(cache->header); - - return 0; - -deleted: - /* unlock deleted */ - APC_UNLOCK(cache->header); - - return 1; -} -/* }}} */ - -/* {{{ apc_cache_make_key */ -PHP_APCU_API zend_bool apc_cache_make_key(apc_cache_key_t* key, char* str, zend_ulong len TSRMLS_DC) -{ - assert(key != NULL); - - if (!str) { - return 0; - } - - if (!len) - len = strlen(str) + 1; - - key->str = str; - key->len = len; - key->h = zend_inline_hash_func((char *)key->str, key->len); - key->mtime = apc_time(); - - return 1; -} -/* }}} */ - -/* {{{ my_serialize_object */ -static zval* my_serialize_object(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC) -{ - smart_str buf = {0}; - apc_pool* pool = ctxt->pool; - apc_serialize_t serialize = APC_SERIALIZER_NAME(php); - void *config = NULL; - - if(ctxt->serializer) { - serialize = ctxt->serializer->serialize; - config = (ctxt->serializer->config != NULL) ? ctxt->serializer->config : ctxt; - } - - if(serialize((unsigned char**)&buf.c, &buf.len, src, config TSRMLS_CC)) { - dst->type = src->type & ~IS_CONSTANT_INDEX; - dst->value.str.len = buf.len; - CHECK(dst->value.str.val = apc_pmemcpy(buf.c, (buf.len + 1), pool TSRMLS_CC)); - } - - if(buf.c) { - smart_str_free(&buf); - } - - return dst; -} -/* }}} */ - -/* {{{ my_unserialize_object */ -static zval* my_unserialize_object(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC) -{ - apc_unserialize_t unserialize = APC_UNSERIALIZER_NAME(php); - unsigned char *p = (unsigned char*)Z_STRVAL_P(src); - void *config = NULL; - - if(ctxt->serializer) { - unserialize = ctxt->serializer->unserialize; - config = (ctxt->serializer->config != NULL) ? ctxt->serializer->config : ctxt; - } - - if(unserialize(&dst, p, Z_STRLEN_P(src), config TSRMLS_CC)) { - return dst; - } else { - zval_dtor(dst); - dst->type = IS_NULL; - } - return dst; -} -/* }}} */ - - -/* {{{ my_copy_hashtable_ex */ -static APC_HOTSPOT HashTable* my_copy_hashtable_ex(HashTable* dst, - HashTable* src TSRMLS_DC, - ht_copy_fun_t copy_fn, - int holds_ptrs, - apc_context_t* ctxt, - ht_check_copy_fun_t check_fn, - ...) -{ - Bucket* curr = NULL; - Bucket* prev = NULL; - Bucket* newp = NULL; - int first = 1; - apc_pool* pool = ctxt->pool; - - assert(src != NULL); - - if (!dst) { - CHECK(dst = (HashTable*) pool->palloc(pool, sizeof(src[0]) TSRMLS_CC)); - } - - memcpy(dst, src, sizeof(src[0])); - - /* allocate buckets for the new hashtable */ - CHECK((dst->arBuckets = pool->palloc(pool, (dst->nTableSize * sizeof(Bucket*)) TSRMLS_CC))); - - memset(dst->arBuckets, 0, dst->nTableSize * sizeof(Bucket*)); - dst->pInternalPointer = NULL; - dst->pListHead = NULL; - - for (curr = src->pListHead; curr != NULL; curr = curr->pListNext) { - int n = curr->h % dst->nTableSize; - - if(check_fn) { - va_list args; - va_start(args, check_fn); - - /* Call the check_fn to see if the current bucket - * needs to be copied out - */ - if(!check_fn(curr, args)) { - dst->nNumOfElements--; - va_end(args); - continue; - } - - va_end(args); - } - - /* create a copy of the bucket 'curr' */ -#ifdef ZEND_ENGINE_2_4 - if (!curr->nKeyLength) { - CHECK((newp = (Bucket*) apc_pmemcpy(curr, sizeof(Bucket), pool TSRMLS_CC))); - } else if (IS_INTERNED(curr->arKey)) { - CHECK((newp = (Bucket*) apc_pmemcpy(curr, sizeof(Bucket), pool TSRMLS_CC))); - } else { - /* I repeat, this is ugly */ - CHECK((newp = (Bucket*) apc_pmemcpy(curr, sizeof(Bucket) + curr->nKeyLength, pool TSRMLS_CC))); - newp->arKey = (const char*)(newp+1); - } -#else - CHECK((newp = (Bucket*) apc_pmemcpy(curr, - (sizeof(Bucket) + curr->nKeyLength - 1), - pool TSRMLS_CC))); -#endif - - /* insert 'newp' into the linked list at its hashed index */ - if (dst->arBuckets[n]) { - newp->pNext = dst->arBuckets[n]; - newp->pLast = NULL; - newp->pNext->pLast = newp; - } else { - newp->pNext = newp->pLast = NULL; - } - - dst->arBuckets[n] = newp; - - /* copy the bucket data using our 'copy_fn' callback function */ - CHECK((newp->pData = copy_fn(NULL, curr->pData, ctxt TSRMLS_CC))); - - if (holds_ptrs) { - memcpy(&newp->pDataPtr, newp->pData, sizeof(void*)); - } - else { - newp->pDataPtr = NULL; - } - - /* insert 'newp' into the table-thread linked list */ - newp->pListLast = prev; - newp->pListNext = NULL; - - if (prev) { - prev->pListNext = newp; - } - - if (first) { - dst->pListHead = newp; - first = 0; - } - - prev = newp; - } - - dst->pListTail = newp; - - zend_hash_internal_pointer_reset(dst); - - return dst; -} -/* }}} */ - - -/* {{{ my_copy_zval_ptr */ -static zval** my_copy_zval_ptr(zval** dst, const zval** src, apc_context_t* ctxt TSRMLS_DC) -{ - zval* dst_new; - apc_pool* pool = ctxt->pool; - int usegc = (ctxt->copy == APC_COPY_OUT); - - assert(src != NULL); - - if (!dst) { - CHECK(dst = (zval**) pool->palloc(pool, sizeof(zval*) TSRMLS_CC)); - } - - if(usegc) { - ALLOC_ZVAL(dst[0]); - CHECK(dst[0]); - } else { - CHECK((dst[0] = (zval*) pool->palloc(pool, sizeof(zval) TSRMLS_CC))); - } - - CHECK((dst_new = my_copy_zval(*dst, *src, ctxt TSRMLS_CC))); - - if(dst_new != *dst) { - if(usegc) { - FREE_ZVAL(dst[0]); - } - *dst = dst_new; - } - - return dst; -} -/* }}} */ - -/* {{{ my_copy_zval */ -static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC) -{ - zval **tmp; - apc_pool* pool = ctxt->pool; - - assert(dst != NULL); - assert(src != NULL); - - memcpy(dst, src, sizeof(src[0])); - - if(ctxt->copied.nTableSize) { - if(zend_hash_index_find(&ctxt->copied, (ulong)src, (void**)&tmp) == SUCCESS) { - if(Z_ISREF_P((zval*)src)) { - Z_SET_ISREF_PP(tmp); - } - Z_ADDREF_PP(tmp); - return *tmp; - } - - zend_hash_index_update(&ctxt->copied, (ulong)src, (void**)&dst, sizeof(zval*), NULL); - } - - if(ctxt->copy == APC_COPY_OUT || ctxt->copy == APC_COPY_IN) { - /* deep copies are refcount(1), but moved up for recursive - * arrays, which end up being add_ref'd during its copy. */ - Z_SET_REFCOUNT_P(dst, 1); - Z_UNSET_ISREF_P(dst); - } else { - /* code uses refcount=2 for consts */ - Z_SET_REFCOUNT_P(dst, Z_REFCOUNT_P((zval*)src)); - Z_SET_ISREF_TO_P(dst, Z_ISREF_P((zval*)src)); - } - - switch (src->type & IS_CONSTANT_TYPE_MASK) { - case IS_RESOURCE: - case IS_BOOL: - case IS_LONG: - case IS_DOUBLE: - case IS_NULL: - break; - - case IS_CONSTANT: - case IS_STRING: - if (src->value.str.val) { - CHECK(dst->value.str.val = apc_pmemcpy(src->value.str.val, - src->value.str.len+1, - pool TSRMLS_CC)); - } - break; - - case IS_ARRAY: - case IS_CONSTANT_ARRAY: - if(ctxt->serializer == NULL) { - - CHECK(dst->value.ht = - my_copy_hashtable(NULL, - src->value.ht, - (ht_copy_fun_t) my_copy_zval_ptr, - 1, - ctxt)); - break; - } else { - /* fall through to object case */ - } - - case IS_OBJECT: - - dst->type = IS_NULL; - if(ctxt->copy == APC_COPY_IN) { - dst = my_serialize_object(dst, src, ctxt TSRMLS_CC); - } else if(ctxt->copy == APC_COPY_OUT) { - dst = my_unserialize_object(dst, src, ctxt TSRMLS_CC); - } - break; -#ifdef ZEND_ENGINE_2_4 - case IS_CALLABLE: - /* XXX implement this */ - assert(0); - break; -#endif - - default: - assert(0); - } - - return dst; -} -/* }}} */ - -/* {{{ apc_copy_zval */ -PHP_APCU_API zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC) -{ - apc_pool* pool = ctxt->pool; - - assert(src != NULL); - - if (!dst) { - if(ctxt->copy == APC_COPY_OUT) { - ALLOC_ZVAL(dst); - CHECK(dst); - } else { - CHECK(dst = (zval*) pool->palloc(pool, sizeof(zval) TSRMLS_CC)); - } - } - - CHECK(dst = my_copy_zval(dst, src, ctxt TSRMLS_CC)); - return dst; -} -/* }}} */ - -/* {{{ apc_cache_store_zval */ -PHP_APCU_API zval* apc_cache_store_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC) -{ - if (Z_TYPE_P(src) == IS_ARRAY) { - /* Maintain a list of zvals we've copied to properly handle recursive structures */ - zend_hash_init(&ctxt->copied, 0, NULL, NULL, 0); - dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC); - zend_hash_destroy(&ctxt->copied); - ctxt->copied.nTableSize=0; - } else { - dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC); - } - - - return dst; -} -/* }}} */ - -/* {{{ apc_cache_fetch_zval */ -PHP_APCU_API zval* apc_cache_fetch_zval(apc_context_t* ctxt, zval* dst, const zval* src TSRMLS_DC) -{ - if (Z_TYPE_P(src) == IS_ARRAY) { - /* Maintain a list of zvals we've copied to properly handle recursive structures */ - zend_hash_init(&ctxt->copied, 0, NULL, NULL, 0); - dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC); - zend_hash_destroy(&ctxt->copied); - ctxt->copied.nTableSize=0; - } else { - dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC); - } - - - return dst; -} -/* }}} */ - -/* {{{ apc_cache_make_entry */ -PHP_APCU_API apc_cache_entry_t* apc_cache_make_entry(apc_context_t* ctxt, apc_cache_key_t *key, const zval* val, const unsigned int ttl TSRMLS_DC) -{ - apc_cache_entry_t* entry; - apc_pool* pool = ctxt->pool; - - entry = (apc_cache_entry_t*) pool->palloc(pool, sizeof(apc_cache_entry_t) TSRMLS_CC); - if (!entry) { - return NULL; - } - - /* set key for serializer */ - ctxt->key = key; - - entry->val = apc_cache_store_zval(NULL, val, ctxt TSRMLS_CC); - if(!entry->val) { - return NULL; - } - - INIT_PZVAL(entry->val); - entry->ttl = ttl; - entry->ref_count = 0; - entry->mem_size = 0; - entry->pool = pool; - return entry; -} -/* }}} */ - -/* {{{ apc_cache_link_info */ -static zval* apc_cache_link_info(apc_cache_t *cache, apc_cache_slot_t* p TSRMLS_DC) -{ - zval *link = NULL; - - ALLOC_INIT_ZVAL(link); - - if(!link) { - return NULL; - } - - array_init(link); - - add_assoc_stringl(link, "key", (char*) p->key.str, p->key.len-1, 1); - add_assoc_long(link, "ttl", (long)p->value->ttl); - - add_assoc_double(link, "nhits", (double)p->nhits); - add_assoc_long(link, "mtime", p->key.mtime); - add_assoc_long(link, "ctime", p->ctime); - add_assoc_long(link, "dtime", p->dtime); - add_assoc_long(link, "atime", p->atime); - add_assoc_long(link, "ref_count", p->value->ref_count); - add_assoc_long(link, "mem_size", p->value->mem_size); - - return link; -} -/* }}} */ - -/* {{{ apc_cache_info */ -PHP_APCU_API zval* apc_cache_info(apc_cache_t* cache, zend_bool limited TSRMLS_DC) -{ - zval *info = NULL; - zval *list = NULL; - zval *gc = NULL; - zval *slots = NULL; - apc_cache_slot_t* p; - zend_ulong i, j; - - if(!cache) { - return NULL; - } - - ALLOC_INIT_ZVAL(info); - - /* read lock header */ - APC_RLOCK(cache->header); - - array_init(info); - add_assoc_long(info, "nslots", cache->nslots); - add_assoc_long(info, "ttl", cache->ttl); - - add_assoc_double(info, "nhits", (double)cache->header->nhits); - add_assoc_double(info, "nmisses", (double)cache->header->nmisses); - add_assoc_double(info, "ninserts", (double)cache->header->ninserts); - add_assoc_long(info, "nentries", cache->header->nentries); - add_assoc_double(info, "nexpunges", (double)cache->header->nexpunges); - - add_assoc_long(info, "stime", cache->header->stime); - add_assoc_double(info, "mem_size", (double)cache->header->mem_size); - -#ifdef MULTIPART_EVENT_FORMDATA - add_assoc_long(info, "file_upload_progress", 1); -#else - add_assoc_long(info, "file_upload_progress", 0); -#endif -#if APC_MMAP - add_assoc_stringl(info, "memory_type", "mmap", sizeof("mmap")-1, 1); -#else - add_assoc_stringl(info, "memory_type", "IPC shared", sizeof("IPC shared")-1, 1); -#endif - - if(!limited) { - /* For each hashtable slot */ - ALLOC_INIT_ZVAL(list); - array_init(list); - - ALLOC_INIT_ZVAL(slots); - array_init(slots); - - for (i = 0; i < cache->nslots; i++) { - p = cache->slots[i]; - j = 0; - for (; p != NULL; p = p->next) { - zval *link = apc_cache_link_info(cache, p TSRMLS_CC); - add_next_index_zval(list, link); - j++; - } - if(j != 0) { - add_index_long(slots, (ulong)i, j); - } - } - - /* For each slot pending deletion */ - ALLOC_INIT_ZVAL(gc); - array_init(gc); - - for (p = cache->header->gc; p != NULL; p = p->next) { - zval *link = apc_cache_link_info(cache, p TSRMLS_CC); - add_next_index_zval(gc, link); - } - - add_assoc_zval(info, "cache_list", list); - add_assoc_zval(info, "deleted_list", gc); - add_assoc_zval(info, "slot_distribution", slots); - } - - /* unlock header */ - APC_RUNLOCK(cache->header); - - return info; -} -/* }}} */ - -/* - fetches information about the key provided -*/ -PHP_APCU_API zval* apc_cache_stat(apc_cache_t* cache, - char *strkey, - zend_uint keylen TSRMLS_DC) { - zval *stat; - apc_cache_slot_t** slot; - zend_ulong h, s; - - /* calculate hash and slot */ - apc_cache_hash_slot(cache, strkey, keylen, &h, &s); - - /* allocate stat buffer */ - ALLOC_INIT_ZVAL(stat); - - /* read lock header */ - APC_RLOCK(cache->header); - - /* find head */ - slot = &cache->slots[s]; - - while (*slot) { - /* check for a matching key by has and identifier */ - if ((h == (*slot)->key.h) && !memcmp((*slot)->key.str, strkey, keylen)) { - array_init(stat); - - add_assoc_long(stat, "hits", (*slot)->nhits); - add_assoc_long(stat, "atime", (*slot)->atime); - add_assoc_long(stat, "mtime", (*slot)->key.mtime); - add_assoc_long(stat, "ctime", (*slot)->ctime); - add_assoc_long(stat, "dtime", (*slot)->dtime); - add_assoc_long(stat, "ttl", (*slot)->value->ttl); - add_assoc_long(stat, "refs", (*slot)->value->ref_count); - - break; - } - - /* next */ - slot = &(*slot)->next; - } - - APC_RUNLOCK(cache->header); - - return stat; -} - -/* {{{ apc_cache_busy */ -PHP_APCU_API zend_bool apc_cache_busy(apc_cache_t* cache TSRMLS_DC) -{ - return (cache->header->state & APC_CACHE_ST_BUSY); -} -/* }}} */ - -/* {{{ apc_cache_defense */ -PHP_APCU_API zend_bool apc_cache_defense(apc_cache_t* cache, apc_cache_key_t* key TSRMLS_DC) -{ - zend_bool result = 0; - - /* in ZTS mode, we use the current TSRM context to determine the owner */ -#ifdef ZTS -# define FROM_DIFFERENT_THREAD(k) ((key->owner = TSRMLS_C) != (k)->owner) -#else -# define FROM_DIFFERENT_THREAD(k) ((key->owner = getpid()) != (k)->owner) -#endif - - /* only continue if slam defense is enabled */ - if (cache->defend) { - - /* for copy of locking key struct */ - apc_cache_key_t *last = &cache->header->lastkey; - - /* check the hash and length match */ - if(last->h == key->h && last->len == key->len) { - - /* check the time ( last second considered slam ) and context */ - if(last->mtime == key->mtime && - FROM_DIFFERENT_THREAD(last)) { - - /* potential cache slam */ - apc_debug( - "Potential cache slam averted for key '%s'" TSRMLS_CC, key->str); - result = 1; - } else { - /* sets enough information for an educated guess, but is not exact */ - last->h = key->h; - last->len = key->len; - last->mtime = apc_time(); - - /* required to tell contexts apart */ -#ifdef ZTS - last->owner = TSRMLS_C; -#else - last->owner = getpid(); -#endif - } - } - } - - return result; -} -/* }}} */ - -/* {{{ apc_cache_serializer */ -PHP_APCU_API void apc_cache_serializer(apc_cache_t* cache, const char* name TSRMLS_DC) { - if (cache && !cache->serializer) { - cache->serializer = apc_find_serializer(name TSRMLS_CC); - } -} /* }}} */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker - * vim<600: expandtab sw=4 ts=4 sts=4 - */ | ||
[+] | Deleted | apcu-4.0.4.tgz/apcu-4.0.4/php_apc.h ^ |
@@ -1,55 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2006-2011 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Daniel Cowgill <dcowgill@communityconnect.com> | - | George Schlossnagle <george@omniti.com> | - | Rasmus Lerdorf <rasmus@php.net> | - +----------------------------------------------------------------------+ - - This software was contributed to PHP by Community Connect Inc. in 2002 - and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1. - Future revisions and derivatives of this source code must acknowledge - Community Connect Inc. as the original contributor of this module by - leaving this note intact in the source code. - - All other licensing and usage conditions are those of the PHP Group. - - */ - -/* $Id: php_apc.h 328953 2013-01-03 02:19:19Z rasmus $ */ - -#ifndef PHP_APC_H -#define PHP_APC_H - -#include "apc_php.h" -#include "apc_globals.h" - -#define PHP_APCU_VERSION "4.0.4" -#define PHP_APCU_EXTNAME "apcu" - -extern zend_module_entry apcu_module_entry; -#define apcu_module_ptr &apcu_module_entry - -#define phpext_apcu_ptr apcu_module_ptr - -#endif /* PHP_APC_H */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker - * vim<600: expandtab sw=4 ts=4 sts=4 - */ | ||
Deleted | apcu-4.0.5.tgz ^ | |
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/INSTALL ^ |
(renamed from apcu-4.0.4/INSTALL) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/INSTALL ^ |
(renamed from apcu-4.0.4/INSTALL) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/LICENSE ^ |
(renamed from apcu-4.0.4/LICENSE) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/LICENSE ^ |
(renamed from apcu-4.0.4/LICENSE) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/Makefile.frag ^ |
(renamed from apcu-4.0.4/Makefile.frag) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/Makefile.frag ^ |
(renamed from apcu-4.0.4/Makefile.frag) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/NOTICE ^ |
(renamed from apcu-4.0.4/NOTICE) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/NOTICE ^ |
(renamed from apcu-4.0.4/NOTICE) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/README.md ^ |
(renamed from apcu-4.0.4/README.md) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/README.md ^ |
(renamed from apcu-4.0.4/README.md) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/TECHNOTES.txt ^ |
(renamed from apcu-4.0.4/TECHNOTES.txt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/TECHNOTES.txt ^ |
(renamed from apcu-4.0.4/TECHNOTES.txt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/TODO ^ |
(renamed from apcu-4.0.4/TODO) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/TODO ^ |
(renamed from apcu-4.0.4/TODO) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc.c ^ |
(renamed from apcu-4.0.4/apc.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc.c ^ |
(renamed from apcu-4.0.4/apc.c) | ||
[+] | Added | apcu-4.0.6.tgz/apcu-4.0.6/apc.h ^ |
@@ -0,0 +1,181 @@ +/* + +----------------------------------------------------------------------+ + | APC | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2011 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> | + | George Schlossnagle <george@omniti.com> | + | Rasmus Lerdorf <rasmus@php.net> | + | Arun C. Murthy <arunc@yahoo-inc.com> | + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> | + +----------------------------------------------------------------------+ + + This software was contributed to PHP by Community Connect Inc. in 2002 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1. + Future revisions and derivatives of this source code must acknowledge + Community Connect Inc. as the original contributor of this module by + leaving this note intact in the source code. + + All other licensing and usage conditions are those of the PHP Group. + + */ + +/* $Id: apc.h 328292 2012-11-09 07:05:17Z laruence $ */ + +#ifndef APC_H +#define APC_H + +/* + * This module defines utilities and helper functions used elsewhere in APC. + */ +#ifdef PHP_WIN32 +# define PHP_APCU_API __declspec(dllexport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define PHP_APCU_API __attribute__ ((visibility("default"))) +#else +# define PHP_APCU_API +#endif + +/* Commonly needed C library headers. */ +#include <assert.h> +#include <errno.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +/* UNIX headers (needed for struct stat) */ +#include <sys/types.h> +#include <sys/stat.h> +#ifndef PHP_WIN32 +#include <unistd.h> +#endif + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "php.h" +#include "main/php_streams.h" + +/* typedefs for extensible memory allocators */ +typedef void* (*apc_malloc_t)(size_t TSRMLS_DC); +typedef void (*apc_free_t) (void * TSRMLS_DC); + +/* wrappers for memory allocation routines */ +PHP_APCU_API void* apc_emalloc(size_t n TSRMLS_DC); +PHP_APCU_API void* apc_erealloc(void* p, size_t n TSRMLS_DC); +PHP_APCU_API void* apc_php_malloc(size_t n TSRMLS_DC); +PHP_APCU_API void apc_php_free(void* p TSRMLS_DC); +PHP_APCU_API void apc_efree(void* p TSRMLS_DC); +PHP_APCU_API char* apc_estrdup(const char* s TSRMLS_DC); +PHP_APCU_API void* apc_xstrdup(const char* s, apc_malloc_t f TSRMLS_DC); +PHP_APCU_API void* apc_xmemcpy(const void* p, size_t n, apc_malloc_t f TSRMLS_DC); + +/* console display functions */ +PHP_APCU_API void apc_error(const char *format TSRMLS_DC, ...); +PHP_APCU_API void apc_warning(const char *format TSRMLS_DC, ...); +PHP_APCU_API void apc_notice(const char *format TSRMLS_DC, ...); +PHP_APCU_API void apc_debug(const char *format TSRMLS_DC, ...); + +/* string and text manipulation */ +PHP_APCU_API char* apc_append(const char* s, const char* t TSRMLS_DC); +PHP_APCU_API char* apc_substr(const char* s, int start, int length TSRMLS_DC); +PHP_APCU_API char** apc_tokenize(const char* s, char delim TSRMLS_DC); + +/* apc_crc32: returns the CRC-32 checksum of the first len bytes in buf */ +PHP_APCU_API unsigned int apc_crc32(const unsigned char* buf, unsigned int len); + +/* apc_flip_hash flips keys and values for faster searching */ +PHP_APCU_API HashTable* apc_flip_hash(HashTable *hash); + +#define APC_NEGATIVE_MATCH 1 +#define APC_POSITIVE_MATCH 2 + +#define apc_time() \ + (APCG(use_request_time) ? (time_t) sapi_get_request_time(TSRMLS_C) : time(0)); + +#if defined(__GNUC__) +# define APC_UNUSED __attribute__((unused)) +# define APC_USED __attribute__((used)) +# define APC_ALLOC __attribute__((malloc)) +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) +# define APC_HOTSPOT __attribute__((hot)) +# else +# define APC_HOTSPOT +# endif +#else +# define APC_UNUSED +# define APC_USED +# define APC_ALLOC +# define APC_HOTSPOT +#endif + +/* +* Serializer API +*/ +#define APC_SERIALIZER_ABI "0" +#define APC_SERIALIZER_CONSTANT "\000apc_register_serializer-" APC_SERIALIZER_ABI + +#define APC_SERIALIZER_NAME(module) module##_apc_serializer +#define APC_UNSERIALIZER_NAME(module) module##_apc_unserializer + +#define APC_SERIALIZER_ARGS unsigned char **buf, size_t *buf_len, const zval *value, void *config TSRMLS_DC +#define APC_UNSERIALIZER_ARGS zval **value, unsigned char *buf, size_t buf_len, void *config TSRMLS_DC + +typedef int (*apc_serialize_t)(APC_SERIALIZER_ARGS); +typedef int (*apc_unserialize_t)(APC_UNSERIALIZER_ARGS); + +/* {{{ struct definition: apc_serializer_t */ +typedef struct apc_serializer_t { + const char* name; + apc_serialize_t serialize; + apc_unserialize_t unserialize; + void* config; +} apc_serializer_t; +/* }}} */ + +/* {{{ _apc_register_serializer + registers the serializer using the given name and paramters */ +PHP_APCU_API int _apc_register_serializer(const char* name, + apc_serialize_t serialize, + apc_unserialize_t unserialize, + void *config TSRMLS_DC); /* }}} */ + +/* {{{ apc_get_serializers + fetches the list of serializers */ +PHP_APCU_API apc_serializer_t* apc_get_serializers(TSRMLS_D); /* }}} */ + +/* {{{ apc_find_serializer + finds a previously registered serializer by name */ +PHP_APCU_API apc_serializer_t* apc_find_serializer(const char* name TSRMLS_DC); /* }}} */ + +/* {{{ default serializers */ +PHP_APCU_API int APC_SERIALIZER_NAME(php) (APC_SERIALIZER_ARGS); +PHP_APCU_API int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS); /* }}} */ + +/* {{{ eval serializers */ +PHP_APCU_API int APC_SERIALIZER_NAME(eval) (APC_SERIALIZER_ARGS); +PHP_APCU_API int APC_UNSERIALIZER_NAME(eval) (APC_UNSERIALIZER_ARGS); /* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker + * vim<600: expandtab sw=4 ts=4 sts=4 + */ | ||
[+] | Added | apcu-4.0.6.tgz/apcu-4.0.6/apc.php ^ |
@@ -0,0 +1,1146 @@ +<?php +/* + +----------------------------------------------------------------------+ + | APC | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2011 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Ralf Becker <beckerr@php.net> | + | Rasmus Lerdorf <rasmus@php.net> | + | Ilia Alshanetsky <ilia@prohost.org> | + +----------------------------------------------------------------------+ + + All other licensing and usage conditions are those of the PHP Group. + + */ + +$VERSION='$Id$'; + +////////// READ OPTIONAL CONFIGURATION FILE //////////// +if (file_exists("apc.conf.php")) include("apc.conf.php"); +//////////////////////////////////////////////////////// + +////////// BEGIN OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////// + +defaults('USE_AUTHENTICATION',1); // Use (internal) authentication - best choice if + // no other authentication is available + // If set to 0: + // There will be no further authentication. You + // will have to handle this by yourself! + // If set to 1: + // You need to change ADMIN_PASSWORD to make + // this work! +defaults('ADMIN_USERNAME','apc'); // Admin Username +defaults('ADMIN_PASSWORD','password'); // Admin Password - CHANGE THIS TO ENABLE!!! + +// (beckerr) I'm using a clear text password here, because I've no good idea how to let +// users generate a md5 or crypt password in a easy way to fill it in above + +//defaults('DATE_FORMAT', "d.m.Y H:i:s"); // German +defaults('DATE_FORMAT', 'Y/m/d H:i:s'); // US + +defaults('GRAPH_SIZE',200); // Image size + +//defaults('PROXY', 'tcp://127.0.0.1:8080'); + +////////// END OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////// + + +// "define if not defined" +function defaults($d,$v) { + if (!defined($d)) define($d,$v); // or just @define(...) +} + +// rewrite $PHP_SELF to block XSS attacks +// +$PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],''), ENT_QUOTES, 'UTF-8') : ''; +$time = time(); +$host = php_uname('n'); +if($host) { $host = '('.$host.')'; } +if (isset($_SERVER['SERVER_ADDR'])) { + $host .= ' ('.$_SERVER['SERVER_ADDR'].')'; +} + +// operation constants +define('OB_HOST_STATS',1); +define('OB_USER_CACHE',2); +define('OB_VERSION_CHECK',3); + +// check validity of input variables +$vardom=array( + 'OB' => '/^\d+$/', // operational mode switch + 'CC' => '/^[01]$/', // clear cache requested + 'DU' => '/^.*$/', // Delete User Key + 'SH' => '/^[a-z0-9]+$/', // shared object description + + 'IMG' => '/^[123]$/', // image to generate + 'LO' => '/^1$/', // login requested + + 'COUNT' => '/^\d+$/', // number of line displayed in list + 'SCOPE' => '/^[AD]$/', // list view scope + 'SORT1' => '/^[AHSMCDTZ]$/', // first sort key + 'SORT2' => '/^[DA]$/', // second sort key + 'AGGR' => '/^\d+$/', // aggregation by dir level + 'SEARCH' => '~^[a-zA-Z0-9/_.-]*$~' // aggregation by dir level +); + +// cache scope +$scope_list=array( + 'A' => 'cache_list', + 'D' => 'deleted_list' +); + +// handle POST and GET requests +if (empty($_REQUEST)) { + if (!empty($_GET) && !empty($_POST)) { + $_REQUEST = array_merge($_GET, $_POST); + } else if (!empty($_GET)) { + $_REQUEST = $_GET; + } else if (!empty($_POST)) { + $_REQUEST = $_POST; + } else { + $_REQUEST = array(); + } +} + +// check parameter syntax +foreach($vardom as $var => $dom) { + if (!isset($_REQUEST[$var])) { + $MYREQUEST[$var]=NULL; + } else if (!is_array($_REQUEST[$var]) && preg_match($dom.'D',$_REQUEST[$var])) { + $MYREQUEST[$var]=$_REQUEST[$var]; + } else { + $MYREQUEST[$var]=$_REQUEST[$var]=NULL; + } +} + +// check parameter sematics +if (empty($MYREQUEST['SCOPE'])) $MYREQUEST['SCOPE']="A"; +if (empty($MYREQUEST['SORT1'])) $MYREQUEST['SORT1']="H"; +if (empty($MYREQUEST['SORT2'])) $MYREQUEST['SORT2']="D"; +if (empty($MYREQUEST['OB'])) $MYREQUEST['OB']=OB_HOST_STATS; +if (!isset($MYREQUEST['COUNT'])) $MYREQUEST['COUNT']=20; +if (!isset($scope_list[$MYREQUEST['SCOPE']])) $MYREQUEST['SCOPE']='A'; + +$MY_SELF= + "$PHP_SELF". + "?SCOPE=".$MYREQUEST['SCOPE']. + "&SORT1=".$MYREQUEST['SORT1']. + "&SORT2=".$MYREQUEST['SORT2']. + "&COUNT=".$MYREQUEST['COUNT']; +$MY_SELF_WO_SORT= + "$PHP_SELF". + "?SCOPE=".$MYREQUEST['SCOPE']. + "&COUNT=".$MYREQUEST['COUNT']; + +// authentication needed? +// +if (!USE_AUTHENTICATION) { + $AUTHENTICATED=1; +} else { + $AUTHENTICATED=0; + if (ADMIN_PASSWORD!='password' && ($MYREQUEST['LO'] == 1 || isset($_SERVER['PHP_AUTH_USER']))) { + + if (!isset($_SERVER['PHP_AUTH_USER']) || + !isset($_SERVER['PHP_AUTH_PW']) || + $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME || + $_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) { + Header("WWW-Authenticate: Basic realm=\"APC Login\""); + Header("HTTP/1.0 401 Unauthorized"); + + echo <<<EOB + <html><body> + <h1>Rejected!</h1> + <big>Wrong Username or Password!</big><br/> <br/> + <big><a href='$PHP_SELF?OB={$MYREQUEST['OB']}'>Continue...</a></big> + </body></html> +EOB; + exit; + + } else { + $AUTHENTICATED=1; + } + } +} + +// clear cache +if ($AUTHENTICATED && isset($MYREQUEST['CC']) && $MYREQUEST['CC']) { + apcu_clear_cache(); +} + +if ($AUTHENTICATED && !empty($MYREQUEST['DU'])) { + apcu_delete($MYREQUEST['DU']); +} + +if(!function_exists('apcu_cache_info')) { + echo "No cache info available. APC does not appear to be running."; + exit; +} + +$cache = apcu_cache_info(); + +$mem=apcu_sma_info(); + +// don't cache this page +// +header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1 +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); // HTTP/1.0 + +function duration($ts) { + global $time; + $years = (int)((($time - $ts)/(7*86400))/52.177457); + $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400)); + $weeks = (int)(($rem)/(7*86400)); + $days = (int)(($rem)/86400) - $weeks*7; + $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24; + $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60; + $str = ''; + if($years==1) $str .= "$years year, "; + if($years>1) $str .= "$years years, "; + if($weeks==1) $str .= "$weeks week, "; + if($weeks>1) $str .= "$weeks weeks, "; + if($days==1) $str .= "$days day,"; + if($days>1) $str .= "$days days,"; + if($hours == 1) $str .= " $hours hour and"; + if($hours>1) $str .= " $hours hours and"; + if($mins == 1) $str .= " 1 minute"; + else $str .= " $mins minutes"; + return $str; +} + +// create graphics +// +function graphics_avail() { + return extension_loaded('gd'); +} +if (isset($MYREQUEST['IMG'])) +{ + if (!graphics_avail()) { + exit(0); + } + + function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) { + $r=$diameter/2; + $w=deg2rad((360+$start+($end-$start)/2)%360); + + + if (function_exists("imagefilledarc")) { + // exists only if GD 2.0.1 is avaliable + imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE); + imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE); + imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED); + } else { + imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2); + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); + imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2); + } + if ($text) { + if ($placeindex>0) { + imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1); + imagestring($im,4,$diameter, $placeindex*12,$text,$color1); + + } else { + imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1); + } + } + } + + function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$text,$placeindex=0) { + $r=$diameter/2; + $w=deg2rad((360+$start+($end-$start)/2)%360); + + if ($placeindex>0) { + imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1); + imagestring($im,4,$diameter, $placeindex*12,$text,$color1); + + } else { + imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1); + } + } + + function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') { + global $col_black; + $x1=$x+$w-1; + $y1=$y+$h-1; + + imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black); + if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2); + else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2); + imagerectangle($im, $x, $y1, $x1, $y, $color1); + if ($text) { + if ($placeindex>0) { + + if ($placeindex<16) + { + $px=5; + $py=$placeindex*12+6; + imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2); + imageline($im,$x,$y+$h/2,$px+90,$py,$color2); + imagestring($im,2,$px,$py-6,$text,$color1); + + } else { + if ($placeindex<31) { + $px=$x+40*2; + $py=($placeindex-15)*12+6; + } else { + $px=$x+40*2+100*intval(($placeindex-15)/15); + $py=($placeindex%15)*12+6; + } + imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2); + imageline($im,$x+$w,$y+$h/2,$px,$py,$color2); + imagestring($im,2,$px+2,$py-6,$text,$color1); + } + } else { + imagestring($im,4,$x+5,$y1-16,$text,$color1); + } + } + } + + + $size = GRAPH_SIZE; // image size + if ($MYREQUEST['IMG']==3) + $image = imagecreate(2*$size+150, $size+10); + else + $image = imagecreate($size+50, $size+10); + + $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); + $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); + $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); + $col_black = imagecolorallocate($image, 0, 0, 0); + imagecolortransparent($image,$col_white); + + switch ($MYREQUEST['IMG']) { + + case 1: + $s=$mem['num_seg']*$mem['seg_size']; + $a=$mem['avail_mem']; + $x=$y=$size/2; + $fuzz = 0.000001; + + // This block of code creates the pie chart. It is a lot more complex than you + // would expect because we try to visualize any memory fragmentation as well. + $angle_from = 0; + $string_placement=array(); + for($i=0; $i<$mem['num_seg']; $i++) { + $ptr = 0; + $free = $mem['block_lists'][$i]; + uasort($free, 'block_sort'); + foreach($free as $block) { + if($block['offset']!=$ptr) { // Used block + $angle_to = $angle_from+($block['offset']-$ptr)/$s; + if(($angle_to+$fuzz)>1) $angle_to = 1; + if( ($angle_to*360) - ($angle_from*360) >= 1) { + fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red); + if (($angle_to-$angle_from)>0.05) { + array_push($string_placement, array($angle_from,$angle_to)); + } + } + $angle_from = $angle_to; + } + $angle_to = $angle_from+($block['size'])/$s; + if(($angle_to+$fuzz)>1) $angle_to = 1; + if( ($angle_to*360) - ($angle_from*360) >= 1) { + fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_green); + if (($angle_to-$angle_from)>0.05) { + array_push($string_placement, array($angle_from,$angle_to)); + } + } + $angle_from = $angle_to; + $ptr = $block['offset']+$block['size']; + } + if ($ptr < $mem['seg_size']) { // memory at the end + $angle_to = $angle_from + ($mem['seg_size'] - $ptr)/$s; + if(($angle_to+$fuzz)>1) $angle_to = 1; + fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red); + if (($angle_to-$angle_from)>0.05) { + array_push($string_placement, array($angle_from,$angle_to)); + } + } + } + foreach ($string_placement as $angle) { + text_arc($image,$x,$y,$size,$angle[0]*360,$angle[1]*360,$col_black,bsize($s*($angle[1]-$angle[0]))); + } + break; + + case 2: + $s=$cache['nhits']+$cache['nmisses']; + $a=$cache['nhits']; + + fill_box($image, 30,$size,50,$s ? (-$a*($size-21)/$s) : 0,$col_black,$col_green,sprintf("%.1f%%",$s ? $cache['nhits']*100/$s : 0)); + fill_box($image,130,$size,50,$s ? -max(4,($s-$a)*($size-21)/$s) : 0,$col_black,$col_red,sprintf("%.1f%%",$s ? $cache['nmisses']*100/$s : 0)); + break; + + case 3: + $s=$mem['num_seg']*$mem['seg_size']; + $a=$mem['avail_mem']; + $x=130; + $y=1; + $j=1; + + // This block of code creates the bar chart. It is a lot more complex than you + // would expect because we try to visualize any memory fragmentation as well. + for($i=0; $i<$mem['num_seg']; $i++) { + $ptr = 0; + $free = $mem['block_lists'][$i]; + uasort($free, 'block_sort'); + foreach($free as $block) { + if($block['offset']!=$ptr) { // Used block + $h=(GRAPH_SIZE-5)*($block['offset']-$ptr)/$s; + if ($h>0) { + $j++; + if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($block['offset']-$ptr),$j); + else fill_box($image,$x,$y,50,$h,$col_black,$col_red); + } + $y+=$h; + } + $h=(GRAPH_SIZE-5)*($block['size'])/$s; + if ($h>0) { + $j++; + if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_green,bsize($block['size']),$j); + else fill_box($image,$x,$y,50,$h,$col_black,$col_green); + } + $y+=$h; + $ptr = $block['offset']+$block['size']; + } + if ($ptr < $mem['seg_size']) { // memory at the end + $h = (GRAPH_SIZE-5) * ($mem['seg_size'] - $ptr) / $s; + if ($h > 0) { + fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($mem['seg_size']-$ptr),$j++); + } + } + } + break; + + case 4: + $s=$cache['nhits']+$cache['nmisses']; + $a=$cache['nhits']; + + fill_box($image, 30,$size,50,$s ? -$a*($size-21)/$s : 0,$col_black,$col_green,sprintf("%.1f%%", $s ? $cache['nhits']*100/$s : 0)); + fill_box($image,130,$size,50,$s ? -max(4,($s-$a)*($size-21)/$s) : 0,$col_black,$col_red,sprintf("%.1f%%", $s ? $cache['nmisses']*100/$s : 0)); + break; + } + + header("Content-type: image/png"); + imagepng($image); + exit; +} + +// pretty printer for byte values +// +function bsize($s) { + foreach (array('','K','M','G') as $i => $k) { + if ($s < 1024) break; + $s/=1024; + } + return sprintf("%5.1f %sBytes",$s,$k); +} + +// sortable table header in "scripts for this host" view +function sortheader($key,$name,$extra='') { + global $MYREQUEST, $MY_SELF_WO_SORT; + + if ($MYREQUEST['SORT1']==$key) { + $MYREQUEST['SORT2'] = $MYREQUEST['SORT2']=='A' ? 'D' : 'A'; + } + return "<a class=sortable href=\"$MY_SELF_WO_SORT$extra&SORT1=$key&SORT2=".$MYREQUEST['SORT2']."\">$name</a>"; + +} + +// create menu entry +function menu_entry($ob,$title) { + global $MYREQUEST,$MY_SELF; + if ($MYREQUEST['OB']!=$ob) { + return "<li><a href=\"$MY_SELF&OB=$ob\">$title</a></li>"; + } else if (empty($MYREQUEST['SH'])) { + return "<li><span class=active>$title</span></li>"; + } else { + return "<li><a class=\"child_active\" href=\"$MY_SELF&OB=$ob\">$title</a></li>"; + } +} + +function put_login_link($s="Login") +{ + global $MY_SELF,$MYREQUEST,$AUTHENTICATED; + // needs ADMIN_PASSWORD to be changed! + // + if (!USE_AUTHENTICATION) { + return; + } else if (ADMIN_PASSWORD=='password') + { + print <<<EOB + <a href="#" onClick="javascript:alert('You need to set a password at the top of apc.php before this will work!');return false";>$s</a> +EOB; + } else if ($AUTHENTICATED) { + print <<<EOB + '{$_SERVER['PHP_AUTH_USER']}' logged in! +EOB; + } else{ + print <<<EOB + <a href="$MY_SELF&LO=1&OB={$MYREQUEST['OB']}">$s</a> +EOB; + } +} + +function block_sort($array1, $array2) +{ + if ($array1['offset'] > $array2['offset']) { + return 1; + } else { + return -1; + } +} + + +?> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head><title>APCu INFO <?php echo $host ?></title> +<style><!-- +body { background:white; font-size:100.01%; margin:0; padding:0; } +body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; } +* html body {font-size:0.8em} +* html p {font-size:0.8em} +* html td {font-size:0.8em} +* html th {font-size:0.8em} +* html input {font-size:0.8em} +* html submit {font-size:0.8em} +td { vertical-align:top } +a { color:black; font-weight:none; text-decoration:none; } +a:hover { text-decoration:underline; } +div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; } + + +div.head div.login { + position:absolute; + right: 1em; + top: 1.2em; + color:white; + width:6em; + } +div.head div.login a { + position:absolute; + right: 0em; + background:rgb(119,123,180); + border:solid rgb(102,102,153) 2px; + color:white; + font-weight:bold; + padding:0.1em 0.5em 0.1em 0.5em; + text-decoration:none; + } +div.head div.login a:hover { + background:rgb(193,193,244); + } + +h1.apc { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; } +* html h1.apc { margin-bottom:-7px; } +h1.apc a:hover { text-decoration:none; color:rgb(90,90,90); } +h1.apc div.logo span.logo { + background:rgb(119,123,180); + color:black; + border-right: solid black 1px; + border-bottom: solid black 1px; + font-style:italic; + font-size:1em; + padding-left:1.2em; + padding-right:1.2em; + text-align:right; + } +h1.apc div.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; } +h1.apc div.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; } +h1.apc div.copy { color:black; font-size:0.4em; position:absolute; right:1em; } +hr.apc { + background:white; + border-bottom:solid rgb(102,102,153) 1px; + border-style:none; + border-top:solid rgb(102,102,153) 10px; + height:12px; + margin:0; + margin-top:1px; + padding:0; +} + +ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;} +ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%} +ol.menu a { + background:rgb(153,153,204); + border:solid rgb(102,102,153) 2px; + color:white; + font-weight:bold; + margin-right:0em; + padding:0.1em 0.5em 0.1em 0.5em; + text-decoration:none; + margin-left: 5px; + } +ol.menu a.child_active { + background:rgb(153,153,204); + border:solid rgb(102,102,153) 2px; + color:white; + font-weight:bold; + margin-right:0em; + padding:0.1em 0.5em 0.1em 0.5em; + text-decoration:none; + border-left: solid black 5px; + margin-left: 0px; + } +ol.menu span.active { + background:rgb(153,153,204); + border:solid rgb(102,102,153) 2px; + color:black; + font-weight:bold; + margin-right:0em; + padding:0.1em 0.5em 0.1em 0.5em; + text-decoration:none; + border-left: solid black 5px; + } +ol.menu span.inactive { + background:rgb(193,193,244); + border:solid rgb(182,182,233) 2px; + color:white; + font-weight:bold; + margin-right:0em; + padding:0.1em 0.5em 0.1em 0.5em; + text-decoration:none; + margin-left: 5px; + } +ol.menu a:hover { + background:rgb(193,193,244); + text-decoration:none; + } + + +div.info { + background:rgb(204,204,204); + border:solid rgb(204,204,204) 1px; + margin-bottom:1em; + } +div.info h2 { + background:rgb(204,204,204); + color:black; + font-size:1em; + margin:0; + padding:0.1em 1em 0.1em 1em; + } +div.info table { + border:solid rgb(204,204,204) 1px; + border-spacing:0; + width:100%; + } +div.info table th { + background:rgb(204,204,204); + color:white; + margin:0; + padding:0.1em 1em 0.1em 1em; + } +div.info table th a.sortable { color:black; } +div.info table tr.tr-0 { background:rgb(238,238,238); } +div.info table tr.tr-1 { background:rgb(221,221,221); } +div.info table td { padding:0.3em 1em 0.3em 1em; } +div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; } +div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; } +div.info table td h3 { + color:black; + font-size:1.1em; + margin-left:-0.3em; + } + +div.graph { margin-bottom:1em } +div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; } +div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; } +div.graph table td.td-0 { background:rgb(238,238,238); } +div.graph table td.td-1 { background:rgb(221,221,221); } +div.graph table td { padding:0.2em 1em 0.4em 1em; } + +div.div1,div.div2 { margin-bottom:1em; width:35em; } +div.div3 { position:absolute; left:40em; top:1em; width:580px; } +//div.div3 { position:absolute; left:37em; top:1em; right:1em; } + +div.sorting { margin:1.5em 0em 1.5em 2em } +.center { text-align:center } +.aright { position:absolute;right:1em } +.right { text-align:right } +.ok { color:rgb(0,200,0); font-weight:bold} +.failed { color:rgb(200,0,0); font-weight:bold} + +span.box { + border: black solid 1px; + border-right:solid black 2px; + border-bottom:solid black 2px; + padding:0 0.5em 0 0.5em; + margin-right:1em; +} +span.green { background:#60F060; padding:0 0.5em 0 0.5em} +span.red { background:#D06030; padding:0 0.5em 0 0.5em } + +div.authneeded { + background:rgb(238,238,238); + border:solid rgb(204,204,204) 1px; + color:rgb(200,0,0); + font-size:1.2em; + font-weight:bold; + padding:2em; + text-align:center; + } + +input { + background:rgb(153,153,204); + border:solid rgb(102,102,153) 2px; + color:white; + font-weight:bold; + margin-right:1em; + padding:0.1em 0.5em 0.1em 0.5em; + } +//--> +</style> +</head> +<body> +<div class="head"> + <h1 class="apc"> + <div class="logo"><span class="logo"><a href="http://pecl.php.net/package/APCu">APCu</a></span></div> + <div class="nameinfo">User Cache</div> + </h1> + <div class="login"> + <?php put_login_link(); ?> + </div> + <hr class="apc"> +</div> + +<?php +// Display main Menu +echo <<<EOB + <ol class=menu> + <li><a href="$MY_SELF&OB={$MYREQUEST['OB']}&SH={$MYREQUEST['SH']}">Refresh Data</a></li> +EOB; +echo + menu_entry(OB_HOST_STATS,'View Host Stats'), + menu_entry(OB_USER_CACHE,'User Cache Entries'), + menu_entry(OB_VERSION_CHECK,'Version Check'); + +if ($AUTHENTICATED) { + echo <<<EOB + <li><a class="aright" href="$MY_SELF&CC=1&OB={$MYREQUEST['OB']}" onClick="javascript:return confirm('Are you sure?');">Clear Cache</a></li> +EOB; +} +echo <<<EOB + </ol> +EOB; + + +// CONTENT +echo <<<EOB + <div class=content> +EOB; + +// MAIN SWITCH STATEMENT + +switch ($MYREQUEST['OB']) { +// ----------------------------------------------- +// Host Stats +// ----------------------------------------------- +case OB_HOST_STATS: + $mem_size = $mem['num_seg']*$mem['seg_size']; + $mem_avail= $mem['avail_mem']; + $mem_used = $mem_size-$mem_avail; + $seg_size = bsize($mem['seg_size']); + $req_rate_user = sprintf("%.2f", $cache['nhits'] ? (($cache['nhits']+$cache['nmisses'])/($time-$cache['stime'])) : 0); + $hit_rate_user = sprintf("%.2f", $cache['nhits'] ? (($cache['nhits'])/($time-$cache['stime'])) : 0); + $miss_rate_user = sprintf("%.2f", $cache['nmisses'] ? (($cache['nmisses'])/($time-$cache['stime'])) : 0); + $insert_rate_user = sprintf("%.2f", $cache['ninserts'] ? (($cache['ninserts'])/($time-$cache['stime'])) : 0); + $apcversion = phpversion('apcu'); + $phpversion = phpversion(); + $number_vars = $cache['nentries']; + $size_vars = bsize($cache['mem_size']); + $i=0; + echo <<< EOB + <div class="info div1"><h2>General Cache Information</h2> + <table cellspacing=0><tbody> + <tr class=tr-0><td class=td-0>APCu Version</td><td>$apcversion</td></tr> + <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr> +EOB; + + if(!empty($_SERVER['SERVER_NAME'])) + echo "<tr class=tr-0><td class=td-0>APCu Host</td><td>{$_SERVER['SERVER_NAME']} $host</td></tr>\n"; + if(!empty($_SERVER['SERVER_SOFTWARE'])) + echo "<tr class=tr-1><td class=td-0>Server Software</td><td>{$_SERVER['SERVER_SOFTWARE']}</td></tr>\n"; + + echo <<<EOB + <tr class=tr-0><td class=td-0>Shared Memory</td><td>{$mem['num_seg']} Segment(s) with $seg_size + <br/> ({$cache['memory_type']} memory) + </td></tr> +EOB; + echo '<tr class=tr-1><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$cache['stime']),'</td></tr>'; + echo '<tr class=tr-0><td class=td-0>Uptime</td><td>',duration($cache['stime']),'</td></tr>'; + echo '<tr class=tr-1><td class=td-0>File Upload Support</td><td>',$cache['file_upload_progress'],'</td></tr>'; + echo <<<EOB + </tbody></table> + </div> + + <div class="info div1"><h2>Cache Information</h2> + <table cellspacing=0> + <tbody> + <tr class=tr-0><td class=td-0>Cached Variables</td><td>$number_vars ($size_vars)</td></tr> + <tr class=tr-1><td class=td-0>Hits</td><td>{$cache['nhits']}</td></tr> + <tr class=tr-0><td class=td-0>Misses</td><td>{$cache['nmisses']}</td></tr> + <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate_user cache requests/second</td></tr> + <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate_user cache requests/second</td></tr> + <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate_user cache requests/second</td></tr> + <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate_user cache requests/second</td></tr> + <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache['nexpunges']}</td></tr> + </tbody> + </table> + </div> + + <div class="info div2"><h2>Runtime Settings</h2><table cellspacing=0><tbody> +EOB; + + $j = 0; + foreach (ini_get_all('apcu') as $k => $v) { + echo "<tr class=tr-$j><td class=td-0>",$k,"</td><td>",str_replace(',',',<br />',$v['local_value']),"</td></tr>\n"; + $j = 1 - $j; + } + + if($mem['num_seg']>1 || $mem['num_seg']==1 && count($mem['block_lists'][0])>1) + $mem_note = "Memory Usage<br /><font size=-2>(multiple slices indicate fragments)</font>"; + else + $mem_note = "Memory Usage"; + + echo <<< EOB + </tbody></table> + </div> + + <div class="graph div3"><h2>Host Status Diagrams</h2> + <table cellspacing=0><tbody> +EOB; + $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10); +echo <<<EOB + <tr> + <td class=td-0>$mem_note</td> + <td class=td-1>Hits & Misses</td> + </tr> +EOB; + + echo + graphics_avail() ? + '<tr>'. + "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF?IMG=1&$time\"></td>". + "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF?IMG=2&$time\"></td></tr>\n" + : "", + '<tr>', + '<td class=td-0><span class="green box"> </span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n", + '<td class=td-1><span class="green box"> </span>Hits: ',$cache['nhits'].@sprintf(" (%.1f%%)",$cache['nhits']*100/($cache['nhits']+$cache['nmisses'])),"</td>\n", + '</tr>', + '<tr>', + '<td class=td-0><span class="red box"> </span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n", + '<td class=td-1><span class="red box"> </span>Misses: ',$cache['nmisses'].@sprintf(" (%.1f%%)",$cache['nmisses']*100/($cache['nhits']+$cache['nmisses'])),"</td>\n"; + echo <<< EOB + </tr> + </tbody></table> + + <br/> + <h2>Detailed Memory Usage and Fragmentation</h2> + <table cellspacing=0><tbody> + <tr> + <td class=td-0 colspan=2><br/> +EOB; + + // Fragementation: (freeseg - 1) / total_seg + $nseg = $freeseg = $fragsize = $freetotal = 0; + for($i=0; $i<$mem['num_seg']; $i++) { + $ptr = 0; + foreach($mem['block_lists'][$i] as $block) { + if ($block['offset'] != $ptr) { + ++$nseg; + } + $ptr = $block['offset'] + $block['size']; + /* Only consider blocks <5M for the fragmentation % */ + if($block['size']<(5*1024*1024)) $fragsize+=$block['size']; + $freetotal+=$block['size']; + } + $freeseg += count($mem['block_lists'][$i]); + } + + if ($freeseg > 1) { + $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize/$freetotal)*100,bsize($fragsize),bsize($freetotal),$freeseg); + } else { + $frag = "0%"; + } + + if (graphics_avail()) { + $size='width='.(2*GRAPH_SIZE+150).' height='.(GRAPH_SIZE+10); + echo <<<EOB + <img alt="" $size src="$PHP_SELF?IMG=3&$time"> +EOB; + } + echo <<<EOB + </br>Fragmentation: $frag + </td> + </tr> +EOB; + if(isset($mem['adist'])) { + foreach($mem['adist'] as $i=>$v) { + $cur = pow(2,$i); $nxt = pow(2,$i+1)-1; + if($i==0) $range = "1"; + else $range = "$cur - $nxt"; + echo "<tr><th align=right>$range</th><td align=right>$v</td></tr>\n"; + } + } + echo <<<EOB + </tbody></table> + </div> +EOB; + + break; + + +// ----------------------------------------------- +// User Cache Entries +// ----------------------------------------------- +case OB_USER_CACHE: + if (!$AUTHENTICATED) { + echo '<div class="error">You need to login to see the user values here!<br/> <br/>'; + put_login_link("Login now!"); + echo '</div>'; + break; + } + $fieldname='key'; + $fieldheading='User Entry Label'; + $fieldkey='key'; + + $cols=6; + echo <<<EOB + <div class=sorting><form>Scope: + <input type=hidden name=OB value={$MYREQUEST['OB']}> + <select name=SCOPE> +EOB; + echo + "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>", + "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>", + "</select>", + ", Sorting:<select name=SORT1>", + "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Hits</option>", + "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Size</option>", + "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">$fieldheading</option>", + "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Last accessed</option>", + "<option value=M",$MYREQUEST['SORT1']=='M' ? " selected":"",">Last modified</option>", + "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Created at</option>", + "<option value=D",$MYREQUEST['SORT1']=='D' ? " selected":"",">Deleted at</option>"; + if($fieldname=='info') echo + "<option value=D",$MYREQUEST['SORT1']=='T' ? " selected":"",">Timeout</option>"; + echo + '</select>', + '<select name=SORT2>', + '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>', + '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>', + '</select>', + '<select name=COUNT onChange="form.submit()">', + '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>', + '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>', + '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>', + '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>', + '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>', + '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>', + '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>', + '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>', + '</select>', + ' Search: <input name=SEARCH value="',$MYREQUEST['SEARCH'],'" type=text size=25/>', + ' <input type=submit value="GO!">', + '</form></div>'; + + if (isset($MYREQUEST['SEARCH'])) { + // Don't use preg_quote because we want the user to be able to specify a + // regular expression subpattern. + $MYREQUEST['SEARCH'] = '/'.str_replace('/', '\\/', $MYREQUEST['SEARCH']).'/i'; + if (preg_match($MYREQUEST['SEARCH'], 'test') === false) { + echo '<div class="error">Error: enter a valid regular expression as a search query.</div>'; + break; + } + } + + echo + '<div class="info"><table cellspacing=0><tbody>', + '<tr>', + '<th>',sortheader('S',$fieldheading, "&OB=".$MYREQUEST['OB']),'</th>', + '<th>',sortheader('H','Hits', "&OB=".$MYREQUEST['OB']),'</th>', + '<th>',sortheader('Z','Size', "&OB=".$MYREQUEST['OB']),'</th>', + '<th>',sortheader('A','Last accessed',"&OB=".$MYREQUEST['OB']),'</th>', + '<th>',sortheader('M','Last modified',"&OB=".$MYREQUEST['OB']),'</th>', + '<th>',sortheader('C','Created at', "&OB=".$MYREQUEST['OB']),'</th>'; + + if($fieldname=='info') { + $cols+=2; + echo '<th>',sortheader('T','Timeout',"&OB=".$MYREQUEST['OB']),'</th>'; + } + echo '<th>',sortheader('D','Deleted at',"&OB=".$MYREQUEST['OB']),'</th></tr>'; + + // builds list with alpha numeric sortable keys + // + $list = array(); + + foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $i => $entry) { + switch($MYREQUEST['SORT1']) { + case 'A': $k=sprintf('%015d-',$entry['atime']); break; + case 'H': $k=sprintf('%015d-',$entry['nhits']); break; + case 'Z': $k=sprintf('%015d-',$entry['mem_size']); break; + case 'M': $k=sprintf('%015d-',$entry['mtime']); break; + case 'C': $k=sprintf('%015d-',$entry['ctime']); break; + case 'T': $k=sprintf('%015d-',$entry['ttl']); break; + case 'D': $k=sprintf('%015d-',$entry['dtime']); break; + case 'S': $k=$entry["key"]; break; + } + if (!$AUTHENTICATED) { + // hide all path entries if not logged in + $list[$k.$entry[$fieldname]]=preg_replace('/^.*(\\/|\\\\)/','*hidden*/',$entry); + } else { + $list[$k.$entry[$fieldname]]=$entry; + } + } + + if ($list) { + // sort list + // + switch ($MYREQUEST['SORT2']) { + case "A": krsort($list); break; + case "D": ksort($list); break; + } + + // output list + $i=0; + foreach($list as $k => $entry) { + if(!$MYREQUEST['SEARCH'] || preg_match($MYREQUEST['SEARCH'], $entry[$fieldname]) != 0) { + $sh=md5($entry["key"]); + $field_value = htmlentities(strip_tags($entry[$fieldname],''), ENT_QUOTES, 'UTF-8'); + echo + '<tr class=tr-',$i%2,'>', + "<td class=td-0><a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&SH=",$sh,"\">",$field_value,'</a></td>', + '<td class="td-n center">',$entry['nhits'],'</td>', + '<td class="td-n right">',$entry['mem_size'],'</td>', + '<td class="td-n center">',date(DATE_FORMAT,$entry['atime']),'</td>', + '<td class="td-n center">',date(DATE_FORMAT,$entry['mtime']),'</td>', + '<td class="td-n center">',date(DATE_FORMAT,$entry['ctime']),'</td>'; + + if($fieldname=='info') { + if($entry['ttl']) + echo '<td class="td-n center">'.$entry['ttl'].' seconds</td>'; + else + echo '<td class="td-n center">None</td>'; + } + if ($entry['dtime']) { + + echo '<td class="td-last center">', date(DATE_FORMAT,$entry['dtime']), '</td>'; + } else if ($MYREQUEST['OB'] == OB_USER_CACHE) { + + echo '<td class="td-last center">'; + echo '[<a href="', $MY_SELF, '&OB=', $MYREQUEST['OB'], '&DU=', urlencode($entry[$fieldkey]), '">Delete Now</a>]'; + echo '</td>'; + } else { + echo '<td class="td-last center"> </td>'; + } + echo '</tr>'; + if ($sh == $MYREQUEST["SH"]) { + echo '<tr>'; + echo '<td colspan="7"><pre>'.htmlentities(print_r(apcu_fetch($entry['key']), 1)).'</pre></td>'; + echo '</tr>'; + } + $i++; + if ($i == $MYREQUEST['COUNT']) + break; + } + } + + } else { + echo '<tr class=tr-0><td class="center" colspan=',$cols,'><i>No data</i></td></tr>'; + } + echo <<< EOB + </tbody></table> +EOB; + + if ($list && $i < count($list)) { + echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>'; + } + + echo <<< EOB + </div> +EOB; + break; + +// ----------------------------------------------- +// Version check +// ----------------------------------------------- +case OB_VERSION_CHECK: + echo <<<EOB + <div class="info"><h2>APCu Version Information</h2> + <table cellspacing=0><tbody> + <tr> + <th></th> + </tr> +EOB; + if (defined('PROXY')) { + $ctxt = stream_context_create( array( 'http' => array( 'proxy' => PROXY, 'request_fulluri' => True ) ) ); + $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apcu.rss", False, $ctxt); + } else { + $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apcu.rss"); + } + if (!$rss) { + echo '<tr class="td-last center"><td>Unable to fetch version information.</td></tr>'; + } else { + $apcversion = phpversion('apc'); + + preg_match('!<title>APCu ([0-9.]+)</title>!', $rss, $match); + echo '<tr class="tr-0 center"><td>'; + if (version_compare($apcversion, $match[1], '>=')) { + echo '<div class="ok">You are running the latest version of APCu ('.$apcversion.')</div>'; + $i = 3; + } else { + echo '<div class="failed">You are running an older version of APCu ('.$apcversion.'), + newer version '.$match[1].' is available at <a href="http://pecl.php.net/package/APCu/'.$match[1].'"> + http://pecl.php.net/package/APCu/'.$match[1].'</a> + </div>'; + $i = -1; + } + echo '</td></tr>'; + echo '<tr class="tr-0"><td><h3>Change Log:</h3><br/>'; + + preg_match_all('!<(title|description)>([^<]+)</\\1>!', $rss, $match); + next($match[2]); next($match[2]); + + while (list(,$v) = each($match[2])) { + list(,$ver) = explode(' ', $v, 2); + if ($i < 0 && version_compare($apcversion, $ver, '>=')) { + break; + } else if (!$i--) { + break; + } + echo "<b><a href=\"http://pecl.php.net/package/APCu/$ver\">".htmlspecialchars($v, ENT_QUOTES, 'UTF-8')."</a></b><br><blockquote>"; + echo nl2br(htmlspecialchars(current($match[2]), ENT_QUOTES, 'UTF-8'))."</blockquote>"; + next($match[2]); + } + echo '</td></tr>'; + } + echo <<< EOB + </tbody></table> + </div> +EOB; + break; + +} + +echo <<< EOB + </div> +EOB; + +?> + +<!-- <?php echo "\nBased on APCGUI By R.Becker\n$VERSION\n"?> --> +</body> +</html> | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_api.h ^ |
(renamed from apcu-4.0.4/apc_api.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_api.h ^ |
(renamed from apcu-4.0.4/apc_api.h) | ||
[+] | Added | apcu-4.0.6.tgz/apcu-4.0.6/apc_bin.c ^ |
@@ -0,0 +1,557 @@ +/* + +----------------------------------------------------------------------+ + | APC | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2011 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Brian Shire <shire@php.net> | + | Xinchen Hui <laruence@php.net> | + +----------------------------------------------------------------------+ + + */ + +/* $Id: apc_bin.c 328828 2012-12-18 15:18:39Z remi $ */ + +/* Creates an architecture specific binary output to a string or file containing + * the current cache contents. This is accomplished via the apc_copy_* functions and + * "swizzling" pointers to achieve position independence. + */ + +#include "apc_globals.h" +#include "apc_bin.h" +#include "apc_php.h" +#include "apc_sma.h" +#include "apc_pool.h" +#include "apc_cache.h" + +#include "ext/standard/md5.h" + +/* in apc_cache.c */ +extern zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC); + +#define APC_BINDUMP_DEBUG 0 + +#if APC_BINDUMP_DEBUG + +#define SWIZZLE(bd, ptr) \ + do { \ + if((ptrdiff_t)bd < (ptrdiff_t)ptr && (size_t)ptr < ((size_t)bd + bd->size)) { \ + printf("SWIZZLE: %x ~> ", ptr); \ + ptr = (void*)((ptrdiff_t)(ptr) - (ptrdiff_t)(bd)); \ + printf("%x in %s on line %d", ptr, __FILE__, __LINE__); \ + } else if((ptrdiff_t)ptr > bd->size) { /* not swizzled */ \ + apc_error("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d" TSRMLS_CC, (ptrdiff_t)bd, ptr, ((size_t)bd + bd->size), __FILE__, __LINE__); \ + return; \ + } \ + printf("\n"); \ + } while(0); + +#define UNSWIZZLE(bd, ptr) \ + do { \ + printf("UNSWIZZLE: %x -> ", ptr); \ + ptr = (void*)((ptrdiff_t)(ptr) + (ptrdiff_t)(bd)); \ + printf("%x in %s on line %d \n", ptr, __FILE__, __LINE__); \ + } while(0); + +#else /* !APC_BINDUMP_DEBUG */ + +#define SWIZZLE(bd, ptr) \ + do { \ + if((ptrdiff_t)bd < (ptrdiff_t)ptr && (size_t)ptr < ((size_t)bd + bd->size)) { \ + ptr = (void*)((ptrdiff_t)(ptr) - (ptrdiff_t)(bd)); \ + } else if((size_t)ptr > bd->size) { /* not swizzled */ \ + apc_error("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d" TSRMLS_CC, (ptrdiff_t)bd, ptr, ((size_t)bd + bd->size), __FILE__, __LINE__); \ + return NULL; \ + } \ + } while(0); + +#define UNSWIZZLE(bd, ptr) \ + do { \ + ptr = (void*)((ptrdiff_t)(ptr) + (ptrdiff_t)(bd)); \ + } while(0); + +#endif + +static void *apc_bd_alloc(size_t size TSRMLS_DC); +static void apc_bd_free(void *ptr TSRMLS_DC); +static void *apc_bd_alloc_ex(void *ptr_new, size_t size TSRMLS_DC); + +typedef void (*apc_swizzle_cb_t)(apc_bd_t *bd, zend_llist *ll, void *ptr TSRMLS_DC); + +#if APC_BINDUMP_DEBUG +#define apc_swizzle_ptr(bd, ctxt, ll, ptr) _apc_swizzle_ptr(bd, ctxt, ll, (void*)ptr, __FILE__, __LINE__ TSRMLS_CC) +#else +#define apc_swizzle_ptr(bd, ctxt, ll, ptr) _apc_swizzle_ptr(bd, ctxt, ll, (void*)ptr, NULL, 0 TSRMLS_CC) +#endif + +static void _apc_swizzle_ptr(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, void **ptr, const char* file, int line TSRMLS_DC); +static void apc_swizzle_hashtable(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, HashTable *ht, apc_swizzle_cb_t swizzle_cb, int is_ptr TSRMLS_DC); +static void apc_swizzle_zval(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, zval *zv TSRMLS_DC); + +static apc_bd_t* apc_swizzle_bd(apc_bd_t* bd, zend_llist *ll TSRMLS_DC); +static int apc_unswizzle_bd(apc_bd_t *bd, int flags TSRMLS_DC); + +/* {{{ apc_bd_alloc + * callback for copy_* functions */ +static void *apc_bd_alloc(size_t size TSRMLS_DC) { + return apc_bd_alloc_ex(NULL, size TSRMLS_CC); +} /* }}} */ + +/* {{{ apc_bd_free + * callback for copy_* functions */ +static void apc_bd_free(void *ptr TSRMLS_DC) { + size_t *size; + if(zend_hash_index_find(&APCG(apc_bd_alloc_list), (ulong)ptr, (void**)&size) == FAILURE) { + apc_error("apc_bd_free could not free pointer (not found in list: %x)" TSRMLS_CC, ptr); + return; + } + APCG(apc_bd_alloc_ptr) = (void*)((size_t)APCG(apc_bd_alloc_ptr) - *size); + zend_hash_index_del(&APCG(apc_bd_alloc_list), (ulong)ptr); +} /* }}} */ + +/* {{{ apc_bd_alloc_ex + * set ranges or allocate a block of data from an already (e)malloc'd range. + * if ptr_new is not NULL, it will reset the pointer to start at ptr_new, + * with a range of size. If ptr_new is NULL, returns the next available + * block of given size. + */ +static void *apc_bd_alloc_ex(void *ptr_new, size_t size TSRMLS_DC) { + void *rval; + + rval = APCG(apc_bd_alloc_ptr); + if(ptr_new != NULL) { /* reset ptrs */ + APCG(apc_bd_alloc_ptr) = ptr_new; + APCG(apc_bd_alloc_ubptr) = (void*)((unsigned char *) ptr_new + size); + } else { /* alloc block */ + APCG(apc_bd_alloc_ptr) = (void*)((size_t)APCG(apc_bd_alloc_ptr) + size); +#if APC_BINDUMP_DEBUG + apc_notice("apc_bd_alloc: rval: 0x%x ptr: 0x%x ubptr: 0x%x size: %d" TSRMLS_CC, rval, APCG(apc_bd_alloc_ptr), APCG(apc_bd_alloc_ubptr), size); +#endif + if(APCG(apc_bd_alloc_ptr) > APCG(apc_bd_alloc_ubptr)) { + apc_error("Exceeded bounds check in apc_bd_alloc_ex by %d bytes." TSRMLS_CC, (unsigned char *) APCG(apc_bd_alloc_ptr) - (unsigned char *) APCG(apc_bd_alloc_ubptr)); + return NULL; + } + zend_hash_index_update(&APCG(apc_bd_alloc_list), (ulong)rval, &size, sizeof(size_t), NULL); + } + + return rval; +} /* }}} */ + +/* {{{ _apc_swizzle_ptr */ +static void _apc_swizzle_ptr(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, void **ptr, const char* file, int line TSRMLS_DC) { + if(*ptr) { + if((ptrdiff_t)bd < (ptrdiff_t)*ptr && (size_t)*ptr < ((size_t)bd + bd->size)) { + zend_llist_add_element(ll, &ptr); +#if APC_BINDUMP_DEBUG + printf("[%06d] apc_swizzle_ptr: %x -> %x ", zend_llist_count(ll), ptr, *ptr); + printf(" in %s on line %d \n", file, line); +#endif + } else if((size_t)ptr > bd->size) { + apc_error("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d" TSRMLS_CC, (ptrdiff_t)bd, *ptr, ((ptrdiff_t)bd + bd->size), file, line); \ + return; + } + } +} /* }}} */ + +/* {{{ apc_swizzle_hashtable */ +static void apc_swizzle_hashtable(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, HashTable *ht, apc_swizzle_cb_t swizzle_cb, int is_ptr TSRMLS_DC) { + uint i; + Bucket **bp, **bp_prev; + + bp = &ht->pListHead; + while(*bp) { + bp_prev = bp; + bp = &(*bp)->pListNext; + if(is_ptr) { + swizzle_cb(bd, ll, *(void**)(*bp_prev)->pData TSRMLS_CC); + apc_swizzle_ptr(bd, ctxt, ll, (*bp_prev)->pData); + } else { + swizzle_cb(bd, ll, (void**)(*bp_prev)->pData TSRMLS_CC); + } +#ifdef ZEND_ENGINE_2_4 + if ((*bp_prev)->nKeyLength) { + if (IS_INTERNED((*bp_prev)->arKey)) { + /* we should dump that internal string out */ + char *tmp = apc_bd_alloc((*bp_prev)->nKeyLength TSRMLS_CC); + memcpy(tmp, (*bp_prev)->arKey, (*bp_prev)->nKeyLength); + (*bp_prev)->arKey = tmp; + } + apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->arKey); + } +#endif + apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->pData); + if((*bp_prev)->pDataPtr) { + apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->pDataPtr); + } + if((*bp_prev)->pListLast) { + apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->pListLast); + } + if((*bp_prev)->pNext) { + apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->pNext); + } + if((*bp_prev)->pLast) { + apc_swizzle_ptr(bd, ctxt, ll, &(*bp_prev)->pLast); + } + apc_swizzle_ptr(bd, ctxt, ll, bp_prev); + } + for(i=0; i < ht->nTableSize; i++) { + if(ht->arBuckets[i]) { + apc_swizzle_ptr(bd, ctxt, ll, &ht->arBuckets[i]); + } + } + apc_swizzle_ptr(bd, ctxt, ll, &ht->pListTail); + + apc_swizzle_ptr(bd, ctxt, ll, &ht->arBuckets); +} /* }}} */ + +/* {{{ apc_swizzle_zval */ +static void apc_swizzle_zval(apc_bd_t *bd, apc_context_t* ctxt, zend_llist *ll, zval *zv TSRMLS_DC) { + + if(ctxt->copied.nTableSize) { + if(zend_hash_index_exists(&ctxt->copied, (ulong)zv)) { + return; + } + zend_hash_index_update(&ctxt->copied, (ulong)zv, (void**)&zv, sizeof(zval*), NULL); + } + + switch(Z_TYPE_P(zv) & IS_CONSTANT_TYPE_MASK) { + case IS_NULL: + case IS_LONG: + case IS_DOUBLE: + case IS_BOOL: + case IS_RESOURCE: + /* nothing to do */ + break; + case IS_CONSTANT: + case IS_STRING: + apc_swizzle_ptr(bd, ctxt, ll, &zv->value.str.val); + break; + case IS_ARRAY: + apc_swizzle_hashtable(bd, ctxt, ll, zv->value.ht, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC); + apc_swizzle_ptr(bd, ctxt, ll, &zv->value.ht); + break; + case IS_OBJECT: + break; + default: + assert(0); /* shouldn't happen */ + } +} /* }}} */ + +/* {{{ apc_swizzle_bd */ +static apc_bd_t* apc_swizzle_bd(apc_bd_t* bd, zend_llist *ll TSRMLS_DC) { + unsigned int i; + int count; + PHP_MD5_CTX context; + unsigned char digest[16]; + register php_uint32 crc; + void ***ptr; + void ***ptr_list; + + count = zend_llist_count(ll); + ptr_list = emalloc(count * sizeof(void**)); + ptr = zend_llist_get_first(ll); + for(i=0; i < count; i++) { +#if APC_BINDUMP_DEBUG + printf("[%06d] ", i+1); +#endif + SWIZZLE(bd, **ptr); /* swizzle ptr */ + if((ptrdiff_t)bd < (ptrdiff_t)*ptr && (size_t)*ptr < ((size_t)bd + bd->size)) { /* exclude ptrs that aren't actually included in the ptr list */ +#if APC_BINDUMP_DEBUG + printf("[------] "); +#endif + SWIZZLE(bd, *ptr); /* swizzle ptr list */ + ptr_list[i] = *ptr; + } + ptr = zend_llist_get_next(ll); + } + SWIZZLE(bd, bd->entries); + + if(count > 0) { + bd = erealloc(bd, bd->size + (count * sizeof(void**))); + bd->num_swizzled_ptrs = count; + bd->swizzled_ptrs = (void***)((unsigned char *)bd + bd->size -2); /* extra -1 for null termination */ + bd->size += count * sizeof(void**); + memcpy(bd->swizzled_ptrs, ptr_list, count * sizeof(void**)); + SWIZZLE(bd, bd->swizzled_ptrs); + } else { + bd->num_swizzled_ptrs = 0; + bd->swizzled_ptrs = NULL; + } + ((unsigned char*)bd)[((bd->size >= 1) ? (bd->size-1) : 0)] = 0; /* silence null termination for zval strings */ + efree(ptr_list); + bd->swizzled = 1; + + /* Generate MD5/CRC32 checksum */ + memset(bd->md5, 0, 16); + bd->crc=0; + + PHP_MD5Init(&context); + PHP_MD5Update(&context, (const unsigned char*)bd, bd->size); + PHP_MD5Final(digest, &context); + crc = apc_crc32((unsigned char*)bd, bd->size); + + memmove(bd->md5, digest, 16); + bd->crc = crc; + + return bd; +} /* }}} */ + +/* {{{ apc_unswizzle_bd */ +static int apc_unswizzle_bd(apc_bd_t *bd, int flags TSRMLS_DC) { + unsigned int i; + unsigned char md5_orig[16]; + unsigned char digest[16]; + PHP_MD5_CTX context; + register php_uint32 crc; + php_uint32 crc_orig; + + /* Verify the md5 or crc32 before we unswizzle */ + memmove(md5_orig, bd->md5, 16); + memset(bd->md5, 0, 16); + crc_orig = bd->crc; + bd->crc=0; + + if(flags & APC_BIN_VERIFY_MD5) { + PHP_MD5Init(&context); + PHP_MD5Update(&context, (const unsigned char*)bd, bd->size); + PHP_MD5Final(digest, &context); + if(memcmp(md5_orig, digest, 16)) { + apc_error("MD5 checksum of binary dump failed." TSRMLS_CC); + return -1; + } + } + if(flags & APC_BIN_VERIFY_CRC32) { + crc = apc_crc32((unsigned char*)bd, bd->size); + if(crc_orig != crc) { + apc_error("CRC32 checksum of binary dump failed." TSRMLS_CC); + return -1; + } + } + memcpy(bd->md5, md5_orig, 16); /* add back md5 checksum */ + bd->crc = crc_orig; + + UNSWIZZLE(bd, bd->entries); + UNSWIZZLE(bd, bd->swizzled_ptrs); + for(i=0; i < bd->num_swizzled_ptrs; i++) { + if(bd->swizzled_ptrs[i]) { + UNSWIZZLE(bd, bd->swizzled_ptrs[i]); + if(*bd->swizzled_ptrs[i] && (*bd->swizzled_ptrs[i] < (void*)bd)) { + UNSWIZZLE(bd, *bd->swizzled_ptrs[i]); + } + } + } + + bd->swizzled=0; + + return 0; +} /* }}} */ + +/* {{{ apc_bin_checkfilter */ +static int apc_bin_checkfilter(HashTable *filter, const char *key, uint key_len) { + zval **zptr; + + if(filter == NULL) { + return 1; + } + + if(zend_hash_find(filter, (char*)key, key_len, (void**)&zptr) == SUCCESS) { + if(Z_TYPE_PP(zptr) == IS_LONG && Z_LVAL_PP(zptr) == 0) { + return 0; + } + } else { + return 0; + } + + + return 1; +} /* }}} */ + +/* {{{ apc_bin_dump */ +PHP_APCU_API apc_bd_t* apc_bin_dump(apc_cache_t* cache, HashTable *user_vars TSRMLS_DC) { + apc_cache_slot_t *sp; + apc_bd_entry_t *ep; + int i, count=0; + apc_bd_t *bd; + zend_llist ll; + size_t size=0; + apc_context_t ctxt; + void *pool_ptr; + + zend_llist_init(&ll, sizeof(void*), NULL, 0); + zend_hash_init(&APCG(apc_bd_alloc_list), 0, NULL, NULL, 0); + + /* flip the hash for faster filter checking */ + user_vars = apc_flip_hash(user_vars); + + APC_RLOCK(cache->header); + + /* get size and entry counts */ + for(i=0; i < cache->nslots; i++) { + sp = cache->slots[i]; + for(; sp != NULL; sp = sp->next) { + if(apc_bin_checkfilter(user_vars, sp->key.str, sp->key.len)) { + size += sizeof(apc_bd_entry_t*) + sizeof(apc_bd_entry_t); + size += sp->value->mem_size - (sizeof(apc_cache_entry_t)); + count++; + } + } + } + + size += sizeof(apc_bd_t) +1; /* +1 for null termination */ + bd = emalloc(size); + bd->size = (unsigned int)size; + pool_ptr = emalloc(sizeof(apc_pool)); + apc_bd_alloc_ex(pool_ptr, sizeof(apc_pool) TSRMLS_CC); + + ctxt.serializer = cache->serializer; + ctxt.pool = apc_pool_create(APC_UNPOOL, apc_bd_alloc, apc_bd_free, NULL, NULL TSRMLS_CC); /* ideally the pool wouldn't be alloc'd as part of this */ + if (!ctxt.pool) { /* TODO need to cleanup */ + apc_warning("Unable to allocate memory for pool." TSRMLS_CC); + return NULL; + } + + ctxt.copy = APC_COPY_OTHER; /* avoid stupid ALLOC_ZVAL calls here, hack */ + apc_bd_alloc_ex((void*)((size_t)bd + sizeof(apc_bd_t)), bd->size - sizeof(apc_bd_t) -1 TSRMLS_CC); + bd->num_entries = count; + bd->entries = apc_bd_alloc_ex(NULL, sizeof(apc_bd_entry_t) * count TSRMLS_CC); + + /* User entries */ + zend_hash_init(&ctxt.copied, 0, NULL, NULL, 0); + count = 0; + for(i=0; i < cache->nslots; i++) { + sp = cache->slots[i]; + for(; sp != NULL; sp = sp->next) { + if(apc_bin_checkfilter(user_vars, sp->key.str, sp->key.len)) { + ep = &bd->entries[count]; + + /* copy key with current pool */ + ep->key.str = apc_pmemcpy(sp->key.str, sp->key.len, ctxt.pool TSRMLS_CC); + ep->key.len = sp->key.len; + + if ((Z_TYPE_P(sp->value->val) == IS_ARRAY && cache->serializer) + || Z_TYPE_P(sp->value->val) == IS_OBJECT) { + /* avoiding hash copy, hack */ + uint type = Z_TYPE_P(sp->value->val); + Z_TYPE_P(sp->value->val) = IS_STRING; + ep->val.val = apc_copy_zval(NULL, sp->value->val, &ctxt TSRMLS_CC); + + Z_TYPE_P(ep->val.val) = IS_OBJECT; + sp->value->val->type = type; + } else if (Z_TYPE_P(sp->value->val) == IS_ARRAY && !cache->serializer) { + /* this is a little complicated, we have to unserialize it first, then serialize it again */ + zval *garbage; + ctxt.copy = APC_COPY_OUT; + garbage = apc_copy_zval(NULL, sp->value->val, &ctxt TSRMLS_CC); + ctxt.copy = APC_COPY_IN; + ep->val.val = apc_copy_zval(NULL, garbage, &ctxt TSRMLS_CC); + ep->val.val->type = IS_OBJECT; + /* a memleak can not be avoided: zval_ptr_dtor(&garbage); */ + ctxt.copy = APC_COPY_OTHER; + } else { + ep->val.val = apc_copy_zval(NULL, sp->value->val, &ctxt TSRMLS_CC); + } + ep->val.ttl = sp->value->ttl; + + /* swizzle pointers */ + zend_hash_clean(&ctxt.copied); + if (ep->val.val->type == IS_OBJECT) { + apc_swizzle_ptr(bd, &ctxt, &ll, &bd->entries[count].val.val->value.str.val); + } else { + apc_swizzle_zval(bd, &ctxt, &ll, bd->entries[count].val.val TSRMLS_CC); + } + apc_swizzle_ptr(bd, &ctxt, &ll, &bd->entries[count].val.val); + apc_swizzle_ptr(bd, &ctxt, &ll, &bd->entries[count].key.str); + + count++; + } + } + } + zend_hash_destroy(&ctxt.copied); + ctxt.copied.nTableSize=0; + + /* append swizzle pointer list to bd */ + bd = apc_swizzle_bd(bd, &ll TSRMLS_CC); + zend_llist_destroy(&ll); + zend_hash_destroy(&APCG(apc_bd_alloc_list)); + + APC_RUNLOCK(cache->header); + + if(user_vars) { + zend_hash_destroy(user_vars); + efree(user_vars); + } + + efree(pool_ptr); + + return bd; +} /* }}} */ + +/* {{{ apc_bin_load */ +PHP_APCU_API int apc_bin_load(apc_cache_t* cache, apc_bd_t *bd, int flags TSRMLS_DC) { + apc_bd_entry_t *ep; + uint i; + apc_context_t ctxt; + + if (bd->swizzled) { + if(apc_unswizzle_bd(bd, flags TSRMLS_CC) < 0) { + return -1; + } + } + + for(i = 0; i < bd->num_entries; i++) { + ctxt.pool = apc_pool_create(APC_SMALL_POOL, (apc_malloc_t) apc_sma_malloc, (apc_free_t) apc_sma_free, apc_sma_protect, apc_sma_unprotect TSRMLS_CC); + if (!ctxt.pool) { /* TODO need to cleanup previous pools */ + apc_warning("Unable to allocate memory for pool." TSRMLS_CC); + goto failure; + } + ep = &bd->entries[i]; + { + zval *data; + uint use_copy = 0; + switch (Z_TYPE_P(ep->val.val)) { + case IS_OBJECT: + ctxt.copy = APC_COPY_OUT; + data = apc_copy_zval(NULL, ep->val.val, &ctxt TSRMLS_CC); + use_copy = 1; + break; + default: + data = ep->val.val; + break; + } + ctxt.copy = APC_COPY_IN; + + apc_cache_store( + cache, ep->key.str, ep->key.len, data, ep->val.ttl, 0 TSRMLS_CC); + + if (use_copy) { + zval_ptr_dtor(&data); + } + } + } + + return 0; + +failure: + apc_pool_destroy(ctxt.pool TSRMLS_CC); + apc_warning("Unable to allocate memory for apc binary load/dump functionality." TSRMLS_CC); + + HANDLE_UNBLOCK_INTERRUPTIONS(); + return -1; +} /* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: expandtab sw=4 ts=4 sts=4 fdm=marker + * vim<600: expandtab sw=4 ts=4 sts=4 + */ | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_bin.h ^ |
(renamed from apcu-4.0.4/apc_bin.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_bin.h ^ |
(renamed from apcu-4.0.4/apc_bin.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_bin_api.h ^ |
(renamed from apcu-4.0.4/apc_bin_api.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_bin_api.h ^ |
(renamed from apcu-4.0.4/apc_bin_api.h) | ||
[+] | Added | apcu-4.0.6.tgz/apcu-4.0.6/apc_cache.c ^ |
@@ -0,0 +1,1711 @@ +/* + +----------------------------------------------------------------------+ + | APC | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2011 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http:www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> | + | Rasmus Lerdorf <rasmus@php.net> | + | Arun C. Murthy <arunc@yahoo-inc.com> | + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> | + +----------------------------------------------------------------------+ + + This software was contributed to PHP by Community Connect Inc. in 2002 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1. + Future revisions and derivatives of this source code must acknowledge + Community Connect Inc. as the original contributor of this module by + leaving this note intact in the source code. + + All other licensing and usage conditions are those of the PHP Group. + + */ + +/* $Id: apc_cache.c 328743 2012-12-12 07:58:32Z ab $ */ + +#include "apc_cache.h" +#include "apc_sma.h" +#include "apc_globals.h" +#include "php_scandir.h" +#include "SAPI.h" +#include "TSRM.h" +#include "php_main.h" +#include "ext/standard/md5.h" +#include "ext/standard/php_var.h" +#include "ext/standard/php_smart_str.h" + +typedef void* (*ht_copy_fun_t)(void*, void*, apc_context_t* TSRMLS_DC); +typedef int (*ht_check_copy_fun_t)(Bucket*, va_list); + +#define CHECK(p) { if ((p) == NULL) return NULL; } + +static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC); +static HashTable* my_copy_hashtable_ex(HashTable*, HashTable* TSRMLS_DC, ht_copy_fun_t, int, apc_context_t*, ht_check_copy_fun_t, ...); +#define my_copy_hashtable( dst, src, copy_fn, holds_ptr, ctxt) \ + my_copy_hashtable_ex(dst, src TSRMLS_CC, copy_fn, holds_ptr, ctxt, NULL) + +/* {{{ make_prime */ +static int const primes[] = { + 257, /* 256 */ + 521, /* 512 */ + 1031, /* 1024 */ + 2053, /* 2048 */ + 3079, /* 3072 */ + 4099, /* 4096 */ + 5147, /* 5120 */ + 6151, /* 6144 */ + 7177, /* 7168 */ + 8209, /* 8192 */ + 9221, /* 9216 */ +10243, /* 10240 */ +11273, /* 11264 */ +12289, /* 12288 */ +13313, /* 13312 */ +14341, /* 14336 */ +15361, /* 15360 */ +16411, /* 16384 */ +17417, /* 17408 */ +18433, /* 18432 */ +19457, /* 19456 */ +0 /* sentinel */ +}; + +static int make_prime(int n) +{ + int *k = (int*)primes; + while(*k) { + if((*k) > n) return *k; + k++; + } + return *(k-1); +} +/* }}} */ + +/* {{{ make_slot */ +apc_cache_slot_t* make_slot(apc_cache_t* cache, apc_cache_key_t *key, apc_cache_entry_t* value, apc_cache_slot_t* next, time_t t TSRMLS_DC) +{ + apc_cache_slot_t* p = NULL; + + /* allocate slot */ + if ((p = value->pool->palloc(value->pool, sizeof(apc_cache_slot_t) TSRMLS_CC))) { + + /* copy identifier */ + char* strkey = (char*) apc_pmemcpy( + key->str, key->len, + value->pool TSRMLS_CC + ); + + if (strkey) { + /* set idenfieir */ + key->str = strkey; + + /* set slot data */ + p->key = key[0]; + p->value = value; + + /* set slot relation */ + p->next = next; + + /* set slot defaults */ + p->nhits = 0; + p->ctime = t; + p->atime = t; + p->dtime = 0; + } + } + + return p; +} +/* }}} */ + +/* {{{ free_slot */ +static void free_slot(apc_cache_slot_t* slot TSRMLS_DC) +{ + /* destroy slot pool */ + apc_pool_destroy( + slot->value->pool TSRMLS_CC); +} +/* }}} */ + +/* {{{ apc_cache_hash_slot + Note: These calculations can and should be done outside of a lock */ +static void apc_cache_hash_slot(apc_cache_t* cache, + char *str, + zend_uint len, + zend_ulong* hash, + zend_ulong* slot) { + (*hash) = zend_inline_hash_func(str, len); + (*slot) = (*hash) % (cache->nslots); +} /* }}} */ + +/* {{{ apc_cache_remove_slot */ +PHP_APCU_API void apc_cache_remove_slot(apc_cache_t* cache, apc_cache_slot_t** slot TSRMLS_DC) +{ + apc_cache_slot_t* dead = *slot; + + /* think here is safer */ + *slot = (*slot)->next; + + /* adjust header info */ + if (cache->header->mem_size) + cache->header->mem_size -= dead->value->mem_size; + + if (cache->header->nentries) + cache->header->nentries--; + + /* remove if there are no references */ + if (dead->value->ref_count <= 0) { + free_slot(dead TSRMLS_CC); + } else { + /* add to gc if there are still refs */ + dead->next = cache->header->gc; + dead->dtime = time(0); + cache->header->gc = dead; + } +} +/* }}} */ + +/* {{{ apc_cache_gc */ +PHP_APCU_API void apc_cache_gc(apc_cache_t* cache TSRMLS_DC) +{ + /* This function scans the list of removed cache entries and deletes any + * entry whose reference count is zero or that has been on the gc + * list for more than cache->gc_ttl seconds + * (we issue a warning in the latter case). + */ + if (!cache || !cache->header->gc) { + return; + } + + { + apc_cache_slot_t** slot = &cache->header->gc; + + while (*slot != NULL) { + time_t now = time(0); + time_t gc_sec = cache->gc_ttl ? (now - (*slot)->dtime) : 0; + + if (!(*slot)->value->ref_count || gc_sec > (time_t)cache->gc_ttl) { + apc_cache_slot_t* dead = *slot; + + /* good ol' whining */ + if (dead->value->ref_count > 0) { + apc_debug( + "GC cache entry '%s' was on gc-list for %d seconds" TSRMLS_CC, + dead->key.str, gc_sec + ); + } + + /* set next slot */ + *slot = dead->next; + + /* free slot */ + free_slot( + dead TSRMLS_CC); + + /* next */ + continue; + + } else { + slot = &(*slot)->next; + } + } + } +} +/* }}} */ + +/* {{{ php serializer */ +PHP_APCU_API int APC_SERIALIZER_NAME(php) (APC_SERIALIZER_ARGS) +{ + smart_str strbuf = {0}; + php_serialize_data_t var_hash; + PHP_VAR_SERIALIZE_INIT(var_hash); + php_var_serialize(&strbuf, (zval**)&value, &var_hash TSRMLS_CC); + PHP_VAR_SERIALIZE_DESTROY(var_hash); + if(strbuf.c) { + *buf = (unsigned char*)strbuf.c; + *buf_len = strbuf.len; + smart_str_0(&strbuf); + return 1; + } + return 0; +} /* }}} */ + +/* {{{ php unserializer */ +PHP_APCU_API int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS) +{ + const unsigned char *tmp = buf; + php_unserialize_data_t var_hash; + PHP_VAR_UNSERIALIZE_INIT(var_hash); + if(!php_var_unserialize(value, &tmp, buf + buf_len, &var_hash TSRMLS_CC)) { + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + zval_dtor(*value); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %ld bytes", (long)(tmp - buf), (long)buf_len); + (*value)->type = IS_NULL; + return 0; + } + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + return 1; +} /* }}} */ + +/* {{{ apc_cache_create */ +PHP_APCU_API apc_cache_t* apc_cache_create(apc_sma_t* sma, apc_serializer_t* serializer, int size_hint, int gc_ttl, int ttl, long smart, zend_bool defend TSRMLS_DC) { + apc_cache_t* cache; + int cache_size; + int nslots; + + /* calculate number of slots */ + nslots = make_prime(size_hint > 0 ? size_hint : 2000); + + /* allocate pointer by normal means */ + cache = (apc_cache_t*) apc_emalloc(sizeof(apc_cache_t) TSRMLS_CC); + + /* calculate cache size for shm allocation */ + cache_size = sizeof(apc_cache_header_t) + nslots*sizeof(apc_cache_slot_t*); + + /* allocate shm */ + cache->shmaddr = sma->smalloc(cache_size TSRMLS_CC); + if(!cache->shmaddr) { + apc_error("Unable to allocate shared memory for cache structures. (Perhaps your shared memory size isn't large enough?). " TSRMLS_CC); + return NULL; + } + + /* zero shm */ + memset(cache->shmaddr, 0, cache_size); + + /* set default header */ + cache->header = (apc_cache_header_t*) cache->shmaddr; + + cache->header->nhits = 0; + cache->header->nmisses = 0; + cache->header->nentries = 0; + cache->header->nexpunges = 0; + cache->header->gc = NULL; + cache->header->stime = time(NULL); + cache->header->state |= APC_CACHE_ST_NONE; + + /* set cache options */ + cache->slots = (apc_cache_slot_t**) (((char*) cache->shmaddr) + sizeof(apc_cache_header_t)); + cache->sma = sma; + cache->serializer = serializer; + cache->nslots = nslots; + cache->gc_ttl = gc_ttl; + cache->ttl = ttl; + cache->smart = smart; + cache->defend = defend; + + /* header lock */ + CREATE_LOCK(&cache->header->lock); + + /* zero slots */ + memset(cache->slots, 0, sizeof(apc_cache_slot_t*)*nslots); + + return cache; +} /* }}} */ + +/* {{{ apc_cache_store */ +PHP_APCU_API zend_bool apc_cache_store(apc_cache_t* cache, char *strkey, zend_uint keylen, const zval *val, const zend_uint ttl, const zend_bool exclusive TSRMLS_DC) { + apc_cache_entry_t *entry; + apc_cache_key_t key; + time_t t; + apc_context_t ctxt={0,}; + zend_bool ret = 0; + + t = apc_time(); + + /* initialize a context suitable for making an insert */ + if (apc_cache_make_context(cache, &ctxt, APC_CONTEXT_SHARE, APC_SMALL_POOL, APC_COPY_IN, 0 TSRMLS_CC)) { + + /* initialize the key for insertion */ + if (apc_cache_make_key(&key, strkey, keylen TSRMLS_CC)) { + + /* run cache defense */ + if (!apc_cache_defense(cache, &key TSRMLS_CC)) { + + /* initialize the entry for insertion */ + if ((entry = apc_cache_make_entry(&ctxt, &key, val, ttl TSRMLS_CC))) { + + /* execute an insertion */ + if (apc_cache_insert(cache, key, entry, &ctxt, t, exclusive TSRMLS_CC)) { + ret = 1; + } + } + } + } + + /* in any case of failure the context should be destroyed */ + if (!ret) { + apc_cache_destroy_context(&ctxt TSRMLS_CC); + } + } + + return ret; +} /* }}} */ + +/* {{{ data_unserialize */ +static zval* data_unserialize(const char *filename TSRMLS_DC) +{ + zval* retval; + long len = 0; + struct stat sb; + char *contents, *tmp; + FILE *fp; + php_unserialize_data_t var_hash = {0,}; + + if(VCWD_STAT(filename, &sb) == -1) { + return NULL; + } + + fp = fopen(filename, "rb"); + + len = sizeof(char)*sb.st_size; + + tmp = contents = malloc(len); + + if(!contents) { + fclose(fp); + return NULL; + } + + if(fread(contents, 1, len, fp) < 1) { + fclose(fp); + free(contents); + return NULL; + } + + MAKE_STD_ZVAL(retval); + + PHP_VAR_UNSERIALIZE_INIT(var_hash); + + /* I wish I could use json */ + if(!php_var_unserialize(&retval, (const unsigned char**)&tmp, (const unsigned char*)(contents+len), &var_hash TSRMLS_CC)) { + fclose(fp); + zval_ptr_dtor(&retval); + return NULL; + } + + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + + free(contents); + fclose(fp); + + return retval; +} + +static int apc_load_data(apc_cache_t* cache, const char *data_file TSRMLS_DC) +{ + char *p; + char key[MAXPATHLEN] = {0,}; + unsigned int key_len; + zval *data; + + p = strrchr(data_file, DEFAULT_SLASH); + + if(p && p[1]) { + strlcpy(key, p+1, sizeof(key)); + p = strrchr(key, '.'); + + if(p) { + p[0] = '\0'; + key_len = strlen(key)+1; + + data = data_unserialize(data_file TSRMLS_CC); + if(data) { + apc_cache_store(cache, key, key_len, data, 0, 1 TSRMLS_CC); + } + return 1; + } + } + + return 0; +} + +/* {{{ apc_cache_preload shall load the prepared data files in path into the specified cache */ +PHP_APCU_API zend_bool apc_cache_preload(apc_cache_t* cache, const char *path TSRMLS_DC) +{ +#ifndef ZTS + zend_bool result = 0; + char file[MAXPATHLEN]={0,}; + int ndir, i; + char *p = NULL; + struct dirent **namelist = NULL; + + if ((ndir = php_scandir(path, &namelist, 0, php_alphasort)) > 0) { + for (i = 0; i < ndir; i++) { + /* check for extension */ + if (!(p = strrchr(namelist[i]->d_name, '.')) + || (p && strcmp(p, ".data"))) { + free(namelist[i]); + continue; + } + + snprintf(file, MAXPATHLEN, "%s%c%s", + path, DEFAULT_SLASH, namelist[i]->d_name); + + if(apc_load_data(cache, file TSRMLS_CC)) { + result = 1; + } + free(namelist[i]); + } + free(namelist); + } + return result; +#else + apc_error("Cannot load data from apc.preload_path=%s in thread-safe mode" TSRMLS_CC, path); + return 0; +#endif +} /* }}} */ + +/* {{{ apc_cache_release */ +PHP_APCU_API void apc_cache_release(apc_cache_t* cache, apc_cache_entry_t* entry TSRMLS_DC) +{ + entry->ref_count--; +} +/* }}} */ + +/* {{{ apc_cache_destroy */ +PHP_APCU_API void apc_cache_destroy(apc_cache_t* cache TSRMLS_DC) +{ + if (!cache) { + return; + } + + /* destroy lock */ + DESTROY_LOCK(&cache->header->lock); + + /* XXX this is definitely a leak, but freeing this causes all the apache + children to freeze. It might be because the segment is shared between + several processes. To figure out is how to free this safely. */ + /*apc_sma_free(cache->shmaddr);*/ + apc_efree(cache TSRMLS_CC); +} +/* }}} */ + +/* {{{ apc_cache_real_expunge */ +PHP_APCU_API void apc_cache_real_expunge(apc_cache_t* cache TSRMLS_DC) { + /* increment counter */ + cache->header->nexpunges++; + + /* expunge */ + { + zend_ulong i; + + for (i = 0; i < cache->nslots; i++) { + apc_cache_slot_t* p = cache->slots[i]; + while (p) { + apc_cache_remove_slot(cache, &p TSRMLS_CC); + } + cache->slots[i] = NULL; + } + } + + /* set new time so counters make sense */ + cache->header->stime = apc_time(); + + /* reset counters */ + cache->header->ninserts = 0; + cache->header->nentries = 0; + cache->header->nhits = 0; + cache->header->nmisses = 0; + + /* resets lastkey */ + memset(&cache->header->lastkey, 0, sizeof(apc_cache_key_t)); +} /* }}} */ + +/* {{{ apc_cache_clear */ +PHP_APCU_API void apc_cache_clear(apc_cache_t* cache TSRMLS_DC) +{ + /* check there is a cache and it is not busy */ + if(!cache || apc_cache_busy(cache TSRMLS_CC)) { + return; + } + + /* lock header */ + APC_LOCK(cache->header); + + /* set busy */ + cache->header->state |= APC_CACHE_ST_BUSY; + + /* expunge cache */ + apc_cache_real_expunge(cache TSRMLS_CC); + + /* set info */ + cache->header->stime = apc_time(); + cache->header->nexpunges = 0; + + /* unset busy */ + cache->header->state &= ~APC_CACHE_ST_BUSY; + + /* unlock header */ + APC_UNLOCK(cache->header); +} +/* }}} */ + +/* {{{ apc_cache_default_expunge */ +PHP_APCU_API void apc_cache_default_expunge(apc_cache_t* cache, size_t size TSRMLS_DC) +{ + time_t t; + size_t suitable = 0L; + size_t available = 0L; + + t = apc_time(); + + /* check there is a cache, and it is not busy */ + if(!cache || apc_cache_busy(cache TSRMLS_CC)) { + return; + } + + /* get the lock for header */ + APC_LOCK(cache->header); + + /* update state in header */ + cache->header->state |= APC_CACHE_ST_BUSY; + + /* make suitable selection */ + suitable = (cache->smart > 0L) ? (size_t) (cache->smart * size) : (size_t) (cache->sma->size/2); + + /* gc */ + apc_cache_gc(cache TSRMLS_CC); + + /* get available */ + available = cache->sma->get_avail_mem(); + + /* perform expunge processing */ + if(!cache->ttl) { + + /* check it is necessary to expunge */ + if (available < suitable) { + apc_cache_real_expunge(cache TSRMLS_CC); + } + } else { + apc_cache_slot_t **slot; + + /* check that expunge is necessary */ + if (available < suitable) { + zend_ulong i; + + /* look for junk */ + for (i = 0; i < cache->nslots; i++) { + slot = &cache->slots[i]; + while (*slot) { + /* + * Entry TTL has precedence over cache TTL + */ + if((*slot)->value->ttl) { + if((time_t) ((*slot)->ctime + (*slot)->value->ttl) < t) { + apc_cache_remove_slot(cache, slot TSRMLS_CC); + continue; + } + } else if(cache->ttl) { + if((time_t) ((*slot)->ctime + cache->ttl) < t) { + apc_cache_remove_slot(cache, slot TSRMLS_CC); + continue; + } + } + + /* grab next slot */ + slot = &(*slot)->next; + } + } + + /* if the cache now has space, then reset last key */ + if (cache->sma->get_avail_size(size)) { + /* wipe lastkey */ + memset(&cache->header->lastkey, 0, sizeof(apc_cache_key_t)); + } else { + /* with not enough space left in cache, we are forced to expunge */ + apc_cache_real_expunge(cache TSRMLS_CC); + } + } + } + + /* we are done */ + cache->header->state &= ~APC_CACHE_ST_BUSY; + + /* unlock header */ + APC_UNLOCK(cache->header); +} +/* }}} */ + +/* {{{ apc_cache_make_context */ +PHP_APCU_API zend_bool apc_cache_make_context(apc_cache_t* cache, + apc_context_t* context, + apc_context_type context_type, + apc_pool_type pool_type, + apc_copy_type copy_type, + uint force_update TSRMLS_DC) { + switch (context_type) { + case APC_CONTEXT_SHARE: { + return apc_cache_make_context_ex( + context, + cache->serializer, + (apc_malloc_t) cache->sma->smalloc, + cache->sma->sfree, + cache->sma->protect, + cache->sma->unprotect, + pool_type, copy_type, force_update TSRMLS_CC + ); + } break; + + case APC_CONTEXT_NOSHARE: { + return apc_cache_make_context_ex( + context, + cache->serializer, + apc_php_malloc, apc_php_free, NULL, NULL, + pool_type, copy_type, force_update TSRMLS_CC + ); + } break; + + case APC_CONTEXT_NONE: + /* never used, just to make gcc warning free */ + break; + } + + return 0; +} /* }}} */ + +/* {{{ apc_cache_make_context_ex */ +PHP_APCU_API zend_bool apc_cache_make_context_ex(apc_context_t* context, + apc_serializer_t* serializer, + apc_malloc_t _malloc, + apc_free_t _free, + apc_protect_t _protect, + apc_unprotect_t _unprotect, + apc_pool_type pool_type, + apc_copy_type copy_type, + uint force_update TSRMLS_DC) { + /* attempt to create the pool */ + context->pool = apc_pool_create( + pool_type, _malloc, _free, _protect, _unprotect TSRMLS_CC + ); + + if (!context->pool) { + apc_warning("Unable to allocate memory for pool." TSRMLS_CC); + return 0; + } + + /* set context information */ + context->serializer = serializer; + context->copy = copy_type; + context->force_update = force_update; + + /* set this to avoid memory errors */ + memset(&context->copied, 0, sizeof(HashTable)); + + return 1; +} /* }}} */ + +/* {{{ apc_context_destroy */ +PHP_APCU_API zend_bool apc_cache_destroy_context(apc_context_t* context TSRMLS_DC) { + if (!context->pool) { + return 0; + } + + apc_pool_destroy(context->pool TSRMLS_CC); + + return 1; +} /* }}} */ + +/* {{{ apc_cache_insert */ +PHP_APCU_API zend_bool apc_cache_insert(apc_cache_t* cache, + apc_cache_key_t key, + apc_cache_entry_t* value, + apc_context_t* ctxt, + time_t t, + zend_bool exclusive TSRMLS_DC) +{ + zend_bool result = 0; + + /* at least */ + if (!value) { + return result; + } + + /* check we are able to deal with this request */ + if (!cache || apc_cache_busy(cache TSRMLS_CC)) { + return result; + } + + /* lock header */ + APC_LOCK(cache->header); + + /* process deleted list */ + apc_cache_gc(cache TSRMLS_CC); + + /* make the insertion */ + { + apc_cache_slot_t** slot; + + /* + * select appropriate slot ... + */ + slot = &cache->slots[key.h % cache->nslots]; + + while (*slot) { + + /* check for a match by hash and string */ + if (((*slot)->key.h == key.h) && (!memcmp((*slot)->key.str, key.str, key.len))) { + + /* + * At this point we have found the user cache entry. If we are doing + * an exclusive insert (apc_add) we are going to bail right away if + * the user entry already exists and it has no ttl, or + * there is a ttl and the entry has not timed out yet. + */ + if(exclusive) { + if (!(*slot)->value->ttl || (time_t) ((*slot)->ctime + (*slot)->value->ttl) >= t) { + goto nothing; + } + } + apc_cache_remove_slot(cache, slot TSRMLS_CC); + break; + } else + + /* + * This is a bit nasty. The idea here is to do runtime cleanup of the linked list of + * slot entries so we don't always have to skip past a bunch of stale entries. We check + * for staleness here and get rid of them by first checking to see if the cache has a global + * access ttl on it and removing entries that haven't been accessed for ttl seconds and secondly + * we see if the entry has a hard ttl on it and remove it if it has been around longer than its ttl + */ + if((cache->ttl && (time_t)(*slot)->atime < (t - (time_t)cache->ttl)) || + ((*slot)->value->ttl && (time_t) ((*slot)->ctime + (*slot)->value->ttl) < t)) { + apc_cache_remove_slot(cache, slot TSRMLS_CC); + continue; + } + + /* set next slot */ + slot = &(*slot)->next; + } + + if ((*slot = make_slot(cache, &key, value, *slot, t TSRMLS_CC)) != NULL) { + /* set value size from pool size */ + value->mem_size = ctxt->pool->size; + + cache->header->mem_size += ctxt->pool->size; + cache->header->nentries++; + cache->header->ninserts++; + } else { + goto nothing; + } + } + + /* unlock and return succesfull */ + APC_UNLOCK(cache->header); + + return 1; + + /* bail */ +nothing: + APC_UNLOCK(cache->header); + + return 0; +} +/* }}} */ + +/* {{{ apc_cache_find */ +PHP_APCU_API apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, char *strkey, zend_uint keylen, time_t t TSRMLS_DC) +{ + /* check we are able to deal with the request */ + if(!cache || apc_cache_busy(cache TSRMLS_CC)) { + return NULL; + } + + /* we only declare a volatile we need */ + { + apc_cache_slot_t** slot; + zend_ulong h, s; + + volatile apc_cache_entry_t* value = NULL; + + /* calculate hash and slot */ + apc_cache_hash_slot(cache, strkey, keylen, &h, &s); + + /* read lock header */ + APC_RLOCK(cache->header); + + /* find head */ + slot = &cache->slots[s]; + + while (*slot) { + /* check for a matching key by has and identifier */ + if ((h == (*slot)->key.h) && !memcmp((*slot)->key.str, strkey, keylen)) { + + /* Check to make sure this entry isn't expired by a hard TTL */ + if((*slot)->value->ttl && (time_t) ((*slot)->ctime + (*slot)->value->ttl) < t) { + /* increment misses on cache */ + cache->header->nmisses++; + + /* unlock header */ + APC_RUNLOCK(cache->header); + + return NULL; + } + + /* Otherwise we are fine, increase counters and return the cache entry */ + (*slot)->nhits++; + (*slot)->value->ref_count++; + (*slot)->atime = t; + + /* set cache num hits */ + cache->header->nhits++; + + /* grab value */ + value = (*slot)->value; + + /* unlock header */ + APC_RUNLOCK(cache->header); + + return (apc_cache_entry_t*)value; + } + + /* next */ + slot = &(*slot)->next; + } + + /* not found, so increment misses */ + cache->header->nmisses++; + + /* unlock header */ + APC_RUNLOCK(cache->header); + } + + return NULL; +} +/* }}} */ + +/* {{{ apc_cache_fetch */ +PHP_APCU_API zend_bool apc_cache_fetch(apc_cache_t* cache, char* strkey, zend_uint keylen, time_t t, zval **dst TSRMLS_DC) +{ + apc_cache_entry_t *entry; + zend_bool ret = 0; + + /* find the entry */ + if ((entry = apc_cache_find(cache, strkey, keylen, t TSRMLS_CC))) { + /* context for copying out */ + apc_context_t ctxt = {0, }; + + /* create unpool context */ + if (apc_cache_make_context(cache, &ctxt, APC_CONTEXT_NOSHARE, APC_UNPOOL, APC_COPY_OUT, 0 TSRMLS_CC)) { + + /* copy to destination */ + apc_cache_fetch_zval(&ctxt, *dst, entry->val TSRMLS_CC); + + /* release entry */ + apc_cache_release( + cache, entry TSRMLS_CC); + + /* destroy context */ + apc_cache_destroy_context(&ctxt TSRMLS_CC ); + + /* set result */ + ret = 1; + } + } + + return ret; +} /* }}} */ + +/* {{{ apc_cache_exists */ +PHP_APCU_API apc_cache_entry_t* apc_cache_exists(apc_cache_t* cache, char *strkey, zend_uint keylen, time_t t TSRMLS_DC) +{ + if(apc_cache_busy(cache TSRMLS_CC)) + { + /* cache cleanup in progress */ + return NULL; + } + + /* we only declare volatiles we need */ + { + apc_cache_slot_t** slot; + + volatile apc_cache_entry_t* value = NULL; + zend_ulong h, s; + + /* get hash and slot */ + apc_cache_hash_slot(cache, strkey, keylen, &h, &s); + + /* read lock header */ + APC_RLOCK(cache->header); + + /* find head */ + slot = &cache->slots[s]; + + while (*slot) { + /* check for match by hash and identifier */ + if ((h == (*slot)->key.h) && + !memcmp((*slot)->key.str, strkey, keylen)) { + + /* Check to make sure this entry isn't expired by a hard TTL */ + if((*slot)->value->ttl && (time_t) ((*slot)->ctime + (*slot)->value->ttl) < t) { + /* marked as a miss */ + cache->header->nmisses++; + + /* unlock header */ + APC_RUNLOCK(cache->header); + + return NULL; + } + + /* Return the cache entry ptr */ + value = (*slot)->value; + + /* unlock header */ + APC_RUNLOCK(cache->header); + + return (apc_cache_entry_t*)value; + } + + slot = &(*slot)->next; + } + + /* unlock header */ + APC_RUNLOCK(cache->header); + } + + return NULL; +} +/* }}} */ + +/* {{{ apc_cache_update */ +PHP_APCU_API zend_bool apc_cache_update(apc_cache_t* cache, char *strkey, zend_uint keylen, apc_cache_updater_t updater, void* data TSRMLS_DC) +{ + apc_cache_slot_t** slot; + + zend_bool retval = 0; + zend_ulong h, s; + + if(apc_cache_busy(cache TSRMLS_CC)) + { + /* cannot service request right now */ + return 0; + } + + /* calculate hash */ + apc_cache_hash_slot(cache, strkey, keylen, &h, &s); + + /* lock header */ + APC_LOCK(cache->header); + + /* find head */ + slot = &cache->slots[s]; + + while (*slot) { + /* check for a match by hash and identifier */ + if ((h == (*slot)->key.h) && + !memcmp((*slot)->key.str, strkey, keylen)) { + /* attempt to perform update */ + switch(Z_TYPE_P((*slot)->value->val) & ~IS_CONSTANT_TYPE_MASK) { + case IS_ARRAY: + case IS_OBJECT: + { + if(cache->serializer) { + retval = 0; + break; + } else { + /* fall through */ + } + } + /* fall through */ + default: + { + /* executing update */ + retval = updater( + cache, (*slot)->value, data); + + /* set modified time */ + (*slot)->key.mtime = apc_time(); + } + break; + } + /* unlock header */ + APC_UNLOCK(cache->header); + + return retval; + } + + /* set next slot */ + slot = &(*slot)->next; + } + + /* unlock header */ + APC_UNLOCK(cache->header); + + return 0; +} +/* }}} */ + +/* {{{ apc_cache_delete */ +PHP_APCU_API zend_bool apc_cache_delete(apc_cache_t* cache, char *strkey, zend_uint keylen TSRMLS_DC) +{ + apc_cache_slot_t** slot; + + zend_ulong h, s; + + if (!cache) { + return 1; + } + + /* calculate hash and slot */ + apc_cache_hash_slot(cache, strkey, keylen, &h, &s); + + /* lock cache */ + APC_LOCK(cache->header); + + /* find head */ + slot = &cache->slots[s]; + + while (*slot) { + /* check for a match by hash and identifier */ + if ((h == (*slot)->key.h) && + !memcmp((*slot)->key.str, strkey, keylen)) { + /* executing removal */ + apc_cache_remove_slot( + cache, slot TSRMLS_CC); + goto deleted; + } + + /* continue locking */ + slot = &(*slot)->next; + } + + /* unlock header */ + APC_UNLOCK(cache->header); + + return 0; + +deleted: + /* unlock deleted */ + APC_UNLOCK(cache->header); + + return 1; +} +/* }}} */ + +/* {{{ apc_cache_make_key */ +PHP_APCU_API zend_bool apc_cache_make_key(apc_cache_key_t* key, char* str, zend_ulong len TSRMLS_DC) +{ + assert(key != NULL); + + if (!str) { + return 0; + } + + if (!len) + len = strlen(str) + 1; + + key->str = str; + key->len = len; + key->h = zend_inline_hash_func((char *)key->str, key->len); + key->mtime = apc_time(); + + return 1; +} +/* }}} */ + +/* {{{ my_serialize_object */ +static zval* my_serialize_object(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC) +{ + smart_str buf = {0}; + apc_pool* pool = ctxt->pool; + apc_serialize_t serialize = APC_SERIALIZER_NAME(php); + void *config = NULL; + + if(ctxt->serializer) { + serialize = ctxt->serializer->serialize; + config = (ctxt->serializer->config != NULL) ? ctxt->serializer->config : ctxt; + } + + if(serialize((unsigned char**)&buf.c, &buf.len, src, config TSRMLS_CC)) { + dst->type = src->type & ~IS_CONSTANT; + dst->value.str.len = buf.len; + CHECK(dst->value.str.val = apc_pmemcpy(buf.c, (buf.len + 1), pool TSRMLS_CC)); + } + + if(buf.c) { + smart_str_free(&buf); + } + + return dst; +} +/* }}} */ + +/* {{{ my_unserialize_object */ +static zval* my_unserialize_object(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC) +{ + apc_unserialize_t unserialize = APC_UNSERIALIZER_NAME(php); + unsigned char *p = (unsigned char*)Z_STRVAL_P(src); + void *config = NULL; + + if(ctxt->serializer) { + unserialize = ctxt->serializer->unserialize; + config = (ctxt->serializer->config != NULL) ? ctxt->serializer->config : ctxt; + } + + if(unserialize(&dst, p, Z_STRLEN_P(src), config TSRMLS_CC)) { + return dst; + } else { + zval_dtor(dst); + dst->type = IS_NULL; + } + return dst; +} +/* }}} */ + + +/* {{{ my_copy_hashtable_ex */ +static APC_HOTSPOT HashTable* my_copy_hashtable_ex(HashTable* dst, + HashTable* src TSRMLS_DC, + ht_copy_fun_t copy_fn, + int holds_ptrs, + apc_context_t* ctxt, + ht_check_copy_fun_t check_fn, + ...) +{ + Bucket* curr = NULL; + Bucket* prev = NULL; + Bucket* newp = NULL; + int first = 1; + apc_pool* pool = ctxt->pool; + + assert(src != NULL); + + if (!dst) { + CHECK(dst = (HashTable*) pool->palloc(pool, sizeof(src[0]) TSRMLS_CC)); + } + + memcpy(dst, src, sizeof(src[0])); + + /* allocate buckets for the new hashtable */ + CHECK((dst->arBuckets = pool->palloc(pool, (dst->nTableSize * sizeof(Bucket*)) TSRMLS_CC))); + + memset(dst->arBuckets, 0, dst->nTableSize * sizeof(Bucket*)); + dst->pInternalPointer = NULL; + dst->pListHead = NULL; + + for (curr = src->pListHead; curr != NULL; curr = curr->pListNext) { + int n = curr->h % dst->nTableSize; + + if(check_fn) { + va_list args; + va_start(args, check_fn); + + /* Call the check_fn to see if the current bucket + * needs to be copied out + */ + if(!check_fn(curr, args)) { + dst->nNumOfElements--; + va_end(args); + continue; + } + + va_end(args); + } + + /* create a copy of the bucket 'curr' */ +#ifdef ZEND_ENGINE_2_4 + if (!curr->nKeyLength) { + CHECK((newp = (Bucket*) apc_pmemcpy(curr, sizeof(Bucket), pool TSRMLS_CC))); + } else if (IS_INTERNED(curr->arKey)) { + CHECK((newp = (Bucket*) apc_pmemcpy(curr, sizeof(Bucket), pool TSRMLS_CC))); + } else { + /* I repeat, this is ugly */ + CHECK((newp = (Bucket*) apc_pmemcpy(curr, sizeof(Bucket) + curr->nKeyLength, pool TSRMLS_CC))); + newp->arKey = (const char*)(newp+1); + } +#else + CHECK((newp = (Bucket*) apc_pmemcpy(curr, + (sizeof(Bucket) + curr->nKeyLength - 1), + pool TSRMLS_CC))); +#endif + + /* insert 'newp' into the linked list at its hashed index */ + if (dst->arBuckets[n]) { + newp->pNext = dst->arBuckets[n]; + newp->pLast = NULL; + newp->pNext->pLast = newp; + } else { + newp->pNext = newp->pLast = NULL; + } + + dst->arBuckets[n] = newp; + + /* copy the bucket data using our 'copy_fn' callback function */ + CHECK((newp->pData = copy_fn(NULL, curr->pData, ctxt TSRMLS_CC))); + + if (holds_ptrs) { + memcpy(&newp->pDataPtr, newp->pData, sizeof(void*)); + } + else { + newp->pDataPtr = NULL; + } + + /* insert 'newp' into the table-thread linked list */ + newp->pListLast = prev; + newp->pListNext = NULL; + + if (prev) { + prev->pListNext = newp; + } + + if (first) { + dst->pListHead = newp; + first = 0; + } + + prev = newp; + } + + dst->pListTail = newp; + + zend_hash_internal_pointer_reset(dst); + + return dst; +} +/* }}} */ + + +/* {{{ my_copy_zval_ptr */ +static zval** my_copy_zval_ptr(zval** dst, const zval** src, apc_context_t* ctxt TSRMLS_DC) +{ + zval* dst_new; + apc_pool* pool = ctxt->pool; + int usegc = (ctxt->copy == APC_COPY_OUT); + + assert(src != NULL); + + if (!dst) { + CHECK(dst = (zval**) pool->palloc(pool, sizeof(zval*) TSRMLS_CC)); + } + + if(usegc) { + ALLOC_ZVAL(dst[0]); + CHECK(dst[0]); + } else { + CHECK((dst[0] = (zval*) pool->palloc(pool, sizeof(zval) TSRMLS_CC))); + } + + CHECK((dst_new = my_copy_zval(*dst, *src, ctxt TSRMLS_CC))); + + if(dst_new != *dst) { + if(usegc) { + FREE_ZVAL(dst[0]); + } + *dst = dst_new; + } + + return dst; +} +/* }}} */ + +/* {{{ my_copy_zval */ +static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC) +{ + zval **tmp; + apc_pool* pool = ctxt->pool; + + assert(dst != NULL); + assert(src != NULL); + + memcpy(dst, src, sizeof(src[0])); + + if(ctxt->copied.nTableSize) { + if(zend_hash_index_find(&ctxt->copied, (ulong)src, (void**)&tmp) == SUCCESS) { + if(Z_ISREF_P((zval*)src)) { + Z_SET_ISREF_PP(tmp); + } + Z_ADDREF_PP(tmp); + return *tmp; + } + + zend_hash_index_update(&ctxt->copied, (ulong)src, (void**)&dst, sizeof(zval*), NULL); + } + + if(ctxt->copy == APC_COPY_OUT || ctxt->copy == APC_COPY_IN) { + /* deep copies are refcount(1), but moved up for recursive + * arrays, which end up being add_ref'd during its copy. */ + Z_SET_REFCOUNT_P(dst, 1); + Z_UNSET_ISREF_P(dst); + } else { + /* code uses refcount=2 for consts */ + Z_SET_REFCOUNT_P(dst, Z_REFCOUNT_P((zval*)src)); + Z_SET_ISREF_TO_P(dst, Z_ISREF_P((zval*)src)); + } + + switch (src->type & IS_CONSTANT_TYPE_MASK) { + case IS_RESOURCE: + case IS_BOOL: + case IS_LONG: + case IS_DOUBLE: + case IS_NULL: + break; + + case IS_CONSTANT: + case IS_STRING: + if (src->value.str.val) { + CHECK(dst->value.str.val = apc_pmemcpy(src->value.str.val, + src->value.str.len+1, + pool TSRMLS_CC)); + } + break; + + case IS_ARRAY: + if(ctxt->serializer == NULL) { + + CHECK(dst->value.ht = + my_copy_hashtable(NULL, + src->value.ht, + (ht_copy_fun_t) my_copy_zval_ptr, + 1, + ctxt)); + break; + } else { + /* fall through to object case */ + } + + case IS_OBJECT: + + dst->type = IS_NULL; + if(ctxt->copy == APC_COPY_IN) { + dst = my_serialize_object(dst, src, ctxt TSRMLS_CC); + } else if(ctxt->copy == APC_COPY_OUT) { + dst = my_unserialize_object(dst, src, ctxt TSRMLS_CC); + } + break; +#ifdef ZEND_ENGINE_2_4 + case IS_CALLABLE: + /* XXX implement this */ + assert(0); + break; +#endif + + default: + assert(0); + } + + return dst; +} +/* }}} */ + +/* {{{ apc_copy_zval */ +PHP_APCU_API zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC) +{ + apc_pool* pool = ctxt->pool; + + assert(src != NULL); + + if (!dst) { + if(ctxt->copy == APC_COPY_OUT) { + ALLOC_ZVAL(dst); + CHECK(dst); + } else { + CHECK(dst = (zval*) pool->palloc(pool, sizeof(zval) TSRMLS_CC)); + } + } + + CHECK(dst = my_copy_zval(dst, src, ctxt TSRMLS_CC)); + return dst; +} +/* }}} */ + +/* {{{ apc_cache_store_zval */ +PHP_APCU_API zval* apc_cache_store_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC) +{ + if (Z_TYPE_P(src) == IS_ARRAY) { + /* Maintain a list of zvals we've copied to properly handle recursive structures */ + zend_hash_init(&ctxt->copied, 0, NULL, NULL, 0); + dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC); + zend_hash_destroy(&ctxt->copied); + ctxt->copied.nTableSize=0; + } else { + dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC); + } + + + return dst; +} +/* }}} */ + +/* {{{ apc_cache_fetch_zval */ +PHP_APCU_API zval* apc_cache_fetch_zval(apc_context_t* ctxt, zval* dst, const zval* src TSRMLS_DC) +{ + if (Z_TYPE_P(src) == IS_ARRAY) { + /* Maintain a list of zvals we've copied to properly handle recursive structures */ + zend_hash_init(&ctxt->copied, 0, NULL, NULL, 0); + dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC); + zend_hash_destroy(&ctxt->copied); + ctxt->copied.nTableSize=0; + } else { + dst = apc_copy_zval(dst, src, ctxt TSRMLS_CC); + } + + + return dst; +} +/* }}} */ + +/* {{{ apc_cache_make_entry */ +PHP_APCU_API apc_cache_entry_t* apc_cache_make_entry(apc_context_t* ctxt, apc_cache_key_t *key, const zval* val, const unsigned int ttl TSRMLS_DC) +{ + apc_cache_entry_t* entry; + apc_pool* pool = ctxt->pool; + + entry = (apc_cache_entry_t*) pool->palloc(pool, sizeof(apc_cache_entry_t) TSRMLS_CC); + if (!entry) { + return NULL; + } + + /* set key for serializer */ + ctxt->key = key; + + entry->val = apc_cache_store_zval(NULL, val, ctxt TSRMLS_CC); + if(!entry->val) { + return NULL; + } + + INIT_PZVAL(entry->val); + entry->ttl = ttl; + entry->ref_count = 0; + entry->mem_size = 0; + entry->pool = pool; + return entry; +} +/* }}} */ + +/* {{{ apc_cache_link_info */ +static zval* apc_cache_link_info(apc_cache_t *cache, apc_cache_slot_t* p TSRMLS_DC) +{ + zval *link = NULL; + + ALLOC_INIT_ZVAL(link); + + if(!link) { + return NULL; + } + + array_init(link); + + add_assoc_stringl(link, "key", (char*) p->key.str, p->key.len-1, 1); + add_assoc_long(link, "ttl", (long)p->value->ttl); + + add_assoc_double(link, "nhits", (double)p->nhits); + add_assoc_long(link, "mtime", p->key.mtime); + add_assoc_long(link, "ctime", p->ctime); + add_assoc_long(link, "dtime", p->dtime); + add_assoc_long(link, "atime", p->atime); + add_assoc_long(link, "ref_count", p->value->ref_count); + add_assoc_long(link, "mem_size", p->value->mem_size); + + return link; +} +/* }}} */ + +/* {{{ apc_cache_info */ +PHP_APCU_API zval* apc_cache_info(apc_cache_t* cache, zend_bool limited TSRMLS_DC) +{ + zval *info = NULL; + zval *list = NULL; + zval *gc = NULL; + zval *slots = NULL; + apc_cache_slot_t* p; + zend_ulong i, j; + + if(!cache) { + return NULL; + } + + ALLOC_INIT_ZVAL(info); + + /* read lock header */ + APC_RLOCK(cache->header); + + array_init(info); + add_assoc_long(info, "nslots", cache->nslots); + add_assoc_long(info, "ttl", cache->ttl); + + add_assoc_double(info, "nhits", (double)cache->header->nhits); + add_assoc_double(info, "nmisses", (double)cache->header->nmisses); + add_assoc_double(info, "ninserts", (double)cache->header->ninserts); + add_assoc_long(info, "nentries", cache->header->nentries); + add_assoc_double(info, "nexpunges", (double)cache->header->nexpunges); + + add_assoc_long(info, "stime", cache->header->stime); + add_assoc_double(info, "mem_size", (double)cache->header->mem_size); + +#ifdef MULTIPART_EVENT_FORMDATA + add_assoc_long(info, "file_upload_progress", 1); +#else + add_assoc_long(info, "file_upload_progress", 0); +#endif +#if APC_MMAP + add_assoc_stringl(info, "memory_type", "mmap", sizeof("mmap")-1, 1); +#else + add_assoc_stringl(info, "memory_type", "IPC shared", sizeof("IPC shared")-1, 1); +#endif + + if(!limited) { + /* For each hashtable slot */ + ALLOC_INIT_ZVAL(list); + array_init(list); + + ALLOC_INIT_ZVAL(slots); + array_init(slots); + + for (i = 0; i < cache->nslots; i++) { + p = cache->slots[i]; + j = 0; + for (; p != NULL; p = p->next) { + zval *link = apc_cache_link_info(cache, p TSRMLS_CC); + add_next_index_zval(list, link); + j++; + } + if(j != 0) { + add_index_long(slots, (ulong)i, j); + } + } + + /* For each slot pending deletion */ + ALLOC_INIT_ZVAL(gc); + array_init(gc); + + for (p = cache->header->gc; p != NULL; p = p->next) { + zval *link = apc_cache_link_info(cache, p TSRMLS_CC); + add_next_index_zval(gc, link); + } + + add_assoc_zval(info, "cache_list", list); + add_assoc_zval(info, "deleted_list", gc); + add_assoc_zval(info, "slot_distribution", slots); + } + + /* unlock header */ + APC_RUNLOCK(cache->header); + + return info; +} +/* }}} */ + +/* + fetches information about the key provided +*/ +PHP_APCU_API zval* apc_cache_stat(apc_cache_t* cache, + char *strkey, + zend_uint keylen TSRMLS_DC) { + zval *stat; + apc_cache_slot_t** slot; + zend_ulong h, s; + + /* calculate hash and slot */ + apc_cache_hash_slot(cache, strkey, keylen, &h, &s); + + /* allocate stat buffer */ + ALLOC_INIT_ZVAL(stat); + + /* read lock header */ + APC_RLOCK(cache->header); + + /* find head */ + slot = &cache->slots[s]; + + while (*slot) { + /* check for a matching key by has and identifier */ + if ((h == (*slot)->key.h) && !memcmp((*slot)->key.str, strkey, keylen)) { + array_init(stat); + + add_assoc_long(stat, "hits", (*slot)->nhits); + add_assoc_long(stat, "atime", (*slot)->atime); + add_assoc_long(stat, "mtime", (*slot)->key.mtime); + add_assoc_long(stat, "ctime", (*slot)->ctime); + add_assoc_long(stat, "dtime", (*slot)->dtime); + add_assoc_long(stat, "ttl", (*slot)->value->ttl); + add_assoc_long(stat, "refs", (*slot)->value->ref_count); + + break; + } + + /* next */ + slot = &(*slot)->next; + } + + APC_RUNLOCK(cache->header); + + return stat; +} + +/* {{{ apc_cache_busy */ +PHP_APCU_API zend_bool apc_cache_busy(apc_cache_t* cache TSRMLS_DC) +{ + return (cache->header->state & APC_CACHE_ST_BUSY); +} +/* }}} */ + +/* {{{ apc_cache_defense */ +PHP_APCU_API zend_bool apc_cache_defense(apc_cache_t* cache, apc_cache_key_t* key TSRMLS_DC) +{ + zend_bool result = 0; + + /* in ZTS mode, we use the current TSRM context to determine the owner */ +#ifdef ZTS +# define FROM_DIFFERENT_THREAD(k) ((key->owner = TSRMLS_C) != (k)->owner) +#else +# define FROM_DIFFERENT_THREAD(k) ((key->owner = getpid()) != (k)->owner) +#endif + + /* only continue if slam defense is enabled */ + if (cache->defend) { + + /* for copy of locking key struct */ + apc_cache_key_t *last = &cache->header->lastkey; + + /* check the hash and length match */ + if(last->h == key->h && last->len == key->len) { + + /* check the time ( last second considered slam ) and context */ + if(last->mtime == key->mtime && + FROM_DIFFERENT_THREAD(last)) { + + /* potential cache slam */ + apc_debug( + "Potential cache slam averted for key '%s'" TSRMLS_CC, key->str); + result = 1; + } else { + /* sets enough information for an educated guess, but is not exact */ + last->h = key->h; + last->len = key->len; + last->mtime = apc_time(); + + /* required to tell contexts apart */ +#ifdef ZTS + last->owner = TSRMLS_C; +#else + last->owner = getpid(); +#endif + } + } + } + + return result; +} +/* }}} */ + +/* {{{ apc_cache_serializer */ +PHP_APCU_API void apc_cache_serializer(apc_cache_t* cache, const char* name TSRMLS_DC) { + if (cache && !cache->serializer) { + cache->serializer = apc_find_serializer(name TSRMLS_CC); + } +} /* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker + * vim<600: expandtab sw=4 ts=4 sts=4 + */ | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_cache.h ^ |
(renamed from apcu-4.0.4/apc_cache.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_cache.h ^ |
(renamed from apcu-4.0.4/apc_cache.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_cache_api.h ^ |
(renamed from apcu-4.0.4/apc_cache_api.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_cache_api.h ^ |
(renamed from apcu-4.0.4/apc_cache_api.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_globals.h ^ |
(renamed from apcu-4.0.4/apc_globals.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_globals.h ^ |
(renamed from apcu-4.0.4/apc_globals.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_iterator.c ^ |
(renamed from apcu-4.0.4/apc_iterator.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_iterator.c ^ |
(renamed from apcu-4.0.4/apc_iterator.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_iterator.h ^ |
(renamed from apcu-4.0.4/apc_iterator.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_iterator.h ^ |
(renamed from apcu-4.0.4/apc_iterator.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_lock.c ^ |
(renamed from apcu-4.0.4/apc_lock.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_lock.c ^ |
(renamed from apcu-4.0.4/apc_lock.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_lock.h ^ |
(renamed from apcu-4.0.4/apc_lock.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_lock.h ^ |
(renamed from apcu-4.0.4/apc_lock.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_lock_api.h ^ |
(renamed from apcu-4.0.4/apc_lock_api.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_lock_api.h ^ |
(renamed from apcu-4.0.4/apc_lock_api.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_mmap.c ^ |
(renamed from apcu-4.0.4/apc_mmap.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_mmap.c ^ |
(renamed from apcu-4.0.4/apc_mmap.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_mmap.h ^ |
(renamed from apcu-4.0.4/apc_mmap.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_mmap.h ^ |
(renamed from apcu-4.0.4/apc_mmap.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_php.h ^ |
(renamed from apcu-4.0.4/apc_php.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_php.h ^ |
(renamed from apcu-4.0.4/apc_php.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_php_pcre.h ^ |
(renamed from apcu-4.0.4/apc_php_pcre.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_php_pcre.h ^ |
(renamed from apcu-4.0.4/apc_php_pcre.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_pool.c ^ |
(renamed from apcu-4.0.4/apc_pool.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_pool.c ^ |
(renamed from apcu-4.0.4/apc_pool.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_pool.h ^ |
(renamed from apcu-4.0.4/apc_pool.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_pool.h ^ |
(renamed from apcu-4.0.4/apc_pool.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_pool_api.h ^ |
(renamed from apcu-4.0.4/apc_pool_api.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_pool_api.h ^ |
(renamed from apcu-4.0.4/apc_pool_api.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_rfc1867.c ^ |
(renamed from apcu-4.0.4/apc_rfc1867.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_rfc1867.c ^ |
(renamed from apcu-4.0.4/apc_rfc1867.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_serializer.h ^ |
(renamed from apcu-4.0.4/apc_serializer.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_serializer.h ^ |
(renamed from apcu-4.0.4/apc_serializer.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_shm.c ^ |
(renamed from apcu-4.0.4/apc_shm.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_shm.c ^ |
(renamed from apcu-4.0.4/apc_shm.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_shm.h ^ |
(renamed from apcu-4.0.4/apc_shm.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_shm.h ^ |
(renamed from apcu-4.0.4/apc_shm.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_signal.c ^ |
(renamed from apcu-4.0.4/apc_signal.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_signal.c ^ |
(renamed from apcu-4.0.4/apc_signal.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_signal.h ^ |
(renamed from apcu-4.0.4/apc_signal.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_signal.h ^ |
(renamed from apcu-4.0.4/apc_signal.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_sma.c ^ |
(renamed from apcu-4.0.4/apc_sma.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_sma.c ^ |
(renamed from apcu-4.0.4/apc_sma.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_sma.h ^ |
(renamed from apcu-4.0.4/apc_sma.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_sma.h ^ |
(renamed from apcu-4.0.4/apc_sma.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_sma_api.h ^ |
(renamed from apcu-4.0.4/apc_sma_api.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_sma_api.h ^ |
(renamed from apcu-4.0.4/apc_sma_api.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_stack.c ^ |
(renamed from apcu-4.0.4/apc_stack.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_stack.c ^ |
(renamed from apcu-4.0.4/apc_stack.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_stack.h ^ |
(renamed from apcu-4.0.4/apc_stack.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_stack.h ^ |
(renamed from apcu-4.0.4/apc_stack.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_windows_srwlock_kernel.c ^ |
(renamed from apcu-4.0.4/apc_windows_srwlock_kernel.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_windows_srwlock_kernel.c ^ |
(renamed from apcu-4.0.4/apc_windows_srwlock_kernel.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_windows_srwlock_kernel.h ^ |
(renamed from apcu-4.0.4/apc_windows_srwlock_kernel.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/apc_windows_srwlock_kernel.h ^ |
(renamed from apcu-4.0.4/apc_windows_srwlock_kernel.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/config.m4 ^ |
(renamed from apcu-4.0.4/config.m4) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/config.m4 ^ |
(renamed from apcu-4.0.4/config.m4) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/config.w32 ^ |
(renamed from apcu-4.0.4/config.w32) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/config.w32 ^ |
(renamed from apcu-4.0.4/config.w32) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/pgsql_s_lock.c ^ |
(renamed from apcu-4.0.4/pgsql_s_lock.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/pgsql_s_lock.c ^ |
(renamed from apcu-4.0.4/pgsql_s_lock.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/pgsql_s_lock.h ^ |
(renamed from apcu-4.0.4/pgsql_s_lock.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/pgsql_s_lock.h ^ |
(renamed from apcu-4.0.4/pgsql_s_lock.h) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/php_apc.c ^ |
(renamed from apcu-4.0.4/php_apc.c) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/php_apc.c ^ |
(renamed from apcu-4.0.4/php_apc.c) | ||
[+] | Added | apcu-4.0.6.tgz/apcu-4.0.6/php_apc.h ^ |
@@ -0,0 +1,55 @@ +/* + +----------------------------------------------------------------------+ + | APC | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2011 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> | + | George Schlossnagle <george@omniti.com> | + | Rasmus Lerdorf <rasmus@php.net> | + +----------------------------------------------------------------------+ + + This software was contributed to PHP by Community Connect Inc. in 2002 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1. + Future revisions and derivatives of this source code must acknowledge + Community Connect Inc. as the original contributor of this module by + leaving this note intact in the source code. + + All other licensing and usage conditions are those of the PHP Group. + + */ + +/* $Id: php_apc.h 328953 2013-01-03 02:19:19Z rasmus $ */ + +#ifndef PHP_APC_H +#define PHP_APC_H + +#include "apc_php.h" +#include "apc_globals.h" + +#define PHP_APCU_VERSION "4.0.6" +#define PHP_APCU_EXTNAME "apcu" + +extern zend_module_entry apcu_module_entry; +#define apcu_module_ptr &apcu_module_entry + +#define phpext_apcu_ptr apcu_module_ptr + +#endif /* PHP_APC_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker + * vim<600: expandtab sw=4 ts=4 sts=4 + */ | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/023-2.inc ^ |
(renamed from apcu-4.0.4/tests/023-2.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/023-2.inc ^ |
(renamed from apcu-4.0.4/tests/023-2.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/024.phpt ^ |
(renamed from apcu-4.0.4/tests/024.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/024.phpt ^ |
(renamed from apcu-4.0.4/tests/024.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc54_014.phpt ^ |
(renamed from apcu-4.0.4/tests/apc54_014.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc54_014.phpt ^ |
(renamed from apcu-4.0.4/tests/apc54_014.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc54_018.phpt ^ |
(renamed from apcu-4.0.4/tests/apc54_018.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc54_018.phpt ^ |
(renamed from apcu-4.0.4/tests/apc54_018.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_001.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_001.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_001.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_001.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_002.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_002.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_002.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_002.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_003.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_003.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_003.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_003.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_003b.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_003b.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_003b.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_003b.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_004.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_004.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_004.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_004.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_005.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_005.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_005.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_005.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_006.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_006.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_006.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_006.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_007.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_007.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_007.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_007.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_008.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_008.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_008.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_008.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_010.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_010.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_010.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_010.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_011.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_011.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_011.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_011.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_bin_001.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_bin_001.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_bin_001.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_bin_001.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_bin_002.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_bin_002.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_bin_002.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_bin_002.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_bin_003.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_bin_003.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_bin_003.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_bin_003.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_bin_004.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_bin_004.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/apc_bin_004.phpt ^ |
(renamed from apcu-4.0.4/tests/apc_bin_004.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/bug63224.phpt ^ |
(renamed from apcu-4.0.4/tests/bug63224.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/bug63224.phpt ^ |
(renamed from apcu-4.0.4/tests/bug63224.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/data/abc.data ^ |
(renamed from apcu-4.0.4/tests/data/abc.data) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/data/abc.data ^ |
(renamed from apcu-4.0.4/tests/data/abc.data) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/get_included_files_inc1.inc ^ |
(renamed from apcu-4.0.4/tests/get_included_files_inc1.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/get_included_files_inc1.inc ^ |
(renamed from apcu-4.0.4/tests/get_included_files_inc1.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/get_included_files_inc2.inc ^ |
(renamed from apcu-4.0.4/tests/get_included_files_inc2.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/get_included_files_inc2.inc ^ |
(renamed from apcu-4.0.4/tests/get_included_files_inc2.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/get_included_files_inc3.inc ^ |
(renamed from apcu-4.0.4/tests/get_included_files_inc3.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/get_included_files_inc3.inc ^ |
(renamed from apcu-4.0.4/tests/get_included_files_inc3.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_001.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_001.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_001.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_001.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_002.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_002.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_002.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_002.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_003.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_003.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_003.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_003.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_004.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_004.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_004.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_004.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_005.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_005.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_005.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_005.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_006.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_006.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_006.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_006.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_007.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_007.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_007.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_007.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_008.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_008.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/iterator_008.phpt ^ |
(renamed from apcu-4.0.4/tests/iterator_008.phpt) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/php_5_3_ns.inc ^ |
(renamed from apcu-4.0.4/tests/php_5_3_ns.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/php_5_3_ns.inc ^ |
(renamed from apcu-4.0.4/tests/php_5_3_ns.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/server_test.inc ^ |
(renamed from apcu-4.0.4/tests/server_test.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/server_test.inc ^ |
(renamed from apcu-4.0.4/tests/server_test.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/skipif.inc ^ |
(renamed from apcu-4.0.4/tests/skipif.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/apcu-4.0.6/tests/skipif.inc ^ |
(renamed from apcu-4.0.4/tests/skipif.inc) | ||
[+] | Changed | apcu-4.0.6.tgz/package.xml ^ |
@@ -16,11 +16,11 @@ <email>ab@php.net</email> <active>yes</active> </developer> - <date>2014-03-01</date> - <time>07:29:53</time> + <date>2014-06-12</date> + <time>13:39:04</time> <version> - <release>4.0.4</release> - <api>4.0.4</api> + <release>4.0.6</release> + <api>4.0.6</api> </version> <stability> <release>beta</release> @@ -28,8 +28,7 @@ </stability> <license uri="http://www.php.net/license">PHP License</license> <notes> -- Fix deadlocking due to destroyed locks -- Fix various compatibility bugs +- fix issues with stddef inclusion causing compilation issue </notes> <contents> <dir name="/"> @@ -70,14 +69,14 @@ <file md5sum="82180b525b9423f50c7fbfe2b61d0cd4" name="tests/data/abc.data" role="test" /> <file md5sum="5683ae20fe5dac6119fc2a93188e192f" name="apc_api.h" role="src" /> <file md5sum="be5af77f3b560a806c23d61cab15bf88" name="apc_bin_api.h" role="src" /> - <file md5sum="533f7780ed861111356211660f680cb7" name="apc_bin.c" role="src" /> + <file md5sum="d6d42c2df2a89ab9e5085ef547657ff7" name="apc_bin.c" role="src" /> <file md5sum="89b19e7b5bef1160105ff259fb6736bb" name="apc_bin.h" role="src" /> <file md5sum="8e01a00d40ce819a651ba5c80524280b" name="apc.c" role="src" /> <file md5sum="5f57118842050697bc5556a08973066c" name="apc_cache_api.h" role="src" /> - <file md5sum="3f28703375b3ae24ea7e53ca7bd97f4e" name="apc_cache.c" role="src" /> + <file md5sum="d6e4d82a73fd6018f347469db1a7e00d" name="apc_cache.c" role="src" /> <file md5sum="b2431ebb39c94c45be7cb3c4e1e04152" name="apc_cache.h" role="src" /> <file md5sum="11fa42ceb6b6311f74f9165d9fe90a93" name="apc_globals.h" role="src" /> - <file md5sum="40db920251c54b0d7ac20ac9492518c3" name="apc.h" role="src" /> + <file md5sum="fa0cf2e4147e7a94e3c89d3336f4968d" name="apc.h" role="src" /> <file md5sum="bf5777b6115c1732d98fb3177384f9b8" name="apc_iterator.c" role="src" /> <file md5sum="8fbf0e09a9dbf8aceebe4e6af705eb66" name="apc_iterator.h" role="src" /> <file md5sum="7c14ffb0b95a175076216f67111075b6" name="apc_lock_api.h" role="src" /> @@ -85,7 +84,7 @@ <file md5sum="bb617a55e93af3869b046920c0f45900" name="apc_lock.h" role="src" /> <file md5sum="3ddccc4e5a88133987f176d4cc898734" name="apc_mmap.c" role="src" /> <file md5sum="e6ce0f97275d5b248427c43b5e57612b" name="apc_mmap.h" role="src" /> - <file md5sum="68b02db79e2432c3e83cadb6c387f5cc" name="apc.php" role="src" /> + <file md5sum="f90002a89bd7186d87e7c7445008f6db" name="apc.php" role="src" /> <file md5sum="7e3dc5affdcea292fc2b7550c20ea44a" name="apc_php.h" role="src" /> <file md5sum="976283da87a44bf02a89c313a73de69d" name="apc_php_pcre.h" role="src" /> <file md5sum="8d9425d328a96c70d4ae6177dd75d514" name="apc_pool_api.h" role="src" /> @@ -108,15 +107,15 @@ <file md5sum="54bfc8892372c1cf55cfa069aaf81eb2" name="apc_serializer.h" role="src" /> <file md5sum="5be4ac2cf190c97d2933e008b57d1055" name="config.m4" role="src" /> <file md5sum="8c723e3d9a87c81326117fc32e56edff" name="config.w32" role="src" /> - <file md5sum="d6c836c279b1fbabf69ada700dd5cdfc" name="INSTALL" role="src" /> - <file md5sum="dd34a70236f008af999de817b93a5e3a" name="LICENSE" role="src" /> + <file md5sum="d6c836c279b1fbabf69ada700dd5cdfc" name="INSTALL" role="doc" /> + <file md5sum="dd34a70236f008af999de817b93a5e3a" name="LICENSE" role="doc" /> <file md5sum="155853fb8cb9945c07313f05874866b6" name="Makefile.frag" role="src" /> - <file md5sum="eea150699d3dffb2cdf7d243854189d7" name="NOTICE" role="src" /> + <file md5sum="eea150699d3dffb2cdf7d243854189d7" name="NOTICE" role="doc" /> <file md5sum="4b4ca2c00077d8636ab17052c120801b" name="php_apc.c" role="src" /> - <file md5sum="e5e36874cafc13bcdfbbf292421df0a2" name="php_apc.h" role="src" /> - <file md5sum="e57e4a3c23c3028fa0692996ba0232a6" name="README.md" role="src" /> - <file md5sum="8159d948b4d05994f7478b5d0e07c371" name="TECHNOTES.txt" role="src" /> - <file md5sum="19a56a46925a8196705c34e1d9878a07" name="TODO" role="src" /> + <file md5sum="de1476dfbd5aa4d0dfdabe81bf3ddc4c" name="php_apc.h" role="src" /> + <file md5sum="e57e4a3c23c3028fa0692996ba0232a6" name="README.md" role="doc" /> + <file md5sum="8159d948b4d05994f7478b5d0e07c371" name="TECHNOTES.txt" role="doc" /> + <file md5sum="19a56a46925a8196705c34e1d9878a07" name="TODO" role="doc" /> </dir> </contents> <dependencies> |