From: Dragan Dosen Date: Sun, 19 Apr 2009 16:28:19 +0000 (+0200) Subject: php5-apc retained as dummy package. X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?a=commitdiff_plain;ds=inline;p=php5-apc.git php5-apc retained as dummy package. debian/control: + depends on Debian package php-apc. --- diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index ee26c27..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,227 +0,0 @@ -3.0.19: 2008-05-14 -- Move expunge callback groundwork to 3.1 (Rasmus) -- Fix fd-leak (Gopal) -- Fix double-free on builtin functions (Gopal) -- Initial PHP 5.3 support (Gopal) - -3.0.18: 2008-03-28 -- Revert memleak patch (Gopal) -- Fix for bug #13504 (David Fraser) - -3.0.17: 2008-03-25 -- Fix for CVE-2008-1488 (Daniel Papasian, Rasmus) -- Fix apc_add() cache expunge bug (Rasmus) -- Added parameter to apc_fetch to determine success/failure when fetching booleans (shire) -- Fix misc. memleaks (shire) - -3.0.16: 2007-12-26 -- Fix for longstanding cache-full crash (Christian Seiler) - http://news.php.net/php.pecl.dev/4951 for the details -- Added optional shm unmap on a fatal signal feature (Lucas Nealan) -- Added PTHREAD_MUTEX_ADAPTIVE_NP option pthread locks (Paul Saab) -- Minor cleanups (Lucas Nealan) -- Added configure option to enable apc_cache_info('filehits') (Shire) - -3.0.15: 2007-10-18 -- Eliminate a per-request time() syscall (Rasmus) -- Added rfc1867 prefix, name, and freq ini options (Shire) -- Allow deletion of individual user cache entries via apc.php (Sara) -- Fix overzealous cleanup during RSHUTDOWN (Gopal) -- Fix memory alignment and locking issues (Gopal) -- Make apc_compile insert/replace entries (Shire) -- Make mixed inheritance recompile & cache afresh (Gopal) -- Make nostat mode search include_path for canonicalization (Gopal) -- ZTS & other compile fixes (Gopal, Edin, Shire) - -3.0.14: 2007-03-21 -- Build fix (Shire) -- Don't hook the upload hook if APC is disabled (Rasmus) -- Local shadow cache support (Gopal) -- Avoid uneccessary loops over op_arrays for "known" auto-globals (Gopal) -- Fix apc_add() to overwrite timed out user entries (Rasmus) -- Fix double inclusion of files with conditional classes in php4 (Gopal) -- Allocator fixes to reduce fragmentation (Gopal) - -3.0.13: 2007-02-24 -- File upload progress (Rasmus) -- Pthread mutex and spin locks (Shire) -- Recursive zval support for apc_fetch/_store (Shire, Gopal) -- apc.stat_ctime flag for ctime checks (Rasmus) -- Multiple key fetches with apc_fetch (Shire) -- Canary checks for shm memory deallocation (Gopal) -- Add hooks for external optimizer (Shire) -- Obsolete and remove apc optimizer (Gopal) -- APC info changes - cache insert rate, hit and miss rates (Shire) -- Fix apc_load_constants (Gopal) -- Rewrite dump opcode code to use vld (Gopal) -- Use apc_[ewn]print functions for error reporting (Shire) -- Auto global fixes and refactoring (Gopal, Shire) -- Fix memory leaks in object serialization (Ilia) -- Memory cleanup code for destructor order (Gopal) -- Win32 build fixes (Ilia, Wez) -- ZTS and Php 4 build fixes (Bjori) -- Add apc_add() function (Rasmus) -- Add optional limited flag to apc_sma_info() (Rasmus) - -3.0.12p2: 2006-09-05 -- Package version up - -3.0,12p1: 2006-09-05 -- PHP4 build fixes - -3.0.12: 2006-09-05 -- PHP 5.2 compatibility (Gopal) -- TSRM fixes (Gopal) -- Add extra flags to op_array->reserved to improve op array - processing code (Gopal) -- Fix crashes in optimizer and cli mode (Ilia) -- Optimizer fixes for PHP5 (Ilia, Gopal) -- Allow multiple inclusions of a file with a dynamic class (Gopal) -- Php 4 function table and properties fixes (Gopal) -- Fix memory leaks in apc_cache_info (Gopal) - -3.0.11: 2006-08-16 -- Made --enable-apc-mmap the default compile option (for real this time) -- Add an optional flag to apc_cache_info() and some apc.php tweaks to make it - only fetch header information to make it useful when you have tens of - thousands of entries. (Brian Shire) -- 64-bit fixes (George) -- Don't mix Full Path and Inode keys (George) -- Override ZEND_INCLUDE_OR_EVAL opcode (when possible) to speed up use of - require_once() and include_once() statements. (Sara) -- Add a non-blocking write_lock for cache inserts. This is a better approach - to prevent cache slams and deprecates the slam_defense setting. (Rasmus) -- A bit of work on the optimizer. (Sara) -- Various memory issues resolved. (Gopal) - -3.0.10: 2006-03-11 -- Add apc.stat ini flag which defaults to 1. If set to 0, the main script and any fullpath - includes will not be stat'ed for any changes. You will have to restart the server if you - change anything. This mode increases performance quite a bit, especially if you have a - lot of includes. - -- Get rid of the lock safety net hack I added in 3.0.9. It seems to cause more problems - than it solves. I'll need to revisit locking and signal handling at some point soon. - -3.0.9: 2006-03-04 -- Eliminate rand() call when slam_defense is not set (Rasmus) -- Fix for __isset problem (Gopal) -- Rewrite allocator from a "best fit" to a "next fit" algorithm (Rasmus) -- Added a Cache Full counter so we have an idea how many times the segment has filled up causing an expunge (Rasmus) -- Report back the correct number of available bytes in the segment instead of the allocated bytes. (Rasmus) -- Add cache busy flag which is set when an expunge is underway (Rasmus) -- Add automatic serialization of objects in apc_store() (Marcus) -- 64-bit .ini flag fix (Rasmus) -- Static members fix (Gopal) -- sma_cleanup() mem leak fix (Rasmus) -- Fix for http://pecl.php.net/bugs/5311 (Rasmus) -- Fix autoglobals JIT bug (Gopal) -- Fix instance bug (Gopal) -- Add a lock cleanup safety net to request shutdown (Rasmus) -- Fix apc.slam_defense edge-case bug (Rasmus) -- User entry memory usage tracking support (Ilia) -- Allow keys used in apc_store/apc_fetch/apc_delete to be binary safe and prevent conflicts between keys that are found at the start of other keys. (Ilia) - -3.0.8: 2005-08-24 -Fix invalid free in globals destructor introduced in 3.0.7 (Rasmus) -Cache corruption fix in cache-full cleanup code (Gopal) - -3.0.7: 2005-08-16 -- Fix to apc.php to show final segment in frag chart. (Ilia) -- A couple of win32 fixes. (Frank) -- Add apc.enable_cli ini directive. (Rasmus) -- Add test cases. (Marcus) -- Fix apc_define_constants() bug - http://pecl.php.net/bugs/5084 (Rasmus) -- Simplify user cache handling by removing the user_cache_stack (Rasmus) -- Fix apc_fetch() memory corruption (Andrei,Rasmus) -- Added apc.max_file_size INI setting that allows exclusion of large files from being cached. Default file size limit, 1 megabyte. (Ilia) - -3.0.6: 2005-07-30 -- Added apc.php to package.xml file. -- Track per-entry memory usage. (Val) -- Various apc.php fixes and enhancements. (Ralf, Ilia, Rasmus) -- fcntl locking robustness fixes. (Rasmus) -- Shared read-locks where possible. (Rasmus) -- Added file_update_protection configuration parameter. (Rasmus) -- Windows ZTS fixes (Frank) - -3.0.5: 2005-07-27 -- Make it easier for sapis that only populate file_handle->filename to use APC. (Rasmus) -- Support extensions such as bcompiler that need to hook into compile_file. (Val) -- Ralf Becker's apcgui code has now become the default apc.php status page. (Ralf, Rasmus, Ilia) -- Segfault in cache cleanup code (Ilia, Rasmus) - -3.0.4: 2005-07-18 -- Add win32 support (Edin ) -- Add --with-apxs switch to work around problem when loading APC into Apache binary compiled with LFS switches (Rasmus) -- A couple of other minor fixes - -3.0.3: 2005-07-05 -- Fix compile problem against PHP 5.0.x - -3.0.2: 2005-07-05 -- Better shm error message - -3.0.1: 2005-07-05 -- PHP4 build fix - -3.0: 2005-06-23 -- PHP 5.1 support (Arun, Gopal, Rasmus) -- Major Inheritance bug fix (Arun, Gopal) - -2.0: 2003-02-10 -- ground-up rewrite sharing none of the original source code (djc) - -1.0.10: -- merge mmap / shm code to be in one file, module supports both modes now [mpb 2001-05-15] -- added apc.mode config parameter [mpb 2001-05-15] NOTE: You'll have to add - this parameter to your php.ini file to activate apc shm or mmap caching -- generic source cleanup (missing includes, PATH_MAX usage etc) [mpb - 2001-05-15] -- fixed: realpath return result checking in generate_key [mpb 2001-05-15] -- updated: gui updated (extras/apc_gui-1.0.2.tar.gz) -- experminental 'fast' cache-retrieval [djc 2001-05-20] -- fixed regex support [gws 2001-05-16] -- enhanced reader-writer lock support [rg 2001-05-07] - -1.0.9: -- fixed (?) memory alignment bug on 64 bit archiecures -- added many cache visibiliy functions -- added opional fcntl locks under shm version -- numerous bug fixes - -1.0.8: -- added ability to detect and decompile compiled files placed as 'source' - [gws,dw 2001-01-30] -- fixed apc_rstat bug [gws 2001-01-29] -- added hack to support included urls [gws 2001-01-30] -- fixed apc_cache_index [mb 2001-01-31] -- added multiple regex support [gs 2001-02-03] -- added apc_cache_info [mb,gs 2001-02-03] - -1.0.7: -- partially fixed for Solaris [gws 2001-01-29] -- fixed mtime support for relative includes [gws 2001-01-29] -- code cleanup [yg,ta,gws 2001-01-29] - -1.0.6: -- support for mtime in mmap [yg,gws 2001-01-27] -- fixed indexed-array initialization bug [djc,gws 2001-01-27] - -1.0.5: -- support for relative include paths [djc,gws 2001-01-19] -- class member array support fixed [djc 2001-01-18] -- added apc_cache_index [gws 2001-01-18] - -1.0.4: -- support for class hierarchies greater than two levels deep [djc 2001-01-17] - -1.0.3: -- fixed support for class inheritance [djc 2001-01-16] - -1.0.2: -- support for inherited classes [gws 2001-01-15] -- support for intialization of class variables and objects [gws 2001-01-13] - -1.0.1: -- added optional file modification time check [djc 2001-01-12] diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 23ec35f..0000000 --- a/INSTALL +++ /dev/null @@ -1,417 +0,0 @@ -Installation Instructions for APC ---------------------------------- - -This version of APC should work on PHP 4.3.0 - 4.4.x and -5.1.0 - 5.2.x. Yes, that means PHP 5.0.x is no longer -supported. Upgrade to PHP 5.1.x or 5.2.x and you will -notice all sorts of performance increases. - -CVS Instructions ----------------- -Building from CVS can be done like this: - - cvs -d :pserver:cvsread@cvs.php.net:/repository login - Password: phpfi - cvs -d :pserver:cvsread@cvs.php.net:/repository co pecl/apc - cd pecl/apc - phpize - ./configure --enable-apc-mmap --with-apxs --with-php-config=/usr/local/php/bin/php-config - make - make install - -Suggested Configuration (in your php.ini file) ----------------------------------------------- - extension=apc.so - apc.enabled=1 - apc.shm_segments=1 - apc.shm_size=128 - apc.ttl=7200 - apc.user_ttl=7200 - apc.num_files_hint=1024 - apc.mmap_file_mask=/tmp/apc.XXXXXX - apc.enable_cli=1 - -These are fully described at the bottom of this file. - -PHP 4 Optimization ------------------- -If you are trying to get every little bit of speed out of PHP4+APC, you need -to tell APC where to find your httpd.h file and also add -DAPC_PHP4_STAT to -your CPPFLAGS. (if you don't have httpd.h, install the apache_dev package -for your OS) and do: - export CPPFLAGS="-I/usr/include/apache-1.3 -DAPC_PHP4_STAT" (for bash on Debian) - setenv CPPFLAGS "-I/usr/include/apache-1.3 -DAPC_PHP4_STAT" (for tsch on Debian) -and then re-run your configure script. - -This optimization saves a stat syscall on the main script file. In PHP5 this -optimization is automatic and doesn't need any special build flags. - -The second thing you are going to want to do to save another syscall is to -compile using the --with-apxs configure switch. This should work for both -Apache1 and Apache2. Point it directly at your apxs2 script for Apache2. -eg. --with-apxs=/usr/local/bin/apxs2 - -+---------------------+ -| QUICK INSTALL (DSO) | -+---------------------+ - -These instructions assume your PHP installation is located in /usr/local/php and you -want Apache optimizations (--with-apxs). - -$ gunzip -c apc_x.y.tar.gz | tar xf - -$ cd apc_x.y -$ /usr/local/php/bin/phpize -$ ./configure --enable-apc --enable-apc-mmap --with-apxs --with-php-config=/usr/local/php/bin/php-config -$ make -$ make install - -You will probably need to run the final command (make install) as root. - -The above sequence of commands will install a .so file in your PHP -installation extension directory. The output of make install should display -that path to the screen. - -Next you must edit your php.ini file, which is normally located in -/usr/local/php/lib/php.ini, and add the following line: - - extension="apc.so" - -Replace "/path/to/php/extensions" with whatever path was displayed when you -ran make install above. - -Then restart your web server and consult the output of phpinfo(). If there is -an informational section for APC, the installation was successful. - -+------------------------+ -| QUICK INSTALL (Static) | -+------------------------+ - -APC will not successfully compile on all systems as a DSO. If you run into -problems using the DSO quick install, you can try to compile it statically -into PHP. (The DSO install is recommended, though.) - -These instructions assume the current directory is the root of the PHP source -tree, and that you have already configured PHP by running its bundled -configure script. - -$ cd ext -$ gunzip -c apc_x.y.tar.gz | tar xf - -$ cd .. -$ ./buildconf -$ ./config.nice -$ make -$ make install - -Once this is complete, simply restart your web server. You do not need to -modify your php.ini file to enable APC. - -+-----------------+ -| VERBOSE INSTALL | -+-----------------+ - -These instructions assume your PHP installation is located in /usr/local/php. - -1. Unpack your distribution file. - - You will have downloaded a file named something like apc_x.y.tar.gz. - Unzip this file with a command like - - gunzip apc_x.y.tar.gz - - Next you have to untar it with - - tar xvf apc_x.y.tar - - This will create an apc_x.y directory. cd into this new directory: - - cd apc_x.y - -2. Run phpize. - - phpize is a script that should have been installed with PHP, and is - normally located in /usr/local/php/bin assuming you installed PHP in - /usr/local/php. (If you do not have the phpize script, you must reinstall - PHP and be sure not to disable PEAR.) - - Run the phpize command: - - /usr/local/php/bin/phpize - - Its output should resemble this: - - autoheader: `config.h.in' is created - You should update your `aclocal.m4' by running aclocal. - Configuring for: - PHP Api Version: 20020918 - Zend Module Api No: 20020429 - Zend Extension Api No: 20021010 - - phpize should create a configure script in the current directory. If you - get errors instead, you might be missing some required development tools, - such as autoconf or libtool. You can try downloading the latest versions - of those tools and running phpize again. - -3. Run the configure script. - - phpize creates a configure script. The only option you need to specify is - the location of your php-config script: - - ./configure --enable-apc - - php-config should be located in the same directory as phpize. - - If you prefer to use mmap instead of the default IPC shared memory support, - add --enable-apc-mmap to your configure line. - - If you prefer to use sysv IPC semaphores over the safer fcntl() locks, add - --enable-sem to your configure line. If you don't have a problem - with your server segaulting, or any other unnatural accumulation of - semaphores on your system, the semaphore based locking is slightly faster. - -4. Compile and install the files. Simply type: make install - - (You may need to be root in order to install) - - If you encounter errors from libtool or gcc during this step, please - contact the project maintainer (dcowgill@php.net). - -5. Edit your php.ini - - make install should have printed a line resembling the following: - - Installing shared extensions: /path/to/extension/ - - Copy the path /path/to/extension/ and add the following line to your - php.ini file (normally located in /usr/local/php/lib/php.ini): - - extension="apc.so" - - If you don't have a php.ini file in that location, you can create it now. - -6. Restart the web server and test the installation. - - Restart your web server now (for apache, it's apachectl restart) and - create a small test PHP file in your document root. The file should - contain just the following line: - - - - Request that file in a web browser. If there is an entry for APC in the - list of installed modules, the installation was successful. - - If APC is not listed, consult your web server error log. If it contains an - error message saying that it can't load the APC extension, your system - might not be able to load shared libraries created with PHP's build - system. One alternative would be to compile APC statically into PHP. See - the Quick Install (Static) instructions above. - - You should consult your error log anyway to see if APC generated any - errors. On BSD-based platforms, it is typical for APC to be unable to - allocate the default-sized shared memory segment. See below for hints on - raising your system's shared memory limitations. - -+-----------------+ -| CONFIGURING APC | -+-----------------+ - -Although the default APC settings are fine for many installations, serious -users should consider tuning the following parameters: - - OPTION DESCRIPTION - ------------------ -------------------------------------------------- - apc.enabled This can be set to 0 to disable APC. This is - primarily useful when APC is statically compiled - into PHP, since there is no other way to disable - it (when compiled as a DSO, the zend_extension - line can just be commented-out). - (Default: 1) - - apc.shm_segments The number of shared memory segments to allocate - for the compiler cache. If APC is running out of - shared memory but you have already set - apc.shm_size as high as your system allows, you - can try raising this value. Setting this to a - value other than 1 has no effect in mmap mode - since mmap'ed shm segments don't have size limits. - (Default: 1) - - apc.shm_size The size of each shared memory segment in MB. - By default, some systems (including most BSD - variants) have very low limits on the size of a - shared memory segment. - (Default: 30) - - apc.optimization This option has been deprecated. - (Default: 0) - - apc.num_files_hint A "hint" about the number of distinct source files - that will be included or requested on your web - server. Set to zero or omit if you're not sure; - this setting is mainly useful for sites that have - many thousands of source files. - (Default: 1000) - - apc.user_entries_hint Just like num_files_hint, a "hint" about the number - of distinct user cache variables to store. - Set to zero or omit if you're not sure; - (Default: 4096) - - apc.ttl The number of seconds a cache entry is allowed to - idle in a slot in case this cache entry slot is - needed by another entry. Leaving this at zero - means that your cache could potentially fill up - with stale entries while newer entries won't be - cached. - (Default: 0) - - apc.user_ttl The number of seconds a user cache entry is allowed - to idle in a slot in case this cache entry slot is - needed by another entry. Leaving this at zero - means that your cache could potentially fill up - with stale entries while newer entries won't be - cached. - (Default: 0) - - - apc.gc_ttl The number of seconds that a cache entry may - remain on the garbage-collection list. This value - provides a failsafe in the event that a server - process dies while executing a cached source file; - if that source file is modified, the memory - allocated for the old version will not be - reclaimed until this TTL reached. Set to zero to - disable this feature. - (Default: 3600) - - apc.cache_by_default On by default, but can be set to off and used in - conjunction with positive apc.filters so that files - are only cached if matched by a positive filter. - (Default: On) - - apc.filters A comma-separated list of POSIX extended regular - expressions. If any pattern matches the source - filename, the file will not be cached. Note that - the filename used for matching is the one passed - to include/require, not the absolute path. If the - first character of the expression is a + then the - expression will be additive in the sense that any - files matched by the expression will be cached, and - if the first character is a - then anything matched - will not be cached. The - case is the default, so - it can be left off. - (Default: "") - - apc.mmap_file_mask If compiled with MMAP support by using --enable-mmap - this is the mktemp-style file_mask to pass to the - mmap module for determing whether your mmap'ed memory - region is going to be file-backed or shared memory - backed. For straight file-backed mmap, set it to - something like /tmp/apc.XXXXXX (exactly 6 X's). - To use POSIX-style shm_open/mmap put a ".shm" - somewhere in your mask. eg. "/apc.shm.XXXXXX" - You can also set it to "/dev/zero" to use your - kernel's /dev/zero interface to anonymous mmap'ed - memory. Leaving it undefined will force an - anonymous mmap. - (Default: "") - - apc.slam_defense ** DEPRECATED - Use apc.write_lock instead ** - On very busy servers whenever you start the server or - modify files you can create a race of many processes - all trying to cache the same file at the same time. - This option sets the percentage of processes that will - skip trying to cache an uncached file. Or think of it - as the probability of a single process to skip caching. - For example, setting this to 75 would mean that there is - a 75% chance that the process will not cache an uncached - file. So the higher the setting the greater the defense - against cache slams. Setting this to 0 disables this - feature. - (Default: 0) - - apc.file_update_protection - When you modify a file on a live web server you really - should do so in an atomic manner. That is, write to a - temporary file and rename (mv) the file into its permanent - position when it is ready. Many text editors, cp, tar and - other such programs don't do this. This means that there - is a chance that a file is accessed (and cached) while it - is still being written to. This file_update_protection - setting puts a delay on caching brand new files. The - default is 2 seconds which means that if the modification - timestamp (mtime) on a file shows that it is less than 2 - seconds old when it is accessed, it will not be cached. - The unfortunate person who accessed this half-written file - will still see weirdness, but at least it won't persist. - If you are certain you always atomically update your files - by using something like rsync which does this correctly, you - can turn this protection off by setting it to 0. If you - have a system that is flooded with io causing some update - procedure to take longer than 2 seconds, you may want to - increase this a bit. - (Default: 2) - - apc.enable_cli Mostly for testing and debugging. Setting this enables APC - for the CLI version of PHP. Normally you wouldn't want to - create, populate and tear down the APC cache on every CLI - request, but for various test scenarios it is handy to be - able to enable APC for the CLI version of APC easily. - (Default: 0) - - apc.max_file_size Prevents large files from being cached. - (Default: 1M) - - apc.stat Whether to stat the main script file and the fullpath - includes. If you turn this off you will need to restart - your server in order to update scripts. - (Default: 1) - - apc.write_lock On busy servers when you first start up the server, or when - many files are modified, you can end up with all your processes - trying to compile and cache the same files. With write_lock - enabled, only one process at a time will try to compile an - uncached script while the other processes will run uncached - instead of sitting around waiting on a lock. - (Default: 1) - - apc.report_autofilter Logs any scripts that were automatically excluded from being - cached due to early/late binding issues. - (Default: 0) - - apc.rfc1867 RFC1867 File Upload Progress hook handler is only available - if you compiled APC against PHP 5.2.0 or later. When enabled - any file uploads which includes a field called - APC_UPLOAD_PROGRESS before the file field in an upload form - will cause APC to automatically create an upload_ - user cache entry where is the value of the - APC_UPLOAD_PROGRESS form entry. - - Note that the file upload tracking is not threadsafe at this - point, so new uploads that happen while a previous one is - still going will disable the tracking for the previous. - (Default: 0) - - apc.rfc1867_prefix Key prefix to use for the user cache entry generated by - rfc1867 upload progress functionality. - (Default: "upload_") - - apc.rfc1867_name Specify the hidden form entry name that activates APC upload - progress and specifies the user cache key suffix. - (Default: "APC_UPLOAD_PROGRESS") - - apc.rfc1867_freq The frequency that updates should be made to the user cache - entry for upload progress. This can take the form of a - percentage of the total file size or a size in bytes - optionally suffixed with 'k', 'm', or 'g' for kilobytes, - megabytes, or gigabytes respectively (case insensitive). - A setting of 0 updates as often as possible, which may cause - slower uploads. - (Default: 0) - - apc.localcache ** REMOVED - apc.localcache.size ** REMOVED - - apc.include_once_override - Optimize include_once and require_once calls and avoid the - expensive system calls used. - (Default: 0) diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 25662b2..0000000 --- a/LICENSE +++ /dev/null @@ -1,68 +0,0 @@ --------------------------------------------------------------------- - The PHP License, version 3.01 -Copyright (c) 1999 - 2008 The PHP Group. All rights reserved. --------------------------------------------------------------------- - -Redistribution and use in source and binary forms, with or without -modification, is permitted provided that the following conditions -are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - 3. The name "PHP" must not be used to endorse or promote products - derived from this software without prior written permission. For - written permission, please contact group@php.net. - - 4. Products derived from this software may not be called "PHP", nor - may "PHP" appear in their name, without prior written permission - from group@php.net. You may indicate that your software works in - conjunction with PHP by saying "Foo for PHP" instead of calling - it "PHP Foo" or "phpfoo" - - 5. The PHP Group may publish revised and/or new versions of the - license from time to time. Each version will be given a - distinguishing version number. - Once covered code has been published under a particular version - of the license, you may always continue to use it under the terms - of that version. You may also choose to use such covered code - under the terms of any subsequent version of the license - published by the PHP Group. No one other than the PHP Group has - the right to modify the terms applicable to covered code created - under this License. - - 6. Redistributions of any form whatsoever must retain the following - acknowledgment: - "This product includes PHP software, freely available from - ". - -THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND -ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP -DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - --------------------------------------------------------------------- - -This software consists of voluntary contributions made by many -individuals on behalf of the PHP Group. - -The PHP Group can be contacted via Email at group@php.net. - -For more information on the PHP Group and the PHP project, -please see . - -PHP includes the Zend Engine, freely available at -. diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 59e686b..0000000 --- a/NOTICE +++ /dev/null @@ -1,43 +0,0 @@ -This is the NOTICE file that holds acknowledgements and stuff. - -The Alternative PHP Cache (APC) is a free and open opcode cache for PHP. -This extension is being released under the PHP License for complete compliance -with PHP and to encourage wide-spread use. It is our intention that this -project be kept open source and that all commercial spin-offs contribute their -modifications back into the public source-tree. - -Creators: - Daniel Cowgill - George Schlossnagle - -PHP5 support and major features by: - Arun C. Murthy - Gopal Vijayaraghavan - Rasmus Lerdorf - -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. - -We would like to thank Community Connect Inc. and Yahoo! Inc. for supporting -this project and providing a challenging and stimulating environment in -which exciting projects can happen. - -Contributors: - Mike Bretz bug fixes, GUI, and lots of work - Ricardo Galli changed read-write locks to prefer readers - Yann Grossel bug fixes - Thies Arntzen bug fixes - Sara Golemon optimizer work - -Special Thanks: - Florian Baumert help debugging phplib problems - Thomas Duffey help debugging inheritance issues - Vibol Hou help debugging phplib problems - Angel Li diffs for ANSI comment compliance - Christian Rishøj help debugging phplib problems - Sascha Schumann memory error bug fix diff --git a/TECHNOTES.txt b/TECHNOTES.txt deleted file mode 100644 index 66d0fb7..0000000 --- a/TECHNOTES.txt +++ /dev/null @@ -1,361 +0,0 @@ -APC Quick-Start Braindump - -This is a rapidly written braindump of how APC currently works in the -form of a quick-start guide to start hacking on APC. - -1. Install and use APC a bit so you know what it does from the end-user's - perspective. - user-space functions are all explained here: - -2. Grab the current APC code from CVS: - - cvs -d:pserver:cvsread@cvs.php.net:/repository login - Password: phpfi - cvs -d:pserver:cvsread@cvs.php.net:/repository co pecl/apc - - apc/php_apc.c has most of the code for the user-visible stuff. It is - also a regular PHP extension in the sense that there are MINIT, MINFO, - MSHUTDOWN, RSHUTDOWN, etc. functions. - -3. Build it. - - cd pecl/apc - phpize - ./configure --enable-apc --enable-mmap - make - cp modules/apc.so /usr/local/lib/php - apachectl restart - -4. Debugging Hints - - apachectl stop - gdb /usr/bin/httpd - break ?? - run -X - - Grab the .gdbinit from the PHP source tree and have a look at the macros. - -5. Look through apc/apc_sma.c - It is a pretty standard memory allocator. - - apc_sma_malloc, apc_sma_realloc, apc_sma_strdup and apc_sma_free behave to the - caller just like malloc, realloc, strdup and free - - On server startup the MINIT hook in php_apc.c calls apc_module_init() in - apc_main.c which in turn calls apc_sma_init(). apc_sma_init calls into - apc_mmap.c to mmap the specified sized segment (I tend to just use a single - segment). apc_mmap.c should be self-explanatory. It mmaps a temp file and - then unlinks that file right after the mmap to provide automatic shared memory - cleanup in case the process dies. - - Once the region has been initialized we stick a header_t at the beginning - of the region. It contains the total size in header->segsize and the number - of bytes available in header->avail. - - After the header comes a bit of a hack. A zero-sized block is inserted just - to make things easier later on. And then a huge block that is basically - the size of the entire segment minus the two (for the 0-sized block, and this one) - block headers. - - The code for this is: - - header = (header_t*) shmaddr; - header->segsize = sma_segsize; - header->avail = sma_segsize - sizeof(header_t) - sizeof(block_t) - alignword(sizeof(int)); - memset(&header->lock,0,sizeof(header->lock)); - sma_lock = &header->lock; - block = BLOCKAT(sizeof(header_t)); - block->size = 0; - block->next = sizeof(header_t) + sizeof(block_t); - block = BLOCKAT(block->next); - block->size = header->avail; - block->next = 0; - - So the shared memory looks like this: - - +--------+-------+---------------------------------+ - | header | block | block | - +--------+-------+---------------------------------+ - - sma_shmaddrs[0] gives you the address of header - - The blocks are just a simple offset-based linked list (so no pointers): - - typedef struct block_t block_t; - struct block_t { - size_t size; /* size of this block */ - size_t next; /* offset in segment of next free block */ - size_t canary; /* canary to check for memory overwrites */ -#ifdef __APC_SMA_DEBUG__ - int id; /* identifier for the memory block */ -#endif - }; - - The BLOCKAT macro turns an offset into an actual address for you: - - #define BLOCKAT(offset) ((block_t*)((char *)shmaddr + offset)) - - where shmaddr = sma_shaddrs[0] - - And the OFFSET macro goes the other way: - - #define OFFSET(block) ((int)(((char*)block) - (char*)shmaddr)) - - Allocating a block with a call to apc_sma_allocate() walks through the - linked list of blocks until it finds one that is >= to the requested size. - The first call to apc_sma_allocate() will hit the second block. We then - chop up that block so it looks like this: - - +--------+-------+-------+-------------------------+ - | header | block | block | block | - +--------+-------+-------+-------------------------+ - - Then we unlink that block from the linked list so it won't show up - as an available block on the next allocate. So we actually have: - - +--------+-------+ +-------------------------+ - | header | block |------>| block | - +--------+-------+ +-------------------------+ - - And header->avail along with block->size of the remaining large - block are updated accordingly. The arrow there representing the - link which now points to a block with an offset further along in - the segment. - - When the block is freed using apc_sma_deallocate() the steps are - basically just reversed. The block is put back and then the deallocate - code looks at the block before and after to see if the block immediately - before and after are free and if so the blocks are combined. So you never - have 2 free blocks next to each other, apart from at the front with that - 0-sized dummy block. This mostly prevents fragmentation. I have been - toying with the idea of always allocating block at 2^n boundaries to make - it more likely that they will be re-used to cut down on fragmentation further. - That's what the POWER_OF_TWO_BLOCKSIZE you see in apc_sma.c is all about. - - Of course, anytime we fiddle with our shared memory segment we lock using - the locking macros, LOCK() and UNLOCK(). - - That should mostly take care of the low-level shared memory handling. - -6. Next up is apc_main.c and apc_cache.c which implement the meat of the - cache logic. - - The apc_main.c file mostly calls functions in apc_sma.c to allocate memory - and apc_cache.c for actual cache manipulation. - - After the shared memory segment is created and the caches are initialized, - apc_module_init() installs the my_compile_file() function overriding Zend's - version. I'll talk about my_compile_file() and the rest of apc_compile.c - in the next section. For now I will stick with apc_main.c and apc_cache.c - and talk about the actual caches. A cache consists of a block of shared - memory returned by apc_sma_allocate() via apc_sma_malloc(). You will - notice references to apc_emalloc(). apc_emalloc() is just a thin wrapper - around PHP's own emalloc() function which allocates per-process memory from - PHP's pool-based memory allocator. Don't confuse apc_emalloc() and - apc_sma_malloc() as the first is per-process and the second is shared memory. - - The cache is stored in/described by this struct allocated locally using - emalloc(): - - struct apc_cache_t { - void* shmaddr; /* process (local) address of shared cache */ - header_t* header; /* cache header (stored in SHM) */ - slot_t** slots; /* array of cache slots (stored in SHM) */ - int num_slots; /* number of slots in cache */ - int gc_ttl; /* maximum time on GC list for a slot */ - int ttl; /* if slot is needed and entry's access time is older than this ttl, remove it */ - }; - - Whenever you see functions that take a 'cache' argument, this is what they - take. And apc_cache_create() returns a pointer to this populated struct. - - At the beginning of the cache we have a header. Remember, we are down a level now - from the sma stuff. The sma stuff is the low-level shared-memory allocator which - has its own header which is completely separate and invisible to apc_cache.c. - As far as apc_cache.c is concerned the block of memory it is working with could - have come from a call to malloc(). - - The header looks like this: - - typedef struct header_t header_t; - struct header_t { - int num_hits; /* total successful hits in cache */ - int num_misses; /* total unsuccessful hits in cache */ - slot_t* deleted_list; /* linked list of to-be-deleted slots */ - }; - - Since this is at the start of the shared memory segment, these values are accessible - across all the yapache processes and hence access to them has to be locked. - - After the header we have an array of slots. The number of slots is user-defined - through the apc.num_slots ini hint. Each slot is described by: - - typedef struct slot_t slot_t; - struct slot_t { - apc_cache_key_t key; /* slot key */ - apc_cache_entry_t* value; /* slot value */ - slot_t* next; /* next slot in linked list */ - int num_hits; /* number of hits to this bucket */ - time_t creation_time; /* time slot was initialized */ - time_t deletion_time; /* time slot was removed from cache */ - time_t access_time; /* time slot was last accessed */ - }; - - The slot_t *next there is a linked list to other slots that happened to hash to the - same array position. - - apc_cache_insert() shows what happens on a new cache insert. - - slot = &cache->slots[hash(key) % cache->num_slots]; - - cache->slots is our array of slots in the segment. hash() is simply: - - static unsigned int hash(apc_cache_key_t key) - { - return key.data.file.device + key.data.file.inode; - } - - That is, we use the file's device and inode to uniquely identify it. Initially - we had used the file's full path, but getting that requires a realpath() call which - is amazingly expensive since it has to stat each component of the path to resolve - symlinks and get rid of relative path components. By using the device+inode we - can uniquely identify a file with a single stat. - - So, on an insert we find the array position in the slots array by hasing the device+inode. - If there are currently no other slots there, we just create the slot and stick it into - the array: - - *slot = make_slot(key, value, *slot, t) - - If there are other slots already at this position we walk the link list to get to - the end. Here is the loop: - - while (*slot) { - if (key_equals((*slot)->key.data.file, key.data.file)) { - /* If existing slot for the same device+inode is different, remove it and insert the new version */ - if ((*slot)->key.mtime != key.mtime) { - remove_slot(cache, slot); - break; - } - UNLOCK(cache); - return 0; - } else if(cache->ttl && (*slot)->access_time < (t - cache->ttl)) { - remove_slot(cache, slot); - continue; - } - slot = &(*slot)->next; - } - - That first key_equals() check sees if we have an exact match meaning the file - is already in the cache. Since we try to find the file in the cache before doing - an insert, this will generally only happen if another process managed to beat us - to inserting it. If we have a newer version of the file at this point we remove - it an insert the new version. If our version is not newer we just return without - doing anything. - - While walking the linked list we also check to see if the cache has a TTL defined. - If while walking the linked list we see a slot that has expired, we remove it - since we are right there looking at it. This is the only place we remove stale - entries unless the shared memory segment fills up and we force a full expunge via - apc_cache_expunge(). apc_cache_expunge() walks the entire slots array and walks - down every linked list removing stale slots to free up room. This is obviously - slow and thus only happens when we have run out of room. - - apc_cache_find() simply hashes and returns the entry if it is there. If it is there - but older than the mtime in the entry we are looking for, we delete the one that is - there and return indicating we didn't find it. - - Next we need to understand what an actual cache entry looks like. Have a look at - apc_cache.h for the structs. I sort of glossed over the key part earlier saying - that we just used the device+inode to find a hash slot. It is actually a bit more - complex than that because we have two kinds of caches. We have the standard file - cache containing opcode arrays, but we also have a user-controlled cache that the - user can insert whatever they want into via apc_store(). For the user cache we - obviously don't have a device+inode. The actual identifier is provided by the user - as a char *. So the key is actually a union that looks like this: - - typedef union _apc_cache_key_data_t { - struct { - int device; /* the filesystem device */ - int inode; /* the filesystem inode */ - } file; - struct { - char *identifier; - } user; - } apc_cache_key_data_t; - - struct apc_cache_key_t { - apc_cache_key_data_t data; - int mtime; /* the mtime of this cached entry */ - }; - - And we have two sets of functions to do inserts and finds. apc_cache_user_find() - and apc_cache_user_insert() operate on the user cache. - - Ok, on to the actual cache entry. Again, because we have two kinds of caches, we - also have the corresponding two kinds of cache entries described by this union: - - typedef union _apc_cache_entry_value_t { - struct { - char *filename; /* absolute path to source file */ - zend_op_array* op_array; /* op_array allocated in shared memory */ - apc_function_t* functions; /* array of apc_function_t's */ - apc_class_t* classes; /* array of apc_class_t's */ - } file; - struct { - char *info; - zval *val; - unsigned int ttl; - } user; - } apc_cache_entry_value_t; - - And then the actual cache entry: - - struct apc_cache_entry_t { - apc_cache_entry_value_t data; - unsigned char type; - int ref_count; - }; - - The user entry is pretty simple and not all that important for now. I will - concentrate on the file entries since that is what holds the actual compiled - opcode arrays along with the functions and classes required by the executor. - - apc_cache_make_file_entry() in apc_cache.c shows how an entry is constructed. - The main thing to understand here is that we need more than just the opcode - array, we also need the functions and classes created by the compiler when it - created the opcode array. As far as the executor is concerned, it doesn't know - that it isn't operating in normal mode being called right after the parse/compile - phase, so we need to recreate everything so it looks exactly like it would at - that point. - -7. my_compile_file() and apc_compile.c - - my_compile_file() in apc_main.c controls where we get the opcodes from. If - the user-specified filters exclude the file from being cached, then we just - call the original compile function and return. Otherwise we fetch the request - time from Apache to avoid an extra syscall, create the key so we can look up - the file in the cache. If we find it we stick it on a local stack which we - use at cleanup time to make sure we return everything back to normal after a - request and call cached_compile() which installs the functions and classes - associated with the op_array in this entry and then copy the op_array down - into our memory space for execution. - - If we didn't find the file in the cache, we need to compile it and insert it. - To compile it we simply call the original compile function: - - op_array = old_compile_file(h, type TSRMLS_CC); - - To do the insert we need to copy the functions, classes and the opcode array - the compile phase created into shared memory. This all happens in apc_compile.c - in the apc_copy_op_array(), apc_copy_new_functions() and apc_copy_new_classes() - functions. Then we make the file entry and do the insert. Both of these - operations were described in the previous section. - -8. The Optimizer - - The optimizer has been deprecated. - -If you made it to the end of this, you should have a pretty good idea of where things are in -the code. I skimmed over a lot of things, so plan on spending some time reading through the code. - diff --git a/TODO b/TODO deleted file mode 100644 index 7bf1b54..0000000 --- a/TODO +++ /dev/null @@ -1,30 +0,0 @@ -Known Bugs - -1. Gallery2 doesn't work with PHP5+APC. There is something wrong - with the way methods are restored in some edge case I haven't - been able to figure out yet. - To reproduce install gallery2 and click down to an individual photo. - -2. apc_store() probably needs some checks to skip trying to store - internal classes. Something along the lines of: - - if(Z_TYPE_P(val) == IS_OBJECT) { - zend_class_entry *ce = Z_OBJCE_P(val); - if(ce->type == ZEND_INTERNAL_CLASS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot cache internal objects"); - RETURN_FALSE; - } - } - - in the apc_store() function in php_apc.c but I am wondering if it needs to do more - than that. - -Enhancements - -1. Some faster platform-specific locking mechanisms wouldd be nice. futex support - for the 2.6 Linux kernels, and/or x86-specific spinlock support. - -2. The optimizer needs a lot of work. - -3. Assert() elimination in the optimizer when some debug flag somewhere isn't set. - diff --git a/apc.c b/apc.c deleted file mode 100644 index 6dd668d..0000000 --- a/apc.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | George Schlossnagle | - | Rasmus Lerdorf | - | Arun C. Murthy | - | Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - 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.c,v 3.18.2.3 2008/05/13 15:48:48 gopalv Exp $ */ - -#include "apc.h" -#include /* for POSIX regular expressions */ -#include "php.h" - -#define NELEMS(a) (sizeof(a)/sizeof((a)[0])) - -/* {{{ memory allocation wrappers */ - -void* apc_emalloc(size_t n) -{ - void* p = malloc(n); - if (p == NULL) { - apc_eprint("apc_emalloc: malloc failed to allocate %u bytes:", n); - } - return p; -} - -void* apc_erealloc(void* p, size_t n) -{ - p = realloc(p, n); - if (p == NULL) { - apc_eprint("apc_erealloc: realloc failed to allocate %u bytes:", n); - } - return p; -} - -void apc_efree(void* p) -{ - if (p == NULL) { - apc_eprint("apc_efree: attempt to free null pointer"); - } - free(p); -} - -char* apc_estrdup(const char* s) -{ - int len; - char* dup; - - if (s == NULL) { - return NULL; - } - len = strlen(s); - dup = (char*) malloc(len+1); - if (dup == NULL) { - apc_eprint("apc_estrdup: malloc failed to allocate %u bytes:", len+1); - } - memcpy(dup, s, len); - dup[len] = '\0'; - return dup; -} - -void* apc_xstrdup(const char* s, apc_malloc_t f) -{ - return s != NULL ? apc_xmemcpy(s, strlen(s)+1, f) : NULL; -} - -void* apc_xmemcpy(const void* p, size_t n, apc_malloc_t f) -{ - void* q; - - if (p != NULL && (q = f(n)) != NULL) { - memcpy(q, p, n); - return q; - } - return NULL; -} - -/* }}} */ - -/* {{{ console display functions */ - -static void my_log(int level, const char* fmt, va_list args) -{ - static const char* level_strings[] = { - "apc-debug", - "apc-notice", - "apc-warning", - "apc-error" - }; - static const int num_levels = NELEMS(level_strings); - - time_t now; - char* buf; /* for ctime */ - - fflush(stdout); - - if (level < 0) - level = 0; - else if (level >= num_levels) - level = num_levels-1; - - now = time(0); - buf = ctime(&now); /* TODO: replace with reentrant impl */ - buf[24] = '\0'; - - fprintf(stderr, "[%s] [%s] ", buf, level_strings[level]); - vfprintf(stderr, fmt, args); - - if (fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':') { - fprintf(stderr, " %s", strerror(errno)); - } - fprintf(stderr, "\n"); - - if (level == APC_ERROR) { - exit(2); - } -} - -void apc_log(int level, const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - my_log(level, fmt, args); - va_end(args); -} - -void apc_eprint(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - my_log(APC_ERROR, fmt, args); - va_end(args); -} - -void apc_wprint(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - my_log(APC_WARNING, fmt, args); - va_end(args); -} - -void apc_nprint(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - my_log(APC_NOTICE, fmt, args); - va_end(args); -} - -void apc_dprint(const char* fmt, ...) -{ -#ifdef APC_DEBUG - va_list args; - va_start(args, fmt); - my_log(APC_DBG, fmt, args); - va_end(args); -#endif -} - -/* }}} */ - -/* {{{ string and text manipulation */ - -char* apc_append(const char* s, const char* t) -{ - int slen; - int tlen; - char* p; - - slen = strlen(s); - tlen = strlen(t); - - p = (char*) apc_emalloc((slen + tlen + 1) * sizeof(char)); - memcpy(p, s, slen); - memcpy(p + slen, t, tlen + 1); - - return p; -} - -char* apc_substr(const char* s, int start, int length) -{ - char* substr; - int src_len = strlen(s); - - /* bring start into range */ - if (start < 0) { - start = 0; - } - else if (start >= src_len) { - start = src_len - 1; - } - - /* bring length into range */ - if (length < 0 || src_len - start < length) { - length = src_len - start; - } - - /* create the substring */ - substr = apc_xmemcpy(s + start, length + 1, apc_emalloc); - substr[length] = '\0'; - return substr; -} - -char** apc_tokenize(const char* s, char delim) -{ - char** tokens; /* array of tokens, NULL terminated */ - int size; /* size of tokens array */ - int n; /* index of next token in tokens array */ - int cur; /* current position in input string */ - int end; /* final legal position in input string */ - int next; /* position of next delimiter in input */ - - if (!s) { - return NULL; - } - - size = 2; - n = 0; - cur = 0; - end = strlen(s) - 1; - - tokens = (char**) apc_emalloc(size * sizeof(char*)); - tokens[n] = NULL; - - while (cur <= end) { - /* search for the next delimiter */ - char* p = strchr(s + cur, delim); - next = p ? p-s : end+1; - - /* resize token array if necessary */ - if (n == size-1) { - size *= 2; - tokens = (char**) apc_erealloc(tokens, size * sizeof(char*)); - } - - /* save the current token */ - tokens[n] = apc_substr(s, cur, next-cur); - - tokens[++n] = NULL; - cur = next + 1; - } - - return tokens; -} - -/* }}} */ - -/* similar to php_stream_stat_path */ -#ifdef ZEND_ENGINE_2 -#define APC_URL_STAT(wrapper, filename, pstatbuf) \ - ((wrapper)->wops->url_stat((wrapper), (filename), PHP_STREAM_URL_STAT_QUIET, (pstatbuf), NULL TSRMLS_CC)) -#else -#define APC_URL_STAT(wrapper, filename, pstatbuf) \ - ((wrapper)->wops->url_stat((wrapper), (filename), (pstatbuf) TSRMLS_CC)) -#endif - -int apc_search_paths(const char* filename, const char* path, apc_fileinfo_t* fileinfo) -{ - char** paths; - char *exec_fname; - int exec_fname_length; - int found = 0; - int i; - php_stream_wrapper *wrapper = NULL; - char *path_for_open = NULL; - - TSRMLS_FETCH(); - - assert(filename && fileinfo); - - - wrapper = php_stream_locate_url_wrapper(filename, &path_for_open, 0 TSRMLS_CC); - - if(!wrapper || !wrapper->wops || !wrapper->wops->url_stat) { - return -1; - } - -#ifdef ZEND_ENGINE_2 - if(wrapper != &php_plain_files_wrapper) { - if(APC_URL_STAT(wrapper, path_for_open, &fileinfo->st_buf) == 0) { - strncpy(fileinfo->fullpath, path_for_open, MAXPATHLEN); - return 0; - } - return -1; /* cannot stat */ - } -#endif - - if (IS_ABSOLUTE_PATH(path_for_open, strlen(path_for_open)) && - APC_URL_STAT(wrapper, path_for_open, &fileinfo->st_buf) == 0) { - strncpy(fileinfo->fullpath, path_for_open, MAXPATHLEN); - return 0; - } - - paths = apc_tokenize(path, DEFAULT_DIR_SEPARATOR); - if (!paths) - return -1; - - /* for each directory in paths, look for filename inside */ - for (i = 0; paths[i]; i++) { - snprintf(fileinfo->fullpath, sizeof(fileinfo->fullpath), "%s%c%s", paths[i], DEFAULT_SLASH, path_for_open); - if (APC_URL_STAT(wrapper, fileinfo->fullpath, &fileinfo->st_buf) == 0) { - found = 1; - break; - } - } - - /* check in path of the calling scripts' current working directory */ - /* modified from main/streams/plain_wrapper.c */ - if(!found && zend_is_executing(TSRMLS_C)) { - exec_fname = zend_get_executed_filename(TSRMLS_C); - exec_fname_length = strlen(exec_fname); - while((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length])); - if((exec_fname && exec_fname[0] != '[') && exec_fname_length > 0) { - /* not: [no active file] or no path */ - memcpy(fileinfo->fullpath, exec_fname, exec_fname_length); - fileinfo->fullpath[exec_fname_length] = DEFAULT_SLASH; - strlcpy(fileinfo->fullpath +exec_fname_length +1, path_for_open,sizeof(fileinfo->fullpath)-exec_fname_length-1); - /* apc_wprint("filename: %s, exec_fname: %s, fileinfo->fullpath: %s", path_for_open, exec_fname, fileinfo->fullpath); */ - if (APC_URL_STAT(wrapper, fileinfo->fullpath, &fileinfo->st_buf) == 0) { - found = 1; - } - } - } - - /* free the value returned by apc_tokenize */ - for (i = 0; paths[i]; i++) { - apc_efree(paths[i]); - } - apc_efree(paths); - - return found ? 0 : -1; -} - -/* }}} */ - -/* {{{ regular expression wrapper functions */ - -typedef struct { - regex_t *reg; - unsigned char type; -} apc_regex; - -void* apc_regex_compile_array(char* patterns[]) -{ - apc_regex** regs; - int npat; - int i; - - if (!patterns) - return NULL; - - /* count the number of patterns in patterns */ - for (npat = 0; patterns[npat] != NULL; npat++) {} - - if (npat == 0) - return NULL; - - /* allocate the array of compiled expressions */ - regs = (apc_regex**) apc_emalloc(sizeof(apc_regex*) * (npat + 1)); - for (i = 0; i <= npat; i++) { - regs[i] = (apc_regex *) apc_emalloc(sizeof(apc_regex)); - regs[i]->reg = NULL; - regs[i]->type = APC_NEGATIVE_MATCH; - } - - /* compile the expressions */ - for (i = 0; i < npat; i++) { - char *pattern = patterns[i]; - if(pattern[0]=='+') { regs[i]->type = APC_POSITIVE_MATCH; pattern = patterns[i]+sizeof(char); } - else if(pattern[0]=='-') { regs[i]->type = APC_NEGATIVE_MATCH; pattern = patterns[i]+sizeof(char); } - - regs[i]->reg = (regex_t*) apc_emalloc(sizeof(regex_t)); - - if (regcomp(regs[i]->reg, pattern, REG_EXTENDED | REG_NOSUB) != 0) { - apc_wprint("apc_regex_compile_array: invalid expression '%s'", - pattern); - - apc_regex_destroy_array(regs); - - return NULL; - } - } - - return (void*) regs; -} - -void apc_regex_destroy_array(void* p) -{ - if (p != NULL) { - apc_regex** regs = (apc_regex**) p; - int i; - - for (i = 0; regs[i]->reg != NULL; i++) { - regfree(regs[i]->reg); - apc_efree(regs[i]->reg); - apc_efree(regs[i]); - } - apc_efree(regs); - } -} - -int apc_regex_match_array(void* p, const char* input) -{ - apc_regex** regs; - int i; - - if (!p) - return 0; - - regs = (apc_regex**) p; - for (i = 0; regs[i]->reg != NULL; i++) - if (regexec(regs[i]->reg, input, 0, NULL, 0) == 0) - return (int)(regs[i]->type); - - return 0; -} - -/* }}} */ - -/* {{{ crc32 implementation */ - -/* this table was generated by crc32gen() */ -static unsigned int crc32tab[] = { - /* 0 */ 0x00000000, 0x3b83984b, 0x77073096, 0x4c84a8dd, - /* 4 */ 0xee0e612c, 0xd58df967, 0x990951ba, 0xa28ac9f1, - /* 8 */ 0x076dc419, 0x3cee5c52, 0x706af48f, 0x4be96cc4, - /* 12 */ 0xe963a535, 0xd2e03d7e, 0x9e6495a3, 0xa5e70de8, - /* 16 */ 0x0edb8832, 0x35581079, 0x79dcb8a4, 0x425f20ef, - /* 20 */ 0xe0d5e91e, 0xdb567155, 0x97d2d988, 0xac5141c3, - /* 24 */ 0x09b64c2b, 0x3235d460, 0x7eb17cbd, 0x4532e4f6, - /* 28 */ 0xe7b82d07, 0xdc3bb54c, 0x90bf1d91, 0xab3c85da, - /* 32 */ 0x1db71064, 0x2634882f, 0x6ab020f2, 0x5133b8b9, - /* 36 */ 0xf3b97148, 0xc83ae903, 0x84be41de, 0xbf3dd995, - /* 40 */ 0x1adad47d, 0x21594c36, 0x6ddde4eb, 0x565e7ca0, - /* 44 */ 0xf4d4b551, 0xcf572d1a, 0x83d385c7, 0xb8501d8c, - /* 48 */ 0x136c9856, 0x28ef001d, 0x646ba8c0, 0x5fe8308b, - /* 52 */ 0xfd62f97a, 0xc6e16131, 0x8a65c9ec, 0xb1e651a7, - /* 56 */ 0x14015c4f, 0x2f82c404, 0x63066cd9, 0x5885f492, - /* 60 */ 0xfa0f3d63, 0xc18ca528, 0x8d080df5, 0xb68b95be, - /* 64 */ 0x3b6e20c8, 0x00edb883, 0x4c69105e, 0x77ea8815, - /* 68 */ 0xd56041e4, 0xeee3d9af, 0xa2677172, 0x99e4e939, - /* 72 */ 0x3c03e4d1, 0x07807c9a, 0x4b04d447, 0x70874c0c, - /* 76 */ 0xd20d85fd, 0xe98e1db6, 0xa50ab56b, 0x9e892d20, - /* 80 */ 0x35b5a8fa, 0x0e3630b1, 0x42b2986c, 0x79310027, - /* 84 */ 0xdbbbc9d6, 0xe038519d, 0xacbcf940, 0x973f610b, - /* 88 */ 0x32d86ce3, 0x095bf4a8, 0x45df5c75, 0x7e5cc43e, - /* 92 */ 0xdcd60dcf, 0xe7559584, 0xabd13d59, 0x9052a512, - /* 96 */ 0x26d930ac, 0x1d5aa8e7, 0x51de003a, 0x6a5d9871, - /* 100 */ 0xc8d75180, 0xf354c9cb, 0xbfd06116, 0x8453f95d, - /* 104 */ 0x21b4f4b5, 0x1a376cfe, 0x56b3c423, 0x6d305c68, - /* 108 */ 0xcfba9599, 0xf4390dd2, 0xb8bda50f, 0x833e3d44, - /* 112 */ 0x2802b89e, 0x138120d5, 0x5f058808, 0x64861043, - /* 116 */ 0xc60cd9b2, 0xfd8f41f9, 0xb10be924, 0x8a88716f, - /* 120 */ 0x2f6f7c87, 0x14ece4cc, 0x58684c11, 0x63ebd45a, - /* 124 */ 0xc1611dab, 0xfae285e0, 0xb6662d3d, 0x8de5b576, - /* 128 */ 0x76dc4190, 0x4d5fd9db, 0x01db7106, 0x3a58e94d, - /* 132 */ 0x98d220bc, 0xa351b8f7, 0xefd5102a, 0xd4568861, - /* 136 */ 0x71b18589, 0x4a321dc2, 0x06b6b51f, 0x3d352d54, - /* 140 */ 0x9fbfe4a5, 0xa43c7cee, 0xe8b8d433, 0xd33b4c78, - /* 144 */ 0x7807c9a2, 0x438451e9, 0x0f00f934, 0x3483617f, - /* 148 */ 0x9609a88e, 0xad8a30c5, 0xe10e9818, 0xda8d0053, - /* 152 */ 0x7f6a0dbb, 0x44e995f0, 0x086d3d2d, 0x33eea566, - /* 156 */ 0x91646c97, 0xaae7f4dc, 0xe6635c01, 0xdde0c44a, - /* 160 */ 0x6b6b51f4, 0x50e8c9bf, 0x1c6c6162, 0x27eff929, - /* 164 */ 0x856530d8, 0xbee6a893, 0xf262004e, 0xc9e19805, - /* 168 */ 0x6c0695ed, 0x57850da6, 0x1b01a57b, 0x20823d30, - /* 172 */ 0x8208f4c1, 0xb98b6c8a, 0xf50fc457, 0xce8c5c1c, - /* 176 */ 0x65b0d9c6, 0x5e33418d, 0x12b7e950, 0x2934711b, - /* 180 */ 0x8bbeb8ea, 0xb03d20a1, 0xfcb9887c, 0xc73a1037, - /* 184 */ 0x62dd1ddf, 0x595e8594, 0x15da2d49, 0x2e59b502, - /* 188 */ 0x8cd37cf3, 0xb750e4b8, 0xfbd44c65, 0xc057d42e, - /* 192 */ 0x4db26158, 0x7631f913, 0x3ab551ce, 0x0136c985, - /* 196 */ 0xa3bc0074, 0x983f983f, 0xd4bb30e2, 0xef38a8a9, - /* 200 */ 0x4adfa541, 0x715c3d0a, 0x3dd895d7, 0x065b0d9c, - /* 204 */ 0xa4d1c46d, 0x9f525c26, 0xd3d6f4fb, 0xe8556cb0, - /* 208 */ 0x4369e96a, 0x78ea7121, 0x346ed9fc, 0x0fed41b7, - /* 212 */ 0xad678846, 0x96e4100d, 0xda60b8d0, 0xe1e3209b, - /* 216 */ 0x44042d73, 0x7f87b538, 0x33031de5, 0x088085ae, - /* 220 */ 0xaa0a4c5f, 0x9189d414, 0xdd0d7cc9, 0xe68ee482, - /* 224 */ 0x5005713c, 0x6b86e977, 0x270241aa, 0x1c81d9e1, - /* 228 */ 0xbe0b1010, 0x8588885b, 0xc90c2086, 0xf28fb8cd, - /* 232 */ 0x5768b525, 0x6ceb2d6e, 0x206f85b3, 0x1bec1df8, - /* 236 */ 0xb966d409, 0x82e54c42, 0xce61e49f, 0xf5e27cd4, - /* 240 */ 0x5edef90e, 0x655d6145, 0x29d9c998, 0x125a51d3, - /* 244 */ 0xb0d09822, 0x8b530069, 0xc7d7a8b4, 0xfc5430ff, - /* 248 */ 0x59b33d17, 0x6230a55c, 0x2eb40d81, 0x153795ca, - /* 252 */ 0xb7bd5c3b, 0x8c3ec470, 0xc0ba6cad, 0xfb39f4e6, -}; - -unsigned int apc_crc32(const char* buf, int len) -{ - int i; - int k; - unsigned int crc; - - /* preconditioning */ - crc = 0xFFFFFFFF; - - for (i = 0; i < len; i++) { - k = (crc ^ buf[i]) & 0x000000FF; - crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[k]; - } - - /* postconditioning */ - return ~crc; -} - -/* crc32gen: generate the nth (0..255) crc32 table value */ -#if 0 -static unsigned long crc32gen(int n) -{ - int i; - unsigned long crc; - - crc = n; - for (i = 8; i >= 0; i--) { - if (crc & 1) { - crc = (crc >> 1) ^ 0xEDB88320; - } - else { - crc >>= 1; - } - } - return crc; -} -#endif - -/* }}} */ - -/* - * 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 - */ diff --git a/apc.dsp b/apc.dsp deleted file mode 100644 index d921b5f..0000000 --- a/apc.dsp +++ /dev/null @@ -1,207 +0,0 @@ -# Microsoft Developer Studio Project File - Name="apc" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=apc - Win32 Debug_TS -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "apc.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "apc.mak" CFG="apc - Win32 Debug_TS" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "apc - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "apc - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "apc - Win32 Debug_TS" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug_TS" -# PROP BASE Intermediate_Dir "Debug_TS" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug_TS" -# PROP Intermediate_Dir "Debug_TS" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "APC_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\php4" /I "..\..\..\php4\main" /I "..\..\..\php4\Zend" /I "..\..\..\php4\TSRM" /I "..\..\..\php4\win32" /I "..\..\..\php4\regex" /D "TSRM_LOCKS" /D HAVE_APC=1 /D "COMPILE_DL_APC" /D ZEND_DEBUG=1 /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "APC_EXPORTS" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 php4ts_debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Debug_TS/php_apc.dll" /pdbtype:sept /libpath:"..\..\..\php4\Debug_TS" - -!ELSEIF "$(CFG)" == "apc - Win32 Release_TS" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release_TS" -# PROP BASE Intermediate_Dir "Release_TS" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release_TS" -# PROP Intermediate_Dir "Release_TS" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "APC_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\php4" /I "..\..\..\php4\main" /I "..\..\..\php4\Zend" /I "..\..\..\php4\TSRM" /I "..\..\..\php4\win32" /I "..\..\..\php4\regex" /D "TSRM_LOCKS" /D HAVE_APC=1 /D "COMPILE_DL_APC" /D ZEND_DEBUG=0 /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "APC_EXPORTS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 php4ts.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../Release_TS/php_apc.dll" /libpath:"..\..\..\php4\Release_TS" /libpath:"..\..\..\php4\Release_TS_Inline" - -!ENDIF - -# Begin Target - -# Name "apc - Win32 Debug_TS" -# Name "apc - Win32 Release_TS" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\apc.c -# End Source File -# Begin Source File - -SOURCE=.\apc_cache.c -# End Source File -# Begin Source File - -SOURCE=.\apc_compile.c -# End Source File -# Begin Source File - -SOURCE=.\apc_debug.c -# End Source File -# Begin Source File - -SOURCE=.\apc_fcntl_win32.c -# End Source File -# Begin Source File - -SOURCE=.\apc_main.c -# End Source File -# Begin Source File - -SOURCE=.\apc_rfc1867.c -# End Source File -# Begin Source File - -SOURCE=.\apc_shm.c -# End Source File -# Begin Source File - -SOURCE=.\apc_sma.c -# End Source File -# Begin Source File - -SOURCE=.\apc_stack.c -# End Source File -# Begin Source File - -SOURCE=.\apc_zend.c -# End Source File -# Begin Source File - -SOURCE=.\php_apc.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\apc.h -# End Source File -# Begin Source File - -SOURCE=.\apc_cache.h -# End Source File -# Begin Source File - -SOURCE=.\apc_compile.h -# End Source File -# Begin Source File - -SOURCE=.\apc_debug.h -# End Source File -# Begin Source File - -SOURCE=.\apc_fcntl.h -# End Source File -# Begin Source File - -SOURCE=.\apc_globals.h -# End Source File -# Begin Source File - -SOURCE=.\apc_lock.h -# End Source File -# Begin Source File - -SOURCE=.\apc_main.h -# End Source File -# Begin Source File - -SOURCE=.\apc_php.h -# End Source File -# Begin Source File - -SOURCE=.\apc_shm.h -# End Source File -# Begin Source File - -SOURCE=.\apc_sma.h -# End Source File -# Begin Source File - -SOURCE=.\apc_stack.h -# End Source File -# Begin Source File - -SOURCE=.\apc_zend.h -# End Source File -# Begin Source File - -SOURCE=.\php_apc.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/apc.h b/apc.h deleted file mode 100644 index 92182ae..0000000 --- a/apc.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | George Schlossnagle | - | Rasmus Lerdorf | - | Arun C. Murthy | - | Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - 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,v 3.14.2.2 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_H -#define APC_H - -/* - * This module defines utilities and helper functions used elsewhere in APC. - */ - -/* Commonly needed C library headers. */ -#include -#include -#include -#include -#include -#include -#include - -/* UNIX headers (needed for struct stat) */ -#include -#include -#ifndef PHP_WIN32 -#include -#endif - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php.h" -#include "main/php_streams.h" - -/* log levels constants (see apc_log) */ -enum { APC_DBG, APC_NOTICE, APC_WARNING, APC_ERROR }; - -/* typedefs for extensible memory allocators */ -typedef void* (*apc_malloc_t)(size_t); -typedef void (*apc_free_t) (void*); - -/* wrappers for memory allocation routines */ -extern void* apc_emalloc(size_t n); -extern void* apc_erealloc(void* p, size_t n); -extern void apc_efree(void* p); -extern char* apc_estrdup(const char* s); -extern void* apc_xstrdup(const char* s, apc_malloc_t f); -extern void* apc_xmemcpy(const void* p, size_t n, apc_malloc_t f); - -/* console display functions */ -extern void apc_log(int level, const char* fmt, ...); -extern void apc_eprint(const char* fmt, ...); -extern void apc_wprint(const char* fmt, ...); -extern void apc_dprint(const char* fmt, ...); -extern void apc_nprint(const char* fmt, ...); - -/* string and text manipulation */ -extern char* apc_append(const char* s, const char* t); -extern char* apc_substr(const char* s, int start, int length); -extern char** apc_tokenize(const char* s, char delim); - -/* filesystem functions */ - -typedef struct apc_fileinfo_t -{ - char fullpath[MAXPATHLEN+1]; - php_stream_statbuf st_buf; -} apc_fileinfo_t; - -extern int apc_search_paths(const char* filename, const char* path, apc_fileinfo_t* fileinfo); - -/* regular expression wrapper functions */ -extern void* apc_regex_compile_array(char* patterns[]); -extern void apc_regex_destroy_array(void* p); -extern int apc_regex_match_array(void* p, const char* input); - -/* apc_crc32: returns the CRC-32 checksum of the first len bytes in buf */ -extern unsigned int apc_crc32(const char* buf, int len); - -#define APC_NEGATIVE_MATCH 1 -#define APC_POSITIVE_MATCH 2 - -#endif - -/* - * 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 - */ diff --git a/apc.php b/apc.php deleted file mode 100644 index dee11cd..0000000 --- a/apc.php +++ /dev/null @@ -1,1341 +0,0 @@ - | - | Rasmus Lerdorf | - | Ilia Alshanetsky | - +----------------------------------------------------------------------+ - - All other licensing and usage conditions are those of the PHP Group. - - */ - -$VERSION='$Id: apc.php,v 3.68.2.2 2008/05/11 18:57:00 rasmus Exp $'; - -////////// 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 - -////////// 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) : ''; -$time = time(); -$host = getenv('HOSTNAME'); -if($host) { $host = '('.$host.')'; } - -// operation constants -define('OB_HOST_STATS',1); -define('OB_SYS_CACHE',2); -define('OB_USER_CACHE',3); -define('OB_SYS_CACHE_DIR',4); -define('OB_VERSION_CHECK',9); - -// 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-1/_.-]*$~' // aggregation by dir level -); - -// default cache mode -$cache_mode='opcode'; - -// 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 << -

Rejected!

- Wrong Username or Password!
 
  - Continue... - -EOB; - exit; - - } else { - $AUTHENTICATED=1; - } - } -} - -// select cache mode -if ($AUTHENTICATED && $MYREQUEST['OB'] == OB_USER_CACHE) { - $cache_mode='user'; -} -// clear cache -if ($AUTHENTICATED && isset($MYREQUEST['CC']) && $MYREQUEST['CC']) { - apc_clear_cache($cache_mode); -} - -if ($AUTHENTICATED && !empty($MYREQUEST['DU'])) { - apc_delete($MYREQUEST['DU']); -} - -if(!function_exists('apc_cache_info') || !($cache=@apc_cache_info($cache_mode))) { - echo "No cache info available. APC does not appear to be running."; - exit; -} - -$cache_user = apc_cache_info('user', 1); -$mem=apc_sma_info(); -if(!$cache['num_hits']) { $cache['num_hits']=1; $time++; } // Avoid division by 0 errors on a cache clear - -// 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]; - 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['num_hits']+$cache['num_misses']; - $a=$cache['num_hits']; - - fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s)); - fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s)); - 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]; - 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['num_hits']+$cache['num_misses']; - $a=$cache['num_hits']; - - fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s)); - fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s)); - 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 "$name"; - -} - -// create menu entry -function menu_entry($ob,$title) { - global $MYREQUEST,$MY_SELF; - if ($MYREQUEST['OB']!=$ob) { - return "
  • $title
  • "; - } else if (empty($MYREQUEST['SH'])) { - return "
  • $title
  • "; - } else { - return "
  • $title
  • "; - } -} - -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 <<$s -EOB; - } else if ($AUTHENTICATED) { - print <<$s -EOB; - } -} - - -?> - - -APC INFO <?php echo $host ?> - - - -
    -

    - -
    Opcode Cache
    -

    - -
    -
    - -
  • Refresh Data
  • -EOB; -echo - menu_entry(1,'View Host Stats'), - menu_entry(2,'System Cache Entries'); -if ($AUTHENTICATED) { - echo menu_entry(4,'Per-Directory Entries'); -} -echo - menu_entry(3,'User Cache Entries'), - menu_entry(9,'Version Check'); - -if ($AUTHENTICATED) { - echo <<Clear $cache_mode Cache -EOB; -} -echo << -EOB; - - -// CONTENT -echo << -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 = sprintf("%.2f",($cache['num_hits']+$cache['num_misses'])/($time-$cache['start_time'])); - $hit_rate = sprintf("%.2f",($cache['num_hits'])/($time-$cache['start_time'])); - $miss_rate = sprintf("%.2f",($cache['num_misses'])/($time-$cache['start_time'])); - $insert_rate = sprintf("%.2f",($cache['num_inserts'])/($time-$cache['start_time'])); - $req_rate_user = sprintf("%.2f",($cache_user['num_hits']+$cache_user['num_misses'])/($time-$cache_user['start_time'])); - $hit_rate_user = sprintf("%.2f",($cache_user['num_hits'])/($time-$cache_user['start_time'])); - $miss_rate_user = sprintf("%.2f",($cache_user['num_misses'])/($time-$cache_user['start_time'])); - $insert_rate_user = sprintf("%.2f",($cache_user['num_inserts'])/($time-$cache_user['start_time'])); - $apcversion = phpversion('apc'); - $phpversion = phpversion(); - $number_files = $cache['num_entries']; - $size_files = bsize($cache['mem_size']); - $number_vars = $cache_user['num_entries']; - $size_vars = bsize($cache_user['mem_size']); - $i=0; - echo <<< EOB -

    General Cache Information

    - - - -EOB; - - if(!empty($_SERVER['SERVER_NAME'])) - echo "\n"; - if(!empty($_SERVER['SERVER_SOFTWARE'])) - echo "\n"; - - echo << -EOB; - echo ''; - echo ''; - echo ''; - echo <<
    APC Version$apcversion
    PHP Version$phpversion
    APC Host{$_SERVER['SERVER_NAME']} $host
    Server Software{$_SERVER['SERVER_SOFTWARE']}
    Shared Memory{$mem['num_seg']} Segment(s) with $seg_size -
    ({$cache['memory_type']} memory, {$cache['locking_type']} locking) -
    Start Time',date(DATE_FORMAT,$cache['start_time']),'
    Uptime',duration($cache['start_time']),'
    File Upload Support',$cache['file_upload_progress'],'
    -
    - -

    File Cache Information

    - - - - - - - - - -
    Cached Files$number_files ($size_files)
    Hits{$cache['num_hits']}
    Misses{$cache['num_misses']}
    Request Rate (hits, misses)$req_rate cache requests/second
    Hit Rate$hit_rate cache requests/second
    Miss Rate$miss_rate cache requests/second
    Insert Rate$insert_rate cache requests/second
    Cache full count{$cache['expunges']}
    -
    - -

    User Cache Information

    - - - - - - - - - - -
    Cached Variables$number_vars ($size_vars)
    Hits{$cache_user['num_hits']}
    Misses{$cache_user['num_misses']}
    Request Rate (hits, misses)$req_rate_user cache requests/second
    Hit Rate$hit_rate_user cache requests/second
    Miss Rate$miss_rate_user cache requests/second
    Insert Rate$insert_rate_user cache requests/second
    Cache full count{$cache_user['expunges']}
    -
    - -

    Runtime Settings

    -EOB; - - $j = 0; - foreach (ini_get_all('apc') as $k => $v) { - echo "\n"; - $j = 1 - $j; - } - - if($mem['num_seg']>1 || $mem['num_seg']==1 && count($mem['block_lists'][0])>1) - $mem_note = "Memory Usage
    (multiple slices indicate fragments)"; - else - $mem_note = "Memory Usage"; - - echo <<< EOB -
    ",$k,"",str_replace(',',',
    ',$v['local_value']),"
    -
    - -

    Host Status Diagrams

    - -EOB; - $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10); - echo << - - - -EOB; - - echo - graphics_avail() ? - ''. - "". - "\n" - : "", - '', - '\n", - '\n", - '', - '', - '\n", - '\n"; - echo <<< EOB - -
    $mem_noteHits & Misses
    \"\"\"\"
     Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size)," Hits: ',$cache['num_hits'].sprintf(" (%.1f%%)",$cache['num_hits']*100/($cache['num_hits']+$cache['num_misses'])),"
     Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size)," Misses: ',$cache['num_misses'].sprintf(" (%.1f%%)",$cache['num_misses']*100/($cache['num_hits']+$cache['num_misses'])),"
    - -
    -

    Detailed Memory Usage and Fragmentation

    - - - - -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 "\n"; - } - } - echo <<

    -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; - } - echo <<Fragmentation: $frag -
    $range$v
    -
    -EOB; - - break; - - -// ----------------------------------------------- -// User Cache Entries -// ----------------------------------------------- -case OB_USER_CACHE: - if (!$AUTHENTICATED) { - echo '
    You need to login to see the user values here!
     
    '; - put_login_link("Login now!"); - echo '
    '; - break; - } - $fieldname='info'; - $fieldheading='User Entry Label'; - $fieldkey='info'; - -// ----------------------------------------------- -// System Cache Entries -// ----------------------------------------------- -case OB_SYS_CACHE: - if (!isset($fieldname)) - { - $fieldname='filename'; - $fieldheading='Script Filename'; - if(ini_get("apc.stat")) $fieldkey='inode'; - else $fieldkey='filename'; - } - if (!empty($MYREQUEST['SH'])) - { - echo <<< EOB -
    - -EOB; - - $m=0; - foreach($scope_list as $j => $list) { - foreach($cache[$list] as $i => $entry) { - if (md5($entry[$fieldkey])!=$MYREQUEST['SH']) continue; - foreach($entry as $k => $value) { - if (!$AUTHENTICATED) { - // hide all path entries if not logged in - $value=preg_replace('/^.*(\\/|\\\\)/','<hidden>/',$value); - } - - if ($k == "num_hits") { - $value=sprintf("%s (%.2f%%)",$value,$value*100/$cache['num_hits']); - } - if ($k == 'deletion_time') { - if(!$entry['deletion_time']) $value = "None"; - } - echo - "", - "", - "", - ""; - $m=1-$m; - } - if($fieldkey=='info') { - echo "\n"; - } - break; - } - } - - echo <<
    AttributeValue
    ",ucwords(preg_replace("/_/"," ",$k)),"",(preg_match("/time/",$k) && $value!='None') ? date(DATE_FORMAT,$value) : $value,"
    Stored Value
    ";
    -					$output = var_export(apc_fetch($entry[$fieldkey]),true);
    -					echo htmlspecialchars($output);
    -					echo "
    -
    -EOB; - break; - } - - $cols=6; - echo <<
    Scope: - - ", - ", Sorting:', - '', - '', - '  Search: ', - ' ', - '
    '; - - 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 '
    Error: enter a valid regular expression as a search query.
    '; - break; - } - } - - echo - '
    ', - '', - '', - '', - '', - '', - '', - ''; - - if($fieldname=='info') { - $cols+=2; - echo ''; - } - echo ''; - - // 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['access_time']); break; - case 'H': $k=sprintf('%015d-',$entry['num_hits']); break; - case 'Z': $k=sprintf('%015d-',$entry['mem_size']); break; - case 'M': $k=sprintf('%015d-',$entry['mtime']); break; - case 'C': $k=sprintf('%015d-',$entry['creation_time']); break; - case 'T': $k=sprintf('%015d-',$entry['ttl']); break; - case 'D': $k=sprintf('%015d-',$entry['deletion_time']); break; - case 'S': $k=''; 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) { - echo - '', - "', - '', - '', - '', - '', - ''; - - if($fieldname=='info') { - if($entry['ttl']) - echo ''; - else - echo ''; - } - if ($entry['deletion_time']) { - - echo ''; - } else if ($MYREQUEST['OB'] == OB_USER_CACHE) { - - echo ''; - } else { - echo ''; - } - echo ''; - $i++; - if ($i == $MYREQUEST['COUNT']) - break; - } - } - - } else { - echo ''; - } - echo <<< EOB -
    ',sortheader('S',$fieldheading, "&OB=".$MYREQUEST['OB']),'',sortheader('H','Hits', "&OB=".$MYREQUEST['OB']),'',sortheader('Z','Size', "&OB=".$MYREQUEST['OB']),'',sortheader('A','Last accessed',"&OB=".$MYREQUEST['OB']),'',sortheader('M','Last modified',"&OB=".$MYREQUEST['OB']),'',sortheader('C','Created at', "&OB=".$MYREQUEST['OB']),'',sortheader('T','Timeout',"&OB=".$MYREQUEST['OB']),'',sortheader('D','Deleted at',"&OB=".$MYREQUEST['OB']),'
    ",$entry[$fieldname],'',$entry['num_hits'],'',$entry['mem_size'],'',date(DATE_FORMAT,$entry['access_time']),'',date(DATE_FORMAT,$entry['mtime']),'',date(DATE_FORMAT,$entry['creation_time']),''.$entry['ttl'].' secondsNone', date(DATE_FORMAT,$entry['deletion_time']), ''; - echo '[Delete Now]'; - echo '  
    No data
    -EOB; - - if ($list && $i < count($list)) { - echo "",count($list)-$i,' more available...'; - } - - echo <<< EOB -
    -EOB; - break; - - -// ----------------------------------------------- -// Per-Directory System Cache Entries -// ----------------------------------------------- -case OB_SYS_CACHE_DIR: - if (!$AUTHENTICATED) { - break; - } - - echo <<
    Scope: - - ", - ", Sorting:', - '', - '', - ", Group By Dir Level:', - ' ', - '
    ', - - '
    ', - '', - '', - '', - '', - '', - '', - '', - ''; - - // builds list with alpha numeric sortable keys - // - $tmp = $list = array(); - foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $entry) { - $n = dirname($entry['filename']); - if ($MYREQUEST['AGGR'] > 0) { - $n = preg_replace("!^(/?(?:[^/\\\\]+[/\\\\]){".($MYREQUEST['AGGR']-1)."}[^/\\\\]*).*!", "$1", $n); - } - if (!isset($tmp[$n])) { - $tmp[$n] = array('hits'=>0,'size'=>0,'ents'=>0); - } - $tmp[$n]['hits'] += $entry['num_hits']; - $tmp[$n]['size'] += $entry['mem_size']; - ++$tmp[$n]['ents']; - } - - foreach ($tmp as $k => $v) { - switch($MYREQUEST['SORT1']) { - case 'A': $kn=sprintf('%015d-',$v['size'] / $v['ents']);break; - case 'T': $kn=sprintf('%015d-',$v['ents']); break; - case 'H': $kn=sprintf('%015d-',$v['hits']); break; - case 'Z': $kn=sprintf('%015d-',$v['size']); break; - case 'C': $kn=sprintf('%015d-',$v['hits'] / $v['ents']);break; - case 'S': $kn = $k; break; - } - $list[$kn.$k] = array($k, $v['ents'], $v['hits'], $v['size']); - } - - if ($list) { - - // sort list - // - switch ($MYREQUEST['SORT2']) { - case "A": krsort($list); break; - case "D": ksort($list); break; - } - - // output list - $i = 0; - foreach($list as $entry) { - echo - '', - "', - '', - '', - '', - '', - '', - ''; - - if (++$i == $MYREQUEST['COUNT']) break; - } - - } else { - echo ''; - } - echo <<< EOB -
    ',sortheader('S','Directory Name', "&OB=".$MYREQUEST['OB']),'',sortheader('T','Number of Files',"&OB=".$MYREQUEST['OB']),'',sortheader('H','Total Hits', "&OB=".$MYREQUEST['OB']),'',sortheader('Z','Total Size', "&OB=".$MYREQUEST['OB']),'',sortheader('C','Avg. Hits', "&OB=".$MYREQUEST['OB']),'',sortheader('A','Avg. Size', "&OB=".$MYREQUEST['OB']),'
    ",$entry[0],'',$entry[1],'',$entry[2],'',$entry[3],'',round($entry[2] / $entry[1]),'',round($entry[3] / $entry[1]),'
    No data
    -EOB; - - if ($list && $i < count($list)) { - echo "",count($list)-$i,' more available...'; - } - - echo <<< EOB -
    -EOB; - break; - -// ----------------------------------------------- -// Version check -// ----------------------------------------------- -case OB_VERSION_CHECK: - echo <<

    APC Version Information

    - - - - -EOB; - - $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss"); - if (!$rss) { - echo ''; - } else { - $apcversion = phpversion('apc'); - - preg_match('!APC ([0-9.]+)!', $rss, $match); - echo ''; - echo ''; - } - echo <<< EOB -
    Unable to fetch version information.
    '; - if (version_compare($apcversion, $match[1], '>=')) { - echo '
    You are running the latest version of APC ('.$apcversion.')
    '; - $i = 3; - } else { - echo '
    You are running an older version of APC ('.$apcversion.'), - newer version '.$match[1].' is available at - http://pecl.php.net/package/APC/'.$match[1].' -
    '; - $i = -1; - } - echo '

    Change Log:


    '; - - preg_match_all('!<(title|description)>([^<]+)!', $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 "".htmlspecialchars($v)."
    "; - echo nl2br(htmlspecialchars(current($match[2])))."
    "; - next($match[2]); - } - echo '
    - -EOB; - break; - -} - -echo <<< EOB - -EOB; - -?> - - - - diff --git a/apc_cache.c b/apc_cache.c deleted file mode 100644 index a837871..0000000 --- a/apc_cache.c +++ /dev/null @@ -1,1114 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | Rasmus Lerdorf | - | Arun C. Murthy | - | Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - 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,v 3.145.2.4 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_cache.h" -#include "apc_lock.h" -#include "apc_sma.h" -#include "apc_globals.h" -#include "SAPI.h" -#include "ext/standard/php_var.h" -#include "ext/standard/php_smart_str.h" - -/* TODO: rehash when load factor exceeds threshold */ - -#define CHECK(p) { if ((p) == NULL) return NULL; } - -/* {{{ locking macros */ -#define CREATE_LOCK(lock) apc_lck_create(NULL, 0, 1, lock) -#define DESTROY_LOCK(c) apc_lck_destroy(c->header->lock) -#define LOCK(c) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lck_lock(c->header->lock); } -#define RDLOCK(c) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lck_rdlock(c->header->lock); } -#define UNLOCK(c) { apc_lck_unlock(c->header->lock); HANDLE_UNBLOCK_INTERRUPTIONS(); } -/* }}} */ - -/* {{{ key_equals */ -#define key_equals(a, b) (a.inode==b.inode && a.device==b.device) -/* }}} */ - -/* {{{ hash */ -static unsigned int hash(apc_cache_key_t key) -{ - return key.data.file.device + key.data.file.inode; -} -/* }}} */ - -/* {{{ string_nhash_8 */ -static unsigned int string_nhash_8(const char *s, size_t len) -{ - register const unsigned int *iv = (const unsigned int *)s; - register unsigned int h = 0; - register const unsigned int *e = (const unsigned int *)(s + len - (len % sizeof(unsigned int))); - - for(;iv> ((8*sizeof(unsigned int)) - 7)); - } - s = (const char *)iv; - for(len %= sizeof(unsigned int);len;len--) { - h += *(s++); - } - h ^= (h >> 13); - h ^= (h >> 7); - return h; -} -/* }}} */ - -/* {{{ make_slot */ -slot_t* make_slot(apc_cache_key_t key, apc_cache_entry_t* value, slot_t* next, time_t t) -{ - slot_t* p = apc_sma_malloc(sizeof(slot_t)); - if (!p) return NULL; - - if(value->type == APC_CACHE_ENTRY_USER) { - char *identifier = (char*) apc_xstrdup(key.data.user.identifier, apc_sma_malloc); - if (!identifier) { - apc_sma_free(p); - return NULL; - } - key.data.user.identifier = identifier; - } else if(key.type == APC_CACHE_KEY_FPFILE) { - char *fullpath = (char*) apc_xstrdup(key.data.fpfile.fullpath, apc_sma_malloc); - if (!fullpath) { - apc_sma_free(p); - return NULL; - } - key.data.fpfile.fullpath = fullpath; - } - p->key = key; - p->value = value; - p->next = next; - p->num_hits = 0; - p->creation_time = t; - p->access_time = t; - p->deletion_time = 0; - return p; -} -/* }}} */ - -/* {{{ free_slot */ -static void free_slot(slot_t* slot) -{ - if(slot->value->type == APC_CACHE_ENTRY_USER) { - apc_sma_free((char *)slot->key.data.user.identifier); - } else if(slot->key.type == APC_CACHE_KEY_FPFILE) { - apc_sma_free((char *)slot->key.data.fpfile.fullpath); - } - apc_cache_free_entry(slot->value); - apc_sma_free(slot); -} -/* }}} */ - -/* {{{ remove_slot */ -static void remove_slot(apc_cache_t* cache, slot_t** slot) -{ - slot_t* dead = *slot; - *slot = (*slot)->next; - - cache->header->mem_size -= dead->value->mem_size; - cache->header->num_entries--; - if (dead->value->ref_count <= 0) { - free_slot(dead); - } - else { - dead->next = cache->header->deleted_list; - dead->deletion_time = time(0); - cache->header->deleted_list = dead; - } -} -/* }}} */ - -/* {{{ process_pending_removals */ -static void process_pending_removals(apc_cache_t* cache) -{ - slot_t** slot; - time_t now; - - /* This function scans the list of removed cache entries and deletes any - * entry whose reference count is zero (indicating that it is no longer - * being executed) or that has been on the pending list for more than - * cache->gc_ttl seconds (we issue a warning in the latter case). - */ - - if (!cache->header->deleted_list) - return; - - slot = &cache->header->deleted_list; - now = time(0); - - while (*slot != NULL) { - int gc_sec = cache->gc_ttl ? (now - (*slot)->deletion_time) : 0; - - if ((*slot)->value->ref_count <= 0 || gc_sec > cache->gc_ttl) { - slot_t* dead = *slot; - - if (dead->value->ref_count > 0) { - switch(dead->value->type) { - case APC_CACHE_ENTRY_FILE: - apc_log(APC_WARNING, "GC cache entry '%s' (dev=%d ino=%d) " - "was on gc-list for %d seconds", dead->value->data.file.filename, - dead->key.data.file.device, dead->key.data.file.inode, gc_sec); - break; - case APC_CACHE_ENTRY_USER: - apc_log(APC_WARNING, "GC cache entry '%s' " - "was on gc-list for %d seconds", dead->value->data.user.info, gc_sec); - break; - } - } - *slot = dead->next; - free_slot(dead); - } - else { - slot = &(*slot)->next; - } - } -} -/* }}} */ - -/* {{{ prevent_garbage_collection */ -static void prevent_garbage_collection(apc_cache_entry_t* entry) -{ - /* set reference counts on zend objects to an arbitrarily high value to - * prevent garbage collection after execution */ - - enum { BIG_VALUE = 1000 }; - - if(entry->data.file.op_array) { - entry->data.file.op_array->refcount[0] = BIG_VALUE; - } - if (entry->data.file.functions) { - int i; - apc_function_t* fns = entry->data.file.functions; - for (i=0; fns[i].function != NULL; i++) { - *(fns[i].function->op_array.refcount) = BIG_VALUE; - } - } - if (entry->data.file.classes) { - int i; - apc_class_t* classes = entry->data.file.classes; - for (i=0; classes[i].class_entry != NULL; i++) { -#ifdef ZEND_ENGINE_2 - classes[i].class_entry->refcount = BIG_VALUE; -#else - classes[i].class_entry->refcount[0] = BIG_VALUE; -#endif - } - } -} -/* }}} */ - -/* {{{ apc_cache_create */ -apc_cache_t* apc_cache_create(int size_hint, int gc_ttl, int ttl) -{ - apc_cache_t* cache; - int cache_size; - int num_slots; - int i; - - num_slots = size_hint > 0 ? size_hint*2 : 2000; - - cache = (apc_cache_t*) apc_emalloc(sizeof(apc_cache_t)); - cache_size = sizeof(cache_header_t) + num_slots*sizeof(slot_t*); - - cache->shmaddr = apc_sma_malloc(cache_size); - if(!cache->shmaddr) { - apc_eprint("Unable to allocate shared memory for cache structures. (Perhaps your shared memory size isn't large enough?). "); - } - memset(cache->shmaddr, 0, cache_size); - - cache->header = (cache_header_t*) cache->shmaddr; - cache->header->num_hits = 0; - cache->header->num_misses = 0; - cache->header->deleted_list = NULL; - cache->header->start_time = time(NULL); - cache->header->expunges = 0; - cache->header->busy = 0; - - cache->slots = (slot_t**) (((char*) cache->shmaddr) + sizeof(cache_header_t)); - cache->num_slots = num_slots; - cache->gc_ttl = gc_ttl; - cache->ttl = ttl; - CREATE_LOCK(cache->header->lock); -#if NONBLOCKING_LOCK_AVAILABLE - CREATE_LOCK(cache->header->wrlock); -#endif - for (i = 0; i < num_slots; i++) { - cache->slots[i] = NULL; - } - - return cache; -} -/* }}} */ - -/* {{{ apc_cache_destroy */ -void apc_cache_destroy(apc_cache_t* cache) -{ - DESTROY_LOCK(cache); - apc_efree(cache); -} -/* }}} */ - -/* {{{ apc_cache_clear */ -void apc_cache_clear(apc_cache_t* cache) -{ - int i; - - if(!cache) return; - - LOCK(cache); - cache->header->busy = 1; - cache->header->num_hits = 0; - cache->header->num_misses = 0; - cache->header->start_time = time(NULL); - cache->header->expunges = 0; - - for (i = 0; i < cache->num_slots; i++) { - slot_t* p = cache->slots[i]; - while (p) { - remove_slot(cache, &p); - } - cache->slots[i] = NULL; - } - - cache->header->busy = 0; - UNLOCK(cache); -} -/* }}} */ - -/* {{{ apc_cache_expunge */ -void apc_cache_expunge(apc_cache_t* cache, time_t t) -{ - int i; - - if(!cache) return; - - if(!cache->ttl) { - /* - * If cache->ttl is not set, we wipe out the entire cache when - * we run out of space. - */ - LOCK(cache); - cache->header->busy = 1; - cache->header->expunges++; - for (i = 0; i < cache->num_slots; i++) { - slot_t* p = cache->slots[i]; - while (p) { - remove_slot(cache, &p); - } - cache->slots[i] = NULL; - } - cache->header->busy = 0; - UNLOCK(cache); - } else { - slot_t **p; - - /* - * If the ttl for the cache is set we walk through and delete stale - * entries. For the user cache that is slightly confusing since - * we have the individual entry ttl's we can look at, but that would be - * too much work. So if you want the user cache expunged, set a high - * default apc.user_ttl and still provide a specific ttl for each entry - * on insert - */ - - LOCK(cache); - cache->header->busy = 1; - cache->header->expunges++; - for (i = 0; i < cache->num_slots; i++) { - p = &cache->slots[i]; - while(*p) { - /* - * For the user cache we look at the individual entry ttl values - * and if not set fall back to the default ttl for the user cache - */ - if((*p)->value->type == APC_CACHE_ENTRY_USER) { - if((*p)->value->data.user.ttl) { - if((*p)->creation_time + (*p)->value->data.user.ttl < t) { - remove_slot(cache, p); - continue; - } - } else if(cache->ttl) { - if((*p)->creation_time + cache->ttl < t) { - remove_slot(cache, p); - continue; - } - } - } else if((*p)->access_time < (t - cache->ttl)) { - remove_slot(cache, p); - continue; - } - p = &(*p)->next; - } - } - cache->header->busy = 0; - UNLOCK(cache); - } -} -/* }}} */ - -/* {{{ apc_cache_insert */ -int apc_cache_insert(apc_cache_t* cache, - apc_cache_key_t key, - apc_cache_entry_t* value, - time_t t) -{ - slot_t** slot; - - if (!value) { - return 0; - } - -#ifdef __DEBUG_APC__ - fprintf(stderr,"Inserting [%s]\n", value->data.file.filename); -#endif - - LOCK(cache); - process_pending_removals(cache); - - if(key.type == APC_CACHE_KEY_FILE) slot = &cache->slots[hash(key) % cache->num_slots]; - else slot = &cache->slots[string_nhash_8(key.data.fpfile.fullpath, key.data.fpfile.fullpath_len) % cache->num_slots]; - - while(*slot) { - if(key.type == (*slot)->key.type) { - if(key.type == APC_CACHE_KEY_FILE) { - if(key_equals((*slot)->key.data.file, key.data.file)) { - /* If existing slot for the same device+inode is different, remove it and insert the new version */ - if ((*slot)->key.mtime != key.mtime) { - remove_slot(cache, slot); - break; - } - UNLOCK(cache); - return 0; - } else if(cache->ttl && (*slot)->access_time < (t - cache->ttl)) { - remove_slot(cache, slot); - continue; - } - } else { /* APC_CACHE_KEY_FPFILE */ - if(!memcmp((*slot)->key.data.fpfile.fullpath, key.data.fpfile.fullpath, key.data.fpfile.fullpath_len+1)) { - /* Hrm.. it's already here, remove it and insert new one */ - remove_slot(cache, slot); - break; - } else if(cache->ttl && (*slot)->access_time < (t - cache->ttl)) { - remove_slot(cache, slot); - continue; - } - } - } - slot = &(*slot)->next; - } - - if ((*slot = make_slot(key, value, *slot, t)) == NULL) { - UNLOCK(cache); - return -1; - } - - cache->header->mem_size += value->mem_size; - cache->header->num_entries++; - cache->header->num_inserts++; - - UNLOCK(cache); - return 1; -} -/* }}} */ - -/* {{{ apc_cache_user_insert */ -int apc_cache_user_insert(apc_cache_t* cache, apc_cache_key_t key, apc_cache_entry_t* value, time_t t, int exclusive TSRMLS_DC) -{ - slot_t** slot; - size_t* mem_size_ptr = NULL; - - if (!value) { - return 0; - } - - LOCK(cache); - process_pending_removals(cache); - - slot = &cache->slots[string_nhash_8(key.data.user.identifier, key.data.user.identifier_len) % cache->num_slots]; - - if (APCG(mem_size_ptr) != NULL) { - mem_size_ptr = APCG(mem_size_ptr); - APCG(mem_size_ptr) = NULL; - } - - while (*slot) { - if (!memcmp((*slot)->key.data.user.identifier, key.data.user.identifier, key.data.user.identifier_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 && ( !(*slot)->value->data.user.ttl || - ( (*slot)->value->data.user.ttl && ((*slot)->creation_time + (*slot)->value->data.user.ttl) >= t ) - ) ) { - UNLOCK(cache); - return 0; - } - remove_slot(cache, slot); - 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 && (*slot)->access_time < (t - cache->ttl)) || - ((*slot)->value->data.user.ttl && ((*slot)->creation_time + (*slot)->value->data.user.ttl) < t)) { - remove_slot(cache, slot); - continue; - } - slot = &(*slot)->next; - } - - if (mem_size_ptr != NULL) { - APCG(mem_size_ptr) = mem_size_ptr; - } - - if ((*slot = make_slot(key, value, *slot, t)) == NULL) { - UNLOCK(cache); - return 0; - } - if (APCG(mem_size_ptr) != NULL) { - value->mem_size = *APCG(mem_size_ptr); - cache->header->mem_size += *APCG(mem_size_ptr); - } - cache->header->num_entries++; - cache->header->num_inserts++; - - UNLOCK(cache); - return 1; -} -/* }}} */ - -/* {{{ apc_cache_find_slot */ -slot_t* apc_cache_find_slot(apc_cache_t* cache, apc_cache_key_t key, time_t t) -{ - slot_t** slot; - volatile slot_t* retval = NULL; - - LOCK(cache); - if(key.type == APC_CACHE_KEY_FILE) slot = &cache->slots[hash(key) % cache->num_slots]; - else slot = &cache->slots[string_nhash_8(key.data.fpfile.fullpath, key.data.fpfile.fullpath_len) % cache->num_slots]; - - while (*slot) { - if(key.type == (*slot)->key.type) { - if(key.type == APC_CACHE_KEY_FILE) { - if(key_equals((*slot)->key.data.file, key.data.file)) { - if((*slot)->key.mtime != key.mtime) { - remove_slot(cache, slot); - cache->header->num_misses++; - UNLOCK(cache); - return NULL; - } - (*slot)->num_hits++; - (*slot)->value->ref_count++; - (*slot)->access_time = t; - prevent_garbage_collection((*slot)->value); - cache->header->num_hits++; - retval = *slot; - UNLOCK(cache); - return (slot_t*)retval; - } - } else { /* APC_CACHE_KEY_FPFILE */ - if(!memcmp((*slot)->key.data.fpfile.fullpath, key.data.fpfile.fullpath, key.data.fpfile.fullpath_len+1)) { - /* TTL Check ? */ - (*slot)->num_hits++; - (*slot)->value->ref_count++; - (*slot)->access_time = t; - prevent_garbage_collection((*slot)->value); - cache->header->num_hits++; - retval = *slot; - UNLOCK(cache); - return (slot_t*)retval; - } - } - } - slot = &(*slot)->next; - } - cache->header->num_misses++; - UNLOCK(cache); - return NULL; -} -/* }}} */ - -/* {{{ apc_cache_find */ -apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, apc_cache_key_t key, time_t t) -{ - slot_t * slot = apc_cache_find_slot(cache, key, t); - return (slot) ? slot->value : NULL; -} -/* }}} */ - -/* {{{ apc_cache_user_find */ -apc_cache_entry_t* apc_cache_user_find(apc_cache_t* cache, char *strkey, int keylen, time_t t) -{ - slot_t** slot; - volatile apc_cache_entry_t* value = NULL; - - LOCK(cache); - - slot = &cache->slots[string_nhash_8(strkey, keylen) % cache->num_slots]; - - while (*slot) { - if (!memcmp((*slot)->key.data.user.identifier, strkey, keylen)) { - /* Check to make sure this entry isn't expired by a hard TTL */ - if((*slot)->value->data.user.ttl && ((*slot)->creation_time + (*slot)->value->data.user.ttl) < t) { - remove_slot(cache, slot); - UNLOCK(cache); - return NULL; - } - /* Otherwise we are fine, increase counters and return the cache entry */ - (*slot)->num_hits++; - (*slot)->value->ref_count++; - (*slot)->access_time = t; - - cache->header->num_hits++; - value = (*slot)->value; - UNLOCK(cache); - return (apc_cache_entry_t*)value; - } - slot = &(*slot)->next; - } - - UNLOCK(cache); - return NULL; -} -/* }}} */ - -/* {{{ apc_cache_user_delete */ -int apc_cache_user_delete(apc_cache_t* cache, char *strkey, int keylen) -{ - slot_t** slot; - - LOCK(cache); - - slot = &cache->slots[string_nhash_8(strkey, keylen) % cache->num_slots]; - - while (*slot) { - if (!memcmp((*slot)->key.data.user.identifier, strkey, keylen)) { - remove_slot(cache, slot); - UNLOCK(cache); - return 1; - } - slot = &(*slot)->next; - } - - UNLOCK(cache); - return 0; -} -/* }}} */ - -/* {{{ apc_cache_release */ -void apc_cache_release(apc_cache_t* cache, apc_cache_entry_t* entry) -{ - LOCK(cache); - entry->ref_count--; - UNLOCK(cache); -} -/* }}} */ - -/* {{{ apc_cache_make_file_key */ -int apc_cache_make_file_key(apc_cache_key_t* key, - const char* filename, - const char* include_path, - time_t t - TSRMLS_DC) -{ - struct stat *tmp_buf=NULL; - struct apc_fileinfo_t fileinfo = { {0}, }; - int len; - - assert(key != NULL); - - if (!filename || !SG(request_info).path_translated) { -#ifdef __DEBUG_APC__ - fprintf(stderr,"No filename and no path_translated - bailing\n"); -#endif - return 0; - } - - len = strlen(filename); - if(APCG(fpstat)==0) { - if(IS_ABSOLUTE_PATH(filename,len)) { - key->data.fpfile.fullpath = filename; - key->data.fpfile.fullpath_len = len; - key->mtime = t; - key->type = APC_CACHE_KEY_FPFILE; - } else { - if (apc_search_paths(filename, include_path, &fileinfo) != 0) { - apc_wprint("apc failed to locate %s - bailing", filename); - return 0; - } - - if(!realpath(fileinfo.fullpath, APCG(canon_path))) { - apc_wprint("realpath failed to canonicalize %s - bailing", filename); - return 0; - } - - key->data.fpfile.fullpath = APCG(canon_path); - key->data.fpfile.fullpath_len = strlen(APCG(canon_path)); - key->mtime = t; - key->type = APC_CACHE_KEY_FPFILE; - } - return 1; - } - - if(!strcmp(SG(request_info).path_translated, filename)) { - tmp_buf = sapi_get_stat(TSRMLS_C); /* Apache has already done this stat() for us */ - } - if(tmp_buf) { - fileinfo.st_buf.sb = *tmp_buf; - } else { - if (apc_search_paths(filename, include_path, &fileinfo) != 0) { -#ifdef __DEBUG_APC__ - fprintf(stderr,"Stat failed %s - bailing (%s) (%d)\n",filename,SG(request_info).path_translated); -#endif - return 0; - } - } - - if(APCG(max_file_size) < fileinfo.st_buf.sb.st_size) { -#ifdef __DEBUG_APC__ - fprintf(stderr,"File is too big %s (%d - %ld) - bailing\n",filename,t,fileinfo.st_buf.sb.st_size); -#endif - return 0; - } - - /* - * This is a bit of a hack. - * - * Here I am checking to see if the file is at least 2 seconds old. - * The idea is that if the file is currently being written to then its - * mtime is going to match or at most be 1 second off of the current - * request time and we want to avoid caching files that have not been - * completely written. Of course, people should be using atomic - * mechanisms to push files onto live web servers, but adding this - * tiny safety is easier than educating the world. This is now - * configurable, but the default is still 2 seconds. - */ - if(APCG(file_update_protection) && (t - fileinfo.st_buf.sb.st_mtime < APCG(file_update_protection))) { -#ifdef __DEBUG_APC__ - fprintf(stderr,"File is too new %s (%d - %d) - bailing\n",filename,t,fileinfo.st_buf.sb.st_mtime); -#endif - return 0; - } - - key->data.file.device = fileinfo.st_buf.sb.st_dev; - key->data.file.inode = fileinfo.st_buf.sb.st_ino; - /* - * If working with content management systems that like to munge the mtime, - * it might be appropriate to key off of the ctime to be immune to systems - * that try to backdate a template. If the mtime is set to something older - * than the previous mtime of a template we will obviously never see this - * "older" template. At some point the Smarty templating system did this. - * I generally disagree with using the ctime here because you lose the - * ability to warm up new content by saving it to a temporary file, hitting - * it once to cache it and then renaming it into its permanent location so - * set the apc.stat_ctime=true to enable this check. - */ - if(APCG(stat_ctime)) { - key->mtime = (fileinfo.st_buf.sb.st_ctime > fileinfo.st_buf.sb.st_mtime) ? fileinfo.st_buf.sb.st_ctime : fileinfo.st_buf.sb.st_mtime; - } else { - key->mtime = fileinfo.st_buf.sb.st_mtime; - } - key->type = APC_CACHE_KEY_FILE; - return 1; -} -/* }}} */ - -/* {{{ apc_cache_make_user_key */ -int apc_cache_make_user_key(apc_cache_key_t* key, char* identifier, int identifier_len, const time_t t) -{ - assert(key != NULL); - - if (!identifier) - return 0; - - key->data.user.identifier = identifier; - key->data.user.identifier_len = identifier_len; - key->mtime = t; - key->type = APC_CACHE_KEY_USER; - return 1; -} -/* }}} */ - -/* {{{ apc_cache_make_file_entry */ -apc_cache_entry_t* apc_cache_make_file_entry(const char* filename, - zend_op_array* op_array, - apc_function_t* functions, - apc_class_t* classes) -{ - apc_cache_entry_t* entry; - - entry = (apc_cache_entry_t*) apc_sma_malloc(sizeof(apc_cache_entry_t)); - if (!entry) return NULL; - - entry->data.file.filename = apc_xstrdup(filename, apc_sma_malloc); - if(!entry->data.file.filename) { -#ifdef __DEBUG_APC__ - fprintf(stderr,"apc_cache_make_file_entry: entry->data.file.filename is NULL - bailing\n"); -#endif - apc_sma_free(entry); - return NULL; - } -#ifdef __DEBUG_APC__ - fprintf(stderr,"apc_cache_make_file_entry: entry->data.file.filename is [%s]\n",entry->data.file.filename); -#endif - entry->data.file.op_array = op_array; - entry->data.file.functions = functions; - entry->data.file.classes = classes; - entry->type = APC_CACHE_ENTRY_FILE; - entry->ref_count = 0; - entry->mem_size = 0; - return entry; -} -/* }}} */ - -/* {{{ apc_cache_store_zval */ -zval* apc_cache_store_zval(zval* dst, const zval* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - smart_str buf = {0}; - php_serialize_data_t var_hash; - TSRMLS_FETCH(); - - if((src->type & ~IS_CONSTANT_INDEX) == IS_OBJECT) { - if(!dst) { - CHECK(dst = (zval*) allocate(sizeof(zval))); - } - - PHP_VAR_SERIALIZE_INIT(var_hash); - php_var_serialize(&buf, (zval**)&src, &var_hash TSRMLS_CC); - PHP_VAR_SERIALIZE_DESTROY(var_hash); - - dst->type = IS_NULL; /* in case we fail */ - if(buf.c) { - dst->type = src->type & ~IS_CONSTANT_INDEX; - dst->value.str.len = buf.len; - CHECK(dst->value.str.val = apc_xmemcpy(buf.c, buf.len+1, allocate)); - dst->type = src->type; - smart_str_free(&buf); - } - return dst; - } else { - - /* Maintain a list of zvals we've copied to properly handle recursive structures */ - HashTable *old = APCG(copied_zvals); - APCG(copied_zvals) = emalloc(sizeof(HashTable)); - zend_hash_init(APCG(copied_zvals), 0, NULL, NULL, 0); - - dst = apc_copy_zval(dst, src, allocate, deallocate); - - if(APCG(copied_zvals)) { - zend_hash_destroy(APCG(copied_zvals)); - efree(APCG(copied_zvals)); - } - - APCG(copied_zvals) = old; - - return dst; - } -} -/* }}} */ - -/* {{{ apc_cache_fetch_zval */ -zval* apc_cache_fetch_zval(zval* dst, const zval* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - TSRMLS_FETCH(); - if((src->type & ~IS_CONSTANT_INDEX) == IS_OBJECT) { - php_unserialize_data_t var_hash; - const unsigned char *p = (unsigned char*)Z_STRVAL_P(src); - - PHP_VAR_UNSERIALIZE_INIT(var_hash); - if(!php_var_unserialize(&dst, &p, p + Z_STRLEN_P(src), &var_hash TSRMLS_CC)) { - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - zval_dtor(dst); - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - Z_STRVAL_P(src)), Z_STRLEN_P(src)); - dst->type = IS_NULL; - } - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - return dst; - } else { - - /* Maintain a list of zvals we've copied to properly handle recursive structures */ - HashTable *old = APCG(copied_zvals); - APCG(copied_zvals) = emalloc(sizeof(HashTable)); - zend_hash_init(APCG(copied_zvals), 0, NULL, NULL, 0); - - dst = apc_copy_zval(dst, src, allocate, deallocate); - - if(APCG(copied_zvals)) { - zend_hash_destroy(APCG(copied_zvals)); - efree(APCG(copied_zvals)); - } - - APCG(copied_zvals) = old; - - return dst; - } -} -/* }}} */ - -/* {{{ apc_cache_free_zval */ -void apc_cache_free_zval(zval* src, apc_free_t deallocate) -{ - TSRMLS_FETCH(); - if ((src->type & ~IS_CONSTANT_INDEX) == IS_OBJECT) { - if (src->value.str.val) { - deallocate(src->value.str.val); - } - deallocate(src); - } else { - /* Maintain a list of zvals we've copied to properly handle recursive structures */ - HashTable *old = APCG(copied_zvals); - APCG(copied_zvals) = emalloc(sizeof(HashTable)); - zend_hash_init(APCG(copied_zvals), 0, NULL, NULL, 0); - - apc_free_zval(src, deallocate); - - if(APCG(copied_zvals)) { - zend_hash_destroy(APCG(copied_zvals)); - efree(APCG(copied_zvals)); - } - - APCG(copied_zvals) = old; - } -} -/* }}} */ - -/* {{{ apc_cache_make_user_entry */ -apc_cache_entry_t* apc_cache_make_user_entry(const char* info, int info_len, const zval* val, const unsigned int ttl) -{ - apc_cache_entry_t* entry; - - entry = (apc_cache_entry_t*) apc_sma_malloc(sizeof(apc_cache_entry_t)); - if (!entry) return NULL; - - entry->data.user.info = apc_xmemcpy(info, info_len, apc_sma_malloc); - entry->data.user.info_len = info_len; - if(!entry->data.user.info) { - apc_sma_free(entry); - return NULL; - } - entry->data.user.val = apc_cache_store_zval(NULL, val, apc_sma_malloc, apc_sma_free); - if(!entry->data.user.val) { - apc_sma_free(entry->data.user.info); - apc_sma_free(entry); - return NULL; - } - INIT_PZVAL(entry->data.user.val); - entry->data.user.ttl = ttl; - entry->type = APC_CACHE_ENTRY_USER; - entry->ref_count = 0; - entry->mem_size = 0; - return entry; -} -/* }}} */ - -/* {{{ apc_cache_free_entry */ -void apc_cache_free_entry(apc_cache_entry_t* entry) -{ - if (entry != NULL) { - assert(entry->ref_count == 0); - switch(entry->type) { - case APC_CACHE_ENTRY_FILE: - apc_sma_free(entry->data.file.filename); - apc_free_op_array(entry->data.file.op_array, apc_sma_free); - apc_free_functions(entry->data.file.functions, apc_sma_free); - apc_free_classes(entry->data.file.classes, apc_sma_free); - break; - case APC_CACHE_ENTRY_USER: - apc_sma_free(entry->data.user.info); - apc_cache_free_zval(entry->data.user.val, apc_sma_free); - break; - } - apc_sma_free(entry); - } -} -/* }}} */ - -/* {{{ apc_cache_info */ -apc_cache_info_t* apc_cache_info(apc_cache_t* cache, zend_bool limited) -{ - apc_cache_info_t* info; - slot_t* p; - int i; - - if(!cache) return NULL; - - LOCK(cache); - - info = (apc_cache_info_t*) apc_emalloc(sizeof(apc_cache_info_t)); - if(!info) { - UNLOCK(cache); - return NULL; - } - info->num_slots = cache->num_slots; - info->ttl = cache->ttl; - info->num_hits = cache->header->num_hits; - info->num_misses = cache->header->num_misses; - info->list = NULL; - info->deleted_list = NULL; - info->start_time = cache->header->start_time; - info->expunges = cache->header->expunges; - info->mem_size = cache->header->mem_size; - info->num_entries = cache->header->num_entries; - info->num_inserts = cache->header->num_inserts; - - if(!limited) { - /* For each hashtable slot */ - for (i = 0; i < info->num_slots; i++) { - p = cache->slots[i]; - for (; p != NULL; p = p->next) { - apc_cache_link_t* link = (apc_cache_link_t*) apc_emalloc(sizeof(apc_cache_link_t)); - - if(p->value->type == APC_CACHE_ENTRY_FILE) { - link->data.file.filename = apc_xstrdup(p->value->data.file.filename, apc_emalloc); - link->data.file.device = p->key.data.file.device; - link->data.file.inode = p->key.data.file.inode; - link->type = APC_CACHE_ENTRY_FILE; - } else if(p->value->type == APC_CACHE_ENTRY_USER) { - link->data.user.info = apc_xmemcpy(p->value->data.user.info, p->value->data.user.info_len, apc_emalloc); - link->data.user.ttl = p->value->data.user.ttl; - link->type = APC_CACHE_ENTRY_USER; - } - link->num_hits = p->num_hits; - link->mtime = p->key.mtime; - link->creation_time = p->creation_time; - link->deletion_time = p->deletion_time; - link->access_time = p->access_time; - link->ref_count = p->value->ref_count; - link->mem_size = p->value->mem_size; - link->next = info->list; - info->list = link; - } - } - - /* For each slot pending deletion */ - for (p = cache->header->deleted_list; p != NULL; p = p->next) { - apc_cache_link_t* link = (apc_cache_link_t*) apc_emalloc(sizeof(apc_cache_link_t)); - - if(p->value->type == APC_CACHE_ENTRY_FILE) { - link->data.file.filename = apc_xstrdup(p->value->data.file.filename, apc_emalloc); - if(p->key.type == APC_CACHE_KEY_FILE) { - link->data.file.device = p->key.data.file.device; - link->data.file.inode = p->key.data.file.inode; - } else { /* This is a no-stat fullpath file entry */ - link->data.file.device = 0; - link->data.file.inode = 0; - } - link->type = APC_CACHE_ENTRY_FILE; - } else if(p->value->type == APC_CACHE_ENTRY_USER) { - link->data.user.info = apc_xmemcpy(p->value->data.user.info, p->value->data.user.info_len, apc_emalloc); - link->data.user.ttl = p->value->data.user.ttl; - link->type = APC_CACHE_ENTRY_USER; - } - link->num_hits = p->num_hits; - link->mtime = p->key.mtime; - link->creation_time = p->creation_time; - link->deletion_time = p->deletion_time; - link->access_time = p->access_time; - link->ref_count = p->value->ref_count; - link->mem_size = p->value->mem_size; - link->next = info->deleted_list; - info->deleted_list = link; - } - } - - UNLOCK(cache); - return info; -} -/* }}} */ - -/* {{{ apc_cache_free_info */ -void apc_cache_free_info(apc_cache_info_t* info) -{ - apc_cache_link_t* p = info->list; - apc_cache_link_t* q = NULL; - while (p != NULL) { - q = p; - p = p->next; - if(q->type == APC_CACHE_ENTRY_FILE) apc_efree(q->data.file.filename); - else if(q->type == APC_CACHE_ENTRY_USER) apc_efree(q->data.user.info); - apc_efree(q); - } - p = info->deleted_list; - while (p != NULL) { - q = p; - p = p->next; - if(q->type == APC_CACHE_ENTRY_FILE) apc_efree(q->data.file.filename); - else if(q->type == APC_CACHE_ENTRY_USER) apc_efree(q->data.user.info); - apc_efree(q); - } - apc_efree(info); -} -/* }}} */ - -/* {{{ apc_cache_unlock */ -void apc_cache_unlock(apc_cache_t* cache) -{ - UNLOCK(cache); -} -/* }}} */ - -/* {{{ apc_cache_busy */ -zend_bool apc_cache_busy(apc_cache_t* cache) -{ - return cache->header->busy; -} -/* }}} */ - -#if NONBLOCKING_LOCK_AVAILABLE -/* {{{ apc_cache_write_lock */ -zend_bool apc_cache_write_lock(apc_cache_t* cache) -{ - return apc_lck_nb_lock(cache->header->wrlock); -} -/* }}} */ - -/* {{{ apc_cache_write_unlock */ -void apc_cache_write_unlock(apc_cache_t* cache) -{ - apc_lck_unlock(cache->header->wrlock); -} -/* }}} */ -#endif - -/* - * 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 - */ diff --git a/apc_cache.h b/apc_cache.h deleted file mode 100644 index 8b6f399..0000000 --- a/apc_cache.h +++ /dev/null @@ -1,341 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | Rasmus Lerdorf | - +----------------------------------------------------------------------+ - - 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.h,v 3.46.2.4 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_CACHE_H -#define APC_CACHE_H - -/* - * This module defines the shared memory file cache. Basically all of the - * logic for storing and retrieving cache entries lives here. - */ - -#include "apc.h" -#include "apc_compile.h" -#include "apc_lock.h" - -#define APC_CACHE_ENTRY_FILE 1 -#define APC_CACHE_ENTRY_USER 2 - -#define APC_CACHE_KEY_FILE 1 -#define APC_CACHE_KEY_USER 2 -#define APC_CACHE_KEY_FPFILE 3 - -/* {{{ struct definition: apc_cache_key_t */ -#define T apc_cache_t* -typedef struct apc_cache_t apc_cache_t; /* opaque cache type */ - -typedef union _apc_cache_key_data_t { - struct { - dev_t device; /* the filesystem device */ - ino_t inode; /* the filesystem inode */ - } file; - struct { - const char *identifier; - int identifier_len; - } user; - struct { - const char *fullpath; - int fullpath_len; - } fpfile; -} apc_cache_key_data_t; - -typedef struct apc_cache_key_t apc_cache_key_t; -struct apc_cache_key_t { - apc_cache_key_data_t data; - time_t mtime; /* the mtime of this cached entry */ - unsigned char type; -}; -/* }}} */ - -/* {{{ struct definition: apc_cache_entry_t */ -typedef union _apc_cache_entry_value_t { - struct { - char *filename; /* absolute path to source file */ - zend_op_array* op_array; /* op_array allocated in shared memory */ - apc_function_t* functions; /* array of apc_function_t's */ - apc_class_t* classes; /* array of apc_class_t's */ - } file; - struct { - char *info; - int info_len; - zval *val; - unsigned int ttl; - } user; -} apc_cache_entry_value_t; - -typedef struct apc_cache_entry_t apc_cache_entry_t; -struct apc_cache_entry_t { - apc_cache_entry_value_t data; - unsigned char type; - int ref_count; - size_t mem_size; -}; -/* }}} */ - -/* - * apc_cache_create creates the shared memory compiler cache. This function - * should be called just once (ideally in the web server parent process, e.g. - * in apache), otherwise you will end up with multiple caches (which won't - * necessarily break anything). Returns a pointer to the cache object. - * - * size_hint is a "hint" at the total number of source files that will be - * cached. It determines the physical size of the hash table. Passing 0 for - * this argument will use a reasonable default value. - * - * gc_ttl is the maximum time a cache entry may speed on the garbage - * collection list. This is basically a work around for the inherent - * unreliability of our reference counting mechanism (see apc_cache_release). - * - * ttl is the maximum time a cache entry can idle in a slot in case the slot - * is needed. This helps in cleaning up the cache and ensuring that entries - * hit frequently stay cached and ones not hit very often eventually disappear. - */ -extern T apc_cache_create(int size_hint, int gc_ttl, int ttl); - -/* - * apc_cache_destroy releases any OS resources associated with a cache object. - * Under apache, this function can be safely called by the child processes - * when they exit. - */ -extern void apc_cache_destroy(T cache); - -/* - * apc_cache_clear empties a cache. This can safely be called at any time, - * even while other server processes are executing cached source files. - */ -extern void apc_cache_clear(T cache); - -/* - * apc_cache_insert adds an entry to the cache, using a filename as a key. - * Internally, the filename is translated to a canonical representation, so - * that relative and absolute filenames will map to a single key. Returns - * non-zero if the file was successfully inserted, 0 otherwise. If 0 is - * returned, the caller must free the cache entry by calling - * apc_cache_free_entry (see below). - * - * key is the value created by apc_cache_make_file_key for file keys. - * - * value is a cache entry returned by apc_cache_make_entry (see below). - */ -extern int apc_cache_insert(T cache, apc_cache_key_t key, - apc_cache_entry_t* value, time_t t); - -extern int apc_cache_user_insert(T cache, apc_cache_key_t key, - apc_cache_entry_t* value, time_t t, int exclusive TSRMLS_DC); - -/* - * apc_cache_find searches for a cache entry by filename, and returns a - * pointer to the entry if found, NULL otherwise. - * - * key is a value created by apc_cache_make_file_key for file keys. - */ -extern apc_cache_entry_t* apc_cache_find(T cache, apc_cache_key_t key, time_t t); - -/* - * apc_cache_user_find searches for a cache entry by its hashed identifier, - * and returns a pointer to the entry if found, NULL otherwise. - * - */ -extern apc_cache_entry_t* apc_cache_user_find(T cache, char* strkey, int keylen, time_t t); - -/* - * apc_cache_user_delete finds an entry in the user cache and deletes it. - */ -extern int apc_cache_user_delete(apc_cache_t* cache, char *strkey, int keylen); - -/* apc_cach_fetch_zval takes a zval in the cache and reconstructs a runtime - * zval from it. - * - */ -zval* apc_cache_fetch_zval(zval* dst, const zval* src, apc_malloc_t allocate, apc_free_t deallocate); - -/* - * apc_cache_release decrements the reference count associated with a cache - * entry. Calling apc_cache_find automatically increments the reference count, - * and this function must be called post-execution to return the count to its - * original value. Failing to do so will prevent the entry from being - * garbage-collected. - * - * entry is the cache entry whose ref count you want to decrement. - */ -extern void apc_cache_release(T cache, apc_cache_entry_t* entry); - -/* - * apc_cache_make_file_key creates a key object given a relative or absolute - * filename and an optional list of auxillary paths to search. include_path is - * searched if the filename cannot be found relative to the current working - * directory. - * - * key points to caller-allocated storage (must not be null). - * - * filename is the path to the source file. - * - * include_path is a colon-separated list of directories to search. - * - * and finally we pass in the current request time so we can avoid - * caching files with a current mtime which tends to indicate that - * they are still being written to. - */ -extern int apc_cache_make_file_key(apc_cache_key_t* key, - const char* filename, - const char* include_path, - time_t t - TSRMLS_DC); - -/* - * apc_cache_make_file_entry creates an apc_cache_entry_t object given a filename - * and the compilation results returned by the PHP compiler. - */ -extern apc_cache_entry_t* apc_cache_make_file_entry(const char* filename, - zend_op_array* op_array, - apc_function_t* functions, - apc_class_t* classes); -/* - * apc_cache_make_user_entry creates an apc_cache_entry_t object given an info string - * and the zval to be stored. - */ -extern apc_cache_entry_t* apc_cache_make_user_entry(const char* info, int info_len, const zval *val, const unsigned int ttl); - -extern int apc_cache_make_user_key(apc_cache_key_t* key, char* identifier, int identifier_len, const time_t t); - -/* - * Frees all memory associated with an object returned by apc_cache_make_entry - * (see above). - */ -extern void apc_cache_free_entry(apc_cache_entry_t* entry); - -/* {{{ struct definition: apc_cache_link_data_t */ -typedef union _apc_cache_link_data_t { - struct { - char *filename; - dev_t device; - ino_t inode; - } file; - struct { - char *info; - unsigned int ttl; - } user; -} apc_cache_link_data_t; -/* }}} */ - -/* {{{ struct definition: apc_cache_link_t */ -typedef struct apc_cache_link_t apc_cache_link_t; -struct apc_cache_link_t { - apc_cache_link_data_t data; - unsigned char type; - int num_hits; - time_t mtime; - time_t creation_time; - time_t deletion_time; - time_t access_time; - int ref_count; - size_t mem_size; - apc_cache_link_t* next; -}; -/* }}} */ - -/* {{{ struct definition: apc_cache_info_t */ -typedef struct apc_cache_info_t apc_cache_info_t; -struct apc_cache_info_t { - int num_slots; - int num_hits; - int num_misses; - int ttl; - apc_cache_link_t* list; - apc_cache_link_t* deleted_list; - time_t start_time; - int expunges; - int num_entries; - int num_inserts; - size_t mem_size; -}; -/* }}} */ - -/* {{{ struct definition: slot_t */ -typedef struct slot_t slot_t; -struct slot_t { - apc_cache_key_t key; /* slot key */ - apc_cache_entry_t* value; /* slot value */ - slot_t* next; /* next slot in linked list */ - int num_hits; /* number of hits to this bucket */ - time_t creation_time; /* time slot was initialized */ - time_t deletion_time; /* time slot was removed from cache */ - time_t access_time; /* time slot was last accessed */ -}; -/* }}} */ - -/* {{{ struct definition: cache_header_t - Any values that must be shared among processes should go in here. */ -typedef struct cache_header_t cache_header_t; -struct cache_header_t { - apc_lck_t lock; /* read/write lock (exclusive blocking cache lock) */ - apc_lck_t wrlock; /* write lock (non-blocking used to prevent cache slams) */ - int num_hits; /* total successful hits in cache */ - int num_misses; /* total unsuccessful hits in cache */ - int num_inserts; /* total successful inserts in cache */ - slot_t* deleted_list; /* linked list of to-be-deleted slots */ - time_t start_time; /* time the above counters were reset */ - int expunges; /* total number of expunges */ - zend_bool busy; /* Flag to tell clients when we are busy cleaning the cache */ - int num_entries; /* Statistic on the number of entries */ - size_t mem_size; /* Statistic on the memory size used by this cache */ -}; -/* }}} */ - -/* {{{ struct definition: apc_cache_t */ -struct apc_cache_t { - void* shmaddr; /* process (local) address of shared cache */ - cache_header_t* header; /* cache header (stored in SHM) */ - slot_t** slots; /* array of cache slots (stored in SHM) */ - int num_slots; /* number of slots in cache */ - int gc_ttl; /* maximum time on GC list for a slot */ - int ttl; /* if slot is needed and entry's access time is older than this ttl, remove it */ -}; -/* }}} */ - -extern apc_cache_info_t* apc_cache_info(T cache, zend_bool limited); -extern void apc_cache_free_info(apc_cache_info_t* info); -extern void apc_cache_expunge(apc_cache_t* cache, time_t t); -extern void apc_cache_unlock(apc_cache_t* cache); -extern zend_bool apc_cache_busy(apc_cache_t* cache); -extern zend_bool apc_cache_write_lock(apc_cache_t* cache); -extern void apc_cache_write_unlock(apc_cache_t* cache); - -#undef T -#endif - -/* - * 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 - */ diff --git a/apc_compile.c b/apc_compile.c deleted file mode 100644 index 112bb40..0000000 --- a/apc_compile.c +++ /dev/null @@ -1,2591 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | Rasmus Lerdorf | - | Arun C. Murthy | - | Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - 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_compile.c,v 3.87.2.8 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_compile.h" -#include "apc_globals.h" -#include "apc_zend.h" - -#ifndef Z_REFCOUNT_P -#define Z_REFCOUNT_P(pz) (pz)->refcount -#define Z_REFCOUNT_PP(ppz) Z_REFCOUNT_P(*(ppz)) -#endif - -#ifndef Z_SET_REFCOUNT_P -#define Z_SET_REFCOUNT_P(pz, rc) (pz)->refcount = rc -#define Z_SET_REFCOUNT_PP(ppz, rc) Z_SET_REFCOUNT_P(*(ppz), rc) -#endif - -#ifndef Z_ADDREF_P -#define Z_ADDREF_P(pz) (pz)->refcount++ -#define Z_ADDREF_PP(ppz) Z_ADDREF_P(*(ppz)) -#endif - -#ifndef Z_DELREF_P -#define Z_DELREF_P(pz) (pz)->refcount-- -#define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz)) -#endif - -#ifndef Z_ISREF_P -#define Z_ISREF_P(pz) (pz)->is_ref -#define Z_ISREF_PP(ppz) Z_ISREF_P(*(ppz)) -#endif - -#ifndef Z_SET_ISREF_P -#define Z_SET_ISREF_P(pz) (pz)->is_ref = 1 -#define Z_SET_ISREF_PP(ppz) Z_SET_ISREF_P(*(ppz)) -#endif - -#ifndef Z_UNSET_ISREF_P -#define Z_UNSET_ISREF_P(pz) (pz)->is_ref = 0 -#define Z_UNSET_ISREF_PP(ppz) Z_UNSET_ISREF_P(*(ppz)) -#endif - -#ifndef Z_SET_ISREF_TO_P -#define Z_SET_ISREF_TO_P(pz, isref) (pz)->is_ref = isref -#define Z_SET_ISREF_TO_PP(ppz, isref) Z_SET_ISREF_TO_P(*(ppz), isref) -#endif - -typedef void* (*ht_copy_fun_t)(void*, void*, apc_malloc_t, apc_free_t); -typedef void (*ht_free_fun_t)(void*, apc_free_t); -typedef int (*ht_check_copy_fun_t)(Bucket*, va_list); - -#ifdef ZEND_ENGINE_2 -typedef void (*ht_fixup_fun_t)(Bucket*, zend_class_entry*, zend_class_entry*); -#endif - -#define CHECK(p) { if ((p) == NULL) return NULL; } - -/* {{{ internal function declarations */ - -static int is_derived_class(zend_op_array* op_array, const char* key, int key_size); - -static zend_function* my_bitwise_copy_function(zend_function*, zend_function*, apc_malloc_t); - -/* - * The "copy" functions perform deep-copies on a particular data structure - * (passed as the second argument). They also optionally allocate space for - * the destination data structure if the first argument is null. - */ -static zval** my_copy_zval_ptr(zval**, const zval**, apc_malloc_t, apc_free_t); -static zval* my_copy_zval(zval*, const zval*, apc_malloc_t, apc_free_t); -static znode* my_copy_znode(znode*, znode*, apc_malloc_t, apc_free_t); -static zend_op* my_copy_zend_op(zend_op*, zend_op*, apc_malloc_t, apc_free_t); -static zend_function* my_copy_function(zend_function*, zend_function*, apc_malloc_t, apc_free_t); -static zend_function_entry* my_copy_function_entry(zend_function_entry*, const zend_function_entry*, apc_malloc_t, apc_free_t); -static zend_class_entry* my_copy_class_entry(zend_class_entry*, zend_class_entry*, apc_malloc_t, apc_free_t); -static HashTable* my_copy_hashtable_ex(HashTable*, HashTable*, ht_copy_fun_t, ht_free_fun_t, int, apc_malloc_t, apc_free_t, ht_check_copy_fun_t, ...); -#define my_copy_hashtable( dst, src, copy_fn, free_fn, holds_ptr, allocate, deallocate) \ - my_copy_hashtable_ex(dst, src, copy_fn, free_fn, holds_ptr, allocate, deallocate, NULL) -static HashTable* my_copy_static_variables(zend_op_array* src, apc_malloc_t allocate, apc_free_t deallocate); -#ifdef ZEND_ENGINE_2 -static zend_property_info* my_copy_property_info(zend_property_info* dst, zend_property_info* src, apc_malloc_t allocate, apc_free_t deallocate); -static zend_arg_info* my_copy_arg_info_array(zend_arg_info*, const zend_arg_info*, uint, apc_malloc_t, apc_free_t); -static zend_arg_info* my_copy_arg_info(zend_arg_info*, const zend_arg_info*, apc_malloc_t, apc_free_t); -#endif -/* - * The "destroy" functions free the memory associated with a particular data - * structure but do not free the pointer to the data structure. - * - * my_destroy_zval() returns SUCCESS or FAILURE, FAILURE means that - * the zval* has other references elsewhere - */ -static int my_destroy_zval(zval*, apc_free_t); -static void my_destroy_zval_ptr(zval**, apc_free_t); -static void my_destroy_zend_op(zend_op*, apc_free_t); -static void my_destroy_znode(znode*, apc_free_t); -static void my_destroy_function(zend_function*, apc_free_t); -static void my_destroy_function_entry(zend_function_entry*, apc_free_t); -static void my_destroy_class_entry(zend_class_entry*, apc_free_t); -static void my_destroy_hashtable(HashTable*, ht_free_fun_t, apc_free_t); -static void my_destroy_op_array(zend_op_array*, apc_free_t); -#ifdef ZEND_ENGINE_2 -static void my_destroy_property_info(zend_property_info*, apc_free_t); -static void my_destroy_arg_info_array(zend_arg_info* src, uint, apc_free_t); -static void my_destroy_arg_info(zend_arg_info*, apc_free_t); -#endif - -/* - * The "free" functions work exactly like their "destroy" counterparts (see - * above) but also free the pointer to the data structure. - */ -static void my_free_zval_ptr(zval**, apc_free_t); -static void my_free_function(zend_function*, apc_free_t); -static void my_free_hashtable(HashTable*, ht_free_fun_t, apc_free_t); -#ifdef ZEND_ENGINE_2 -static void my_free_property_info(zend_property_info* src, apc_free_t); -static void my_free_arg_info_array(zend_arg_info*, uint, apc_free_t); -static void my_free_arg_info(zend_arg_info*, apc_free_t); -#endif - -/* - * The "fixup" functions need for ZEND_ENGINE_2 - */ -#ifdef ZEND_ENGINE_2 -static void my_fixup_function( Bucket *p, zend_class_entry *src, zend_class_entry *dst ); -static void my_fixup_hashtable( HashTable *ht, ht_fixup_fun_t fixup, zend_class_entry *src, zend_class_entry *dst ); -/* my_fixup_function_for_execution is the same as my_fixup_function - * but named differently for clarity - */ -#define my_fixup_function_for_execution my_fixup_function - -#ifdef ZEND_ENGINE_2_2 -static void my_fixup_property_info( Bucket *p, zend_class_entry *src, zend_class_entry *dst ); -#define my_fixup_property_info_for_execution my_fixup_property_info -#endif - -#endif - -/* - * These functions return "1" if the member/function is - * defined/overridden in the 'current' class and not inherited. - */ -static int my_check_copy_function(Bucket* src, va_list args); -static int my_check_copy_default_property(Bucket* p, va_list args); -#ifdef ZEND_ENGINE_2 -static int my_check_copy_property_info(Bucket* src, va_list args); -static int my_check_copy_static_member(Bucket* src, va_list args); -#endif - -/* }}} */ - -/* {{{ check_op_array_integrity */ -#if 0 -static void check_op_array_integrity(zend_op_array* src) -{ - int i, j; - - /* These sorts of checks really aren't particularly effective, but they - * can provide a welcome sanity check when debugging. Just don't enable - * for production use! */ - - assert(src->refcount != NULL); - assert(src->opcodes != NULL); - assert(src->last > 0); - - for (i = 0; i < src->last; i++) { - zend_op* op = &src->opcodes[i]; - znode* nodes[] = { &op->result, &op->op1, &op->op2 }; - for (j = 0; j < 3; j++) { - assert(nodes[j]->op_type == IS_CONST || - nodes[j]->op_type == IS_VAR || - nodes[j]->op_type == IS_TMP_VAR || - nodes[j]->op_type == IS_UNUSED); - - if (nodes[j]->op_type == IS_CONST) { - int type = nodes[j]->u.constant.type; - assert(type == IS_RESOURCE || - type == IS_BOOL || - type == IS_LONG || - type == IS_DOUBLE || - type == IS_NULL || - type == IS_CONSTANT || - type == IS_STRING || - type == FLAG_IS_BC || - type == IS_ARRAY || - type == IS_CONSTANT_ARRAY || - type == IS_OBJECT); - } - } - } -} -#endif -/* }}} */ - -/* {{{ is_derived_class */ -static int is_derived_class(zend_op_array* op_array, const char* key, int key_size) -{ - int i; - - /* - * Scan the op_array for execution-time class declarations of derived - * classes. If we find one whose key matches our current class key, we - * know the current class is a derived class. - * - * This check is exceedingly inefficient (fortunately it only has to occur - * once, when the source file is first compiled and cached), but the - * compiler should save this information for us -- definitely a candidate - * for a Zend Engine patch. - * - * XXX checking for derived classes provides a minimal (albeit measurable) - * speed up. It may not be worth the added complexity -- considere - * removing this optimization. - */ - - for (i = 0; i < op_array->last; i++) { - zend_op* op = &op_array->opcodes[i]; - -#ifdef ZEND_ENGINE_2 - if (op->opcode == ZEND_DECLARE_CLASS && - op->extended_value == ZEND_DECLARE_INHERITED_CLASS) -#else - if (op->opcode == ZEND_DECLARE_FUNCTION_OR_CLASS && - op->extended_value == ZEND_DECLARE_INHERITED_CLASS) -#endif - { - if (op->op1.u.constant.value.str.len == key_size && - !memcmp(op->op1.u.constant.value.str.val, key, key_size)) - { - return 1; - } - } - } - - return 0; -} -/* }}} */ - -/* {{{ my_bitwise_copy_function */ -static zend_function* my_bitwise_copy_function(zend_function* dst, zend_function* src, apc_malloc_t allocate) -{ - assert(src != NULL); - - if (!dst) { - CHECK(dst = (zend_function*) allocate(sizeof(src[0]))); - } - - /* We only need to do a bitwise copy */ - memcpy(dst, src, sizeof(src[0])); - - return dst; -} -/* }}} */ - -/* {{{ my_copy_zval_ptr */ -static zval** my_copy_zval_ptr(zval** dst, const zval** src, apc_malloc_t allocate, apc_free_t deallocate) -{ - int local_dst_alloc = 0; - zval* dst_new; - - assert(src != NULL); - - if (!dst) { - CHECK(dst = (zval**) allocate(sizeof(zval*))); - local_dst_alloc = 1; - } - -#ifdef ZEND_ENGINE_2_3 - if(!(dst[0] = (zval*) allocate(sizeof(zval_gc_info)))) { - if(local_dst_alloc) deallocate(dst); - return NULL; - } - - if(allocate == apc_php_malloc) { - GC_ZVAL_INIT(dst[0]); - } -#else - if(!(dst[0] = (zval*) allocate(sizeof(zval)))) { - if(local_dst_alloc) deallocate(dst); - return NULL; - } -#endif - if(!(dst_new = my_copy_zval(*dst, *src, allocate, deallocate))) { - if(local_dst_alloc) deallocate(dst); - return NULL; - } - if(dst_new != *dst) { - deallocate(*dst); - *dst = dst_new; - } - - Z_SET_REFCOUNT_PP(dst, Z_REFCOUNT_PP((zval**)src)); - Z_SET_ISREF_TO_PP(dst, Z_ISREF_PP((zval**)src)); - - return dst; -} -/* }}} */ - -/* {{{ my_copy_zval */ -static zval* my_copy_zval(zval* dst, const zval* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - zval **tmp; - TSRMLS_FETCH(); - - assert(dst != NULL); - assert(src != NULL); - - memcpy(dst, src, sizeof(src[0])); - - switch (src->type & ~IS_CONSTANT_INDEX) { - case IS_RESOURCE: - case IS_BOOL: - case IS_LONG: - case IS_DOUBLE: - case IS_NULL: - break; - - case IS_CONSTANT: - case IS_STRING: -#ifndef ZEND_ENGINE_2 - case FLAG_IS_BC: -#endif - if (src->value.str.val) { - CHECK(dst->value.str.val = apc_xmemcpy(src->value.str.val, - src->value.str.len+1, - allocate)); - } - break; - - case IS_ARRAY: - - if(APCG(copied_zvals)) { - if(zend_hash_index_find(APCG(copied_zvals), (ulong)src, (void**)&tmp) == SUCCESS) { - Z_ADDREF_PP(tmp); - return *tmp; - } - - zend_hash_index_update(APCG(copied_zvals), (ulong)src, (void**)&dst, sizeof(zval*), NULL); - } - /* fall through */ - - case IS_CONSTANT_ARRAY: - - CHECK(dst->value.ht = - my_copy_hashtable(NULL, - src->value.ht, - (ht_copy_fun_t) my_copy_zval_ptr, - (ht_free_fun_t) my_free_zval_ptr, - 1, - allocate, deallocate)); - break; - - case IS_OBJECT: -#ifndef ZEND_ENGINE_2 - CHECK(dst->value.obj.ce = - my_copy_class_entry(NULL, src->value.obj.ce, allocate, deallocate)); - - if(!(dst->value.obj.properties = my_copy_hashtable(NULL, - src->value.obj.properties, - (ht_copy_fun_t) my_copy_zval_ptr, - (ht_free_fun_t) my_free_zval_ptr, - 1, - allocate, deallocate))) { - my_destroy_class_entry(dst->value.obj.ce, deallocate); - return NULL; - } - break; -#else - dst->type = IS_NULL; -#endif - break; - - default: - assert(0); - } - - return dst; -} -/* }}} */ - -/* {{{ my_copy_znode */ -static znode* my_copy_znode(znode* dst, znode* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - assert(dst != NULL); - assert(src != NULL); - - memcpy(dst, src, sizeof(src[0])); - -#ifdef IS_CV - assert(dst ->op_type == IS_CONST || - dst ->op_type == IS_VAR || - dst ->op_type == IS_CV || - dst ->op_type == IS_TMP_VAR || - dst ->op_type == IS_UNUSED); -#else - assert(dst ->op_type == IS_CONST || - dst ->op_type == IS_VAR || - dst ->op_type == IS_TMP_VAR || - dst ->op_type == IS_UNUSED); -#endif - - if (src->op_type == IS_CONST) { - if(!my_copy_zval(&dst->u.constant, &src->u.constant, allocate, deallocate)) { - return NULL; - } - } - - return dst; -} -/* }}} */ - -/* {{{ my_copy_zend_op */ -static zend_op* my_copy_zend_op(zend_op* dst, zend_op* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - assert(dst != NULL); - assert(src != NULL); - - memcpy(dst, src, sizeof(src[0])); - - if( my_copy_znode(&dst->result, &src->result, allocate, deallocate) == NULL - || my_copy_znode(&dst->op1, &src->op1, allocate, deallocate) == NULL - || my_copy_znode(&dst->op2, &src->op2, allocate, deallocate) == NULL) - { - return NULL; - } - - return dst; -} -/* }}} */ - -/* {{{ my_copy_function */ -static zend_function* my_copy_function(zend_function* dst, zend_function* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - int local_dst_alloc = 0; - TSRMLS_FETCH(); - - assert(src != NULL); - - if(!dst) local_dst_alloc = 1; - CHECK(dst = my_bitwise_copy_function(dst, src, allocate)); - - switch (src->type) { - case ZEND_INTERNAL_FUNCTION: - case ZEND_OVERLOADED_FUNCTION: - /* shallow copy because op_array is internal */ - dst->op_array = src->op_array; - break; - - case ZEND_USER_FUNCTION: - case ZEND_EVAL_CODE: - if(!apc_copy_op_array(&dst->op_array, - &src->op_array, - allocate, deallocate TSRMLS_CC)) { - if(local_dst_alloc) deallocate(dst); - return NULL; - } - break; - - default: - assert(0); - } -#ifdef ZEND_ENGINE_2 - /* - * op_array bitwise copying overwrites what ever you modified - * before apc_copy_op_array - which is why this code is outside - * my_bitwise_copy_function. - */ - - /* zend_do_inheritance will re-look this up, because the pointers - * in prototype are from a function table of another class. It just - * helps if that one is from EG(class_table). - */ - dst->common.prototype = NULL; - - /* once a method is marked as ZEND_ACC_IMPLEMENTED_ABSTRACT then you - * have to carry around a prototype. Thankfully zend_do_inheritance - * sets this properly as well - */ - dst->common.fn_flags = src->common.fn_flags & (~ZEND_ACC_IMPLEMENTED_ABSTRACT); -#endif - - - return dst; -} -/* }}} */ - -/* {{{ my_copy_function_entry */ -static zend_function_entry* my_copy_function_entry(zend_function_entry* dst, const zend_function_entry* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - int local_dst_alloc = 0; - assert(src != NULL); - - if (!dst) { - CHECK(dst = (zend_function_entry*) allocate(sizeof(src[0]))); - local_dst_alloc = 1; - } - - /* Start with a bitwise copy */ - memcpy(dst, src, sizeof(src[0])); - - dst->fname = NULL; -#ifdef ZEND_ENGINE_2 - dst->arg_info = NULL; -#else - dst->func_arg_types = NULL; -#endif - - if (src->fname) { - if(!(dst->fname = apc_xstrdup(src->fname, allocate))) { - goto cleanup; - } - } - -#ifdef ZEND_ENGINE_2 - if (src->arg_info) { - if(!(dst->arg_info = my_copy_arg_info_array(NULL, - src->arg_info, - src->num_args, - allocate, - deallocate))) { - goto cleanup; - } - } -#else - if (src->func_arg_types) { - if(!(dst->func_arg_types = apc_xmemcpy(src->func_arg_types, - src->func_arg_types[0]+1, - allocate))) { - goto cleanup; - } - } -#endif - - return dst; - -cleanup: - if(dst->fname) deallocate((char*)dst->fname); - if(local_dst_alloc) deallocate(dst); - return NULL; -} -/* }}} */ - -#ifdef ZEND_ENGINE_2 -/* {{{ my_copy_property_info */ -static zend_property_info* my_copy_property_info(zend_property_info* dst, zend_property_info* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - int local_dst_alloc = 0; - - assert(src != NULL); - - if (!dst) { - CHECK(dst = (zend_property_info*) allocate(sizeof(*src))); - local_dst_alloc = 1; - } - - /* Start with a bitwise copy */ - memcpy(dst, src, sizeof(*src)); - - dst->name = NULL; -#if defined(ZEND_ENGINE_2) && PHP_MINOR_VERSION > 0 - dst->doc_comment = NULL; -#endif - - if (src->name) { - /* private members are stored inside property_info as a mangled - * string of the form: - * \0\0\0 - */ - if(!(dst->name = - apc_xmemcpy(src->name, src->name_length+1, allocate))) { - goto cleanup; - } - } - -#if defined(ZEND_ENGINE_2) && PHP_MINOR_VERSION > 0 - if (src->doc_comment) { - if( !(dst->doc_comment = - apc_xmemcpy(src->doc_comment, src->doc_comment_len+1, allocate))) { - goto cleanup; - } - } -#endif - - return dst; - -cleanup: - if(dst->name) deallocate(dst->name); -#if defined(ZEND_ENGINE_2) && PHP_MINOR_VERSION > 0 - if(dst->doc_comment) deallocate(dst->doc_comment); -#endif - if(local_dst_alloc) deallocate(dst); - return NULL; -} -/* }}} */ - -/* {{{ my_copy_property_info_for_execution */ -static zend_property_info* my_copy_property_info_for_execution(zend_property_info* dst, zend_property_info* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - int local_dst_alloc = 0; - - assert(src != NULL); - - if (!dst) { - CHECK(dst = (zend_property_info*) allocate(sizeof(*src))); - local_dst_alloc = 1; - } - - /* We need only a shallow copy */ - memcpy(dst, src, sizeof(*src)); - - return dst; -} -/* }}} */ - -/* {{{ my_copy_arg_info_array */ -static zend_arg_info* my_copy_arg_info_array(zend_arg_info* dst, const zend_arg_info* src, uint num_args, apc_malloc_t allocate, apc_free_t deallocate) -{ - int local_dst_alloc = 0; - int i = 0; - - - if (!dst) { - CHECK(dst = (zend_arg_info*) allocate(sizeof(*src)*num_args)); - local_dst_alloc = 1; - } - - /* Start with a bitwise copy */ - memcpy(dst, src, sizeof(*src)*num_args); - - for(i=0; i < num_args; i++) { - if(!(my_copy_arg_info( &dst[i], &src[i], allocate, deallocate))) { - if(i) my_destroy_arg_info_array(dst, i-1, deallocate); - if(local_dst_alloc) deallocate(dst); - return NULL; - } - } - - return dst; -} -/* }}} */ - -/* {{{ my_copy_arg_info */ -static zend_arg_info* my_copy_arg_info(zend_arg_info* dst, const zend_arg_info* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - int local_dst_alloc = 0; - - assert(src != NULL); - - if (!dst) { - CHECK(dst = (zend_arg_info*) allocate(sizeof(*src))); - local_dst_alloc = 1; - } - - /* Start with a bitwise copy */ - memcpy(dst, src, sizeof(*src)); - - dst->name = NULL; - dst->class_name = NULL; - - if (src->name) { - if(!(dst->name = - apc_xmemcpy(src->name, src->name_len+1, allocate))) { - goto cleanup; - } - } - - if (src->class_name) { - if(!(dst->class_name = - apc_xmemcpy(src->class_name, src->class_name_len+1, allocate))) { - goto cleanup; - } - } - - return dst; - -cleanup: - if(dst->name) deallocate((char*)dst->name); - if(dst->class_name) deallocate((char*)dst->class_name); - if(local_dst_alloc) deallocate(dst); - return NULL; -} -/* }}} */ -#endif - -/* {{{ my_copy_class_entry */ -static zend_class_entry* my_copy_class_entry(zend_class_entry* dst, zend_class_entry* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - int local_dst_alloc = 0; - int i = 0; - - assert(src != NULL); - - if (!dst) { - CHECK(dst = (zend_class_entry*) allocate(sizeof(*src))); - local_dst_alloc = 1; - } - - /* Start with a bitwise copy */ - memcpy(dst, src, sizeof(*src)); - - dst->name = NULL; - dst->builtin_functions = NULL; - memset(&dst->function_table, 0, sizeof(dst->function_table)); - memset(&dst->default_properties, 0, sizeof(dst->default_properties)); -#ifndef ZEND_ENGINE_2 - dst->refcount = NULL; -#else - dst->static_members = NULL; - dst->doc_comment = NULL; - dst->filename = NULL; - memset(&dst->properties_info, 0, sizeof(dst->properties_info)); - memset(&dst->constants_table, 0, sizeof(dst->constants_table)); - memset(&dst->default_static_members, 0, sizeof(dst->default_static_members)); -#endif - - if (src->name) { - if(!(dst->name = apc_xstrdup(src->name, allocate))) { - goto cleanup; - } - } - -#ifndef ZEND_ENGINE_2 - if(!(dst->refcount = apc_xmemcpy(src->refcount, - sizeof(src->refcount[0]), - allocate))) { - goto cleanup; - } -#endif - - if(!(my_copy_hashtable_ex(&dst->function_table, - &src->function_table, - (ht_copy_fun_t) my_copy_function, - (ht_free_fun_t) my_free_function, - 0, - allocate, deallocate, - (ht_check_copy_fun_t) my_check_copy_function, - src))) { - goto cleanup; - } - -#ifdef ZEND_ENGINE_2 - - /* the interfaces are populated at runtime using ADD_INTERFACE */ - dst->interfaces = NULL; - - /* the current count includes inherited interfaces as well, - the real dynamic ones are the first which are zero'd - out in zend_do_end_class_declaration */ - for(i = 0 ; i < src->num_interfaces ; i++) { - if(src->interfaces[i]) - { - dst->num_interfaces = i; - break; - } - } - - /* these will either be set inside my_fixup_hashtable or - * they will be copied out from parent inside zend_do_inheritance - */ - dst->constructor = NULL; - dst->destructor = NULL; - dst->clone = NULL; - dst->__get = NULL; - dst->__set = NULL; - dst->__unset = NULL; - dst->__isset = NULL; - dst->__call = NULL; -#ifdef ZEND_ENGINE_2_2 - dst->__tostring = NULL; -#endif - - /* unset function proxies */ - dst->serialize_func = NULL; - dst->unserialize_func = NULL; - - my_fixup_hashtable(&dst->function_table, (ht_fixup_fun_t)my_fixup_function, src, dst); -#endif - - if(!(my_copy_hashtable_ex(&dst->default_properties, - &src->default_properties, - (ht_copy_fun_t) my_copy_zval_ptr, - (ht_free_fun_t) my_free_zval_ptr, - 1, - allocate,deallocate, - (ht_check_copy_fun_t) my_check_copy_default_property, - src))) { - goto cleanup; - } - -#ifdef ZEND_ENGINE_2 - - if(!(my_copy_hashtable_ex(&dst->properties_info, - &src->properties_info, - (ht_copy_fun_t) my_copy_property_info, - (ht_free_fun_t) my_free_property_info, - 0, - allocate, deallocate, - (ht_check_copy_fun_t) my_check_copy_property_info, - src))) { - goto cleanup; - } - -#ifdef ZEND_ENGINE_2_2 - /* php5.2 introduced a scope attribute for property info */ - my_fixup_hashtable(&dst->properties_info, (ht_fixup_fun_t)my_fixup_property_info_for_execution, src, dst); -#endif - - if(!my_copy_hashtable_ex(&dst->default_static_members, - &src->default_static_members, - (ht_copy_fun_t) my_copy_zval_ptr, - (ht_free_fun_t) my_free_zval_ptr, - 1, - allocate, deallocate, - (ht_check_copy_fun_t) my_check_copy_static_member, - src, - &src->default_static_members)) { - goto cleanup; - } - if(src->static_members != &src->default_static_members) - { - if(!(dst->static_members = my_copy_hashtable_ex(NULL, - src->static_members, - (ht_copy_fun_t) my_copy_zval_ptr, - (ht_free_fun_t) my_free_zval_ptr, - 1, - allocate, deallocate, - (ht_check_copy_fun_t) my_check_copy_static_member, - src, - src->static_members))) { - goto cleanup; - } - } - else - { - dst->static_members = &dst->default_static_members; - } - - if(!(my_copy_hashtable(&dst->constants_table, - &src->constants_table, - (ht_copy_fun_t) my_copy_zval_ptr, - (ht_free_fun_t) my_free_zval_ptr, - 1, - allocate, deallocate))) { - goto cleanup; - } - - if (src->doc_comment) { - if(!(dst->doc_comment = - apc_xmemcpy(src->doc_comment, src->doc_comment_len+1, allocate))) { - goto cleanup; - } - } -#endif - - if (src->builtin_functions) { - int i, n; - - for (n = 0; src->type == ZEND_INTERNAL_CLASS && src->builtin_functions[n].fname != NULL; n++) {} - - if(!(dst->builtin_functions = - (zend_function_entry*) - allocate((n + 1) * sizeof(zend_function_entry)))) { - goto cleanup; - } - - - for (i = 0; i < n; i++) { - if(!my_copy_function_entry((zend_function_entry*)(&dst->builtin_functions[i]), - &src->builtin_functions[i], - allocate, deallocate)) { - int ii; - - for(ii=i-1; ii>=0; ii--) my_destroy_function_entry((zend_function_entry*)(&dst->builtin_functions[ii]), deallocate); - goto cleanup; - } - } - *(char**)&(dst->builtin_functions[n].fname) = NULL; - } - -#ifdef ZEND_ENGINE_2 - if (src->filename) { - if(!(dst->filename = apc_xstrdup(src->filename, allocate))) { - goto cleanup; - } - } -#endif - - return dst; - - -cleanup: - if(dst->name) deallocate(dst->name); -#ifdef ZEND_ENGINE_2 - if(dst->doc_comment) deallocate(dst->doc_comment); - if(dst->filename) deallocate(dst->filename); -#else - if(dst->refcount) deallocate(dst->refcount); -#endif - - if(dst->builtin_functions) deallocate((zend_function_entry*)dst->builtin_functions); - if(dst->function_table.arBuckets) my_destroy_hashtable(&dst->function_table, (ht_free_fun_t) my_free_function, deallocate); - if(dst->default_properties.arBuckets) my_destroy_hashtable(&dst->default_properties, (ht_free_fun_t) my_free_zval_ptr, deallocate); - -#ifdef ZEND_ENGINE_2 - if(dst->properties_info.arBuckets) my_destroy_hashtable(&dst->properties_info, (ht_free_fun_t) my_free_property_info, deallocate); - if(dst->default_static_members.arBuckets) - { - my_destroy_hashtable(&dst->default_static_members, (ht_free_fun_t) my_free_zval_ptr, deallocate); - } - if(dst->static_members && dst->static_members != &(dst->default_static_members)) - { - my_destroy_hashtable(dst->static_members, (ht_free_fun_t) my_free_zval_ptr, deallocate); - deallocate(dst->static_members); - } - if(dst->constants_table.arBuckets) my_destroy_hashtable(&dst->constants_table, (ht_free_fun_t) my_free_zval_ptr, deallocate); -#endif - if(local_dst_alloc) deallocate(dst); - - return NULL; -} -/* }}} */ - -/* {{{ my_copy_hashtable */ -static HashTable* my_copy_hashtable_ex(HashTable* dst, - HashTable* src, - ht_copy_fun_t copy_fn, - ht_free_fun_t free_fn, - int holds_ptrs, - apc_malloc_t allocate, - apc_free_t deallocate, - ht_check_copy_fun_t check_fn, - ...) -{ - Bucket* curr = NULL; - Bucket* prev = NULL; - Bucket* newp = NULL; - int first = 1; - int local_dst_alloc = 0; - int index = 0; - - assert(src != NULL); - - if (!dst) { - CHECK(dst = (HashTable*) allocate(sizeof(src[0]))); - local_dst_alloc = 1; - } - - memcpy(dst, src, sizeof(src[0])); - - /* allocate buckets for the new hashtable */ - if(!(dst->arBuckets = allocate(dst->nTableSize * sizeof(Bucket*)))) { - if(local_dst_alloc) deallocate(dst); - return NULL; - } - - 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--; - continue; - } - - va_end(args); - } - - /* create a copy of the bucket 'curr' */ - if(!(newp = - (Bucket*) apc_xmemcpy(curr, - sizeof(Bucket) + curr->nKeyLength - 1, - allocate))) { - goto cleanup; - } - - /* 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 */ - if(!(newp->pData = copy_fn(NULL, curr->pData, allocate, deallocate))) { - goto cleanup; - } - - 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; - - return dst; - - cleanup: - for(index = 0; index < dst->nTableSize; index++) - { - curr = dst->arBuckets[index]; - while(curr != NULL) - { - Bucket * tmp = curr; - if(curr->pData && free_fn) - { - free_fn(curr->pData, deallocate); - } - curr = curr->pNext; - deallocate(tmp); - } - } - deallocate(dst->arBuckets); - if(local_dst_alloc) deallocate(dst); - else dst->arBuckets = NULL; - - return NULL; -} -/* }}} */ - -/* {{{ my_copy_static_variables */ -static HashTable* my_copy_static_variables(zend_op_array* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - if (src->static_variables == NULL) { - return NULL; - } - - return my_copy_hashtable(NULL, - src->static_variables, - (ht_copy_fun_t) my_copy_zval_ptr, - (ht_free_fun_t) my_free_zval_ptr, - 1, - allocate, deallocate); -} -/* }}} */ - -/* {{{ apc_copy_zval */ -zval* apc_copy_zval(zval* dst, const zval* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - int local_dst_alloc = 0; - assert(src != NULL); - - if (!dst) { -#ifdef ZEND_ENGINE_2_3 - CHECK(dst = (zval*) allocate(sizeof(zval_gc_info))); - - if(allocate == apc_php_malloc) { - GC_ZVAL_INIT(dst); - } -#else - CHECK(dst = (zval*) allocate(sizeof(zval))); -#endif - local_dst_alloc = 1; - } - - dst = my_copy_zval(dst, src, allocate, deallocate); - if(!dst) { - if(local_dst_alloc) deallocate(dst); - return NULL; - } - return dst; -} -/* }}} */ - -#ifdef ZEND_ENGINE_2 -/* {{{ apc_fixup_op_array_jumps */ -static void apc_fixup_op_array_jumps(zend_op_array *dst, zend_op_array *src ) -{ - int i; - - for (i=0; i < dst->last; ++i) { - zend_op *zo = &(dst->opcodes[i]); - /*convert opline number to jump address*/ - switch (zo->opcode) { - case ZEND_JMP: - /*Note: if src->opcodes != dst->opcodes then we need to the opline according to src*/ - zo->op1.u.jmp_addr = dst->opcodes + (zo->op1.u.jmp_addr - src->opcodes); - break; - case ZEND_JMPZ: - case ZEND_JMPNZ: - case ZEND_JMPZ_EX: - case ZEND_JMPNZ_EX: - zo->op2.u.jmp_addr = dst->opcodes + (zo->op2.u.jmp_addr - src->opcodes); - break; - default: - break; - } - } -} -/* }}} */ -#endif - -/* {{{ apc_copy_op_array */ -zend_op_array* apc_copy_op_array(zend_op_array* dst, zend_op_array* src, apc_malloc_t allocate, apc_free_t deallocate TSRMLS_DC) -{ - int i; - int local_dst_alloc = 0; - apc_fileinfo_t fileinfo; - char canon_path[MAXPATHLEN]; - char *fullpath = NULL; -#ifdef ZEND_ENGINE_2 - apc_opflags_t * flags = NULL; -#endif - - assert(src != NULL); - - if (!dst) { - CHECK(dst = (zend_op_array*) allocate(sizeof(src[0]))); - local_dst_alloc = 1; - } - - if(APCG(apc_optimize_function)) { - APCG(apc_optimize_function)(src TSRMLS_CC); - } - - /* start with a bitwise copy of the array */ - memcpy(dst, src, sizeof(src[0])); - - dst->function_name = NULL; - dst->filename = NULL; - dst->refcount = NULL; - dst->opcodes = NULL; - dst->brk_cont_array = NULL; - dst->static_variables = NULL; -#ifdef ZEND_ENGINE_2 - dst->try_catch_array = NULL; - dst->arg_info = NULL; - dst->doc_comment = NULL; -#else - dst->arg_types = NULL; -#endif -#ifdef ZEND_ENGINE_2_1 - dst->vars = NULL; -#endif - - /* copy the arg types array (if set) */ -#ifdef ZEND_ENGINE_2 - if (src->arg_info) { - if(!(dst->arg_info = my_copy_arg_info_array(NULL, - src->arg_info, - src->num_args, - allocate, - deallocate))) { - goto cleanup; - } - } -#else - if (src->arg_types) { - if(!(dst->arg_types = apc_xmemcpy(src->arg_types, - sizeof(src->arg_types[0]) * (src->arg_types[0]+1), - allocate))) { - goto cleanup; - } - } -#endif - - if (src->function_name) { - if(!(dst->function_name = apc_xstrdup(src->function_name, allocate))) { - goto cleanup; - } - } - if (src->filename) { - if(!(dst->filename = apc_xstrdup(src->filename, allocate))) { - goto cleanup; - } - } - - if(!(dst->refcount = apc_xmemcpy(src->refcount, - sizeof(src->refcount[0]), - allocate))) { - goto cleanup; - } - - /* deep-copy the opcodes */ - if(!(dst->opcodes = (zend_op*) allocate(sizeof(zend_op) * src->last))) { - goto cleanup; - } - -#ifdef ZEND_ENGINE_2 - if(APCG(reserved_offset) != -1) { - /* Insanity alert: the void* pointer is cast into an apc_opflags_t - * struct. apc_zend_init() checks to ensure that it fits in a void* */ - flags = (apc_opflags_t*) & (dst->reserved[APCG(reserved_offset)]); - memset(flags, 0, sizeof(apc_opflags_t)); - /* assert(sizeof(apc_opflags_t) < sizeof(dst->reserved)); */ - } -#endif - - for (i = 0; i < src->last; i++) { -#ifdef ZEND_ENGINE_2 - zend_op *zo = &(src->opcodes[i]); - /* a lot of files are merely constant arrays with no jumps */ - switch (zo->opcode) { - case ZEND_JMP: - case ZEND_JMPZ: - case ZEND_JMPNZ: - case ZEND_JMPZ_EX: - case ZEND_JMPNZ_EX: - if(flags != NULL) { - flags->has_jumps = 1; - } - break; -#ifdef ZEND_ENGINE_2 - /* auto_globals_jit was not in php-4.3.* */ - case ZEND_FETCH_R: - case ZEND_FETCH_W: - case ZEND_FETCH_IS: - case ZEND_FETCH_FUNC_ARG: - if(PG(auto_globals_jit) && flags != NULL) - { - /* The fetch is only required if auto_globals_jit=1 */ - if(zo->op2.u.EA.type == ZEND_FETCH_GLOBAL && - zo->op1.op_type == IS_CONST && - zo->op1.u.constant.type == IS_STRING) { - znode * varname = &zo->op1; - if (varname->u.constant.value.str.val[0] == '_') { -#define SET_IF_AUTOGLOBAL(member) \ - if(!strcmp(varname->u.constant.value.str.val, #member)) \ - flags->member = 1 /* no ';' here */ - SET_IF_AUTOGLOBAL(_GET); - else SET_IF_AUTOGLOBAL(_POST); - else SET_IF_AUTOGLOBAL(_COOKIE); - else SET_IF_AUTOGLOBAL(_SERVER); - else SET_IF_AUTOGLOBAL(_ENV); - else SET_IF_AUTOGLOBAL(_FILES); - else SET_IF_AUTOGLOBAL(_REQUEST); - else if(zend_is_auto_global( - varname->u.constant.value.str.val, - varname->u.constant.value.str.len - TSRMLS_CC)) - { - flags->unknown_global = 1; - } - } - } - } - break; -#endif - case ZEND_RECV_INIT: - if(zo->op2.op_type == IS_CONST && - zo->op2.u.constant.type == IS_CONSTANT_ARRAY) { - if(flags != NULL) { - flags->deep_copy = 1; - } - } - break; - default: - if((zo->op1.op_type == IS_CONST && - zo->op1.u.constant.type == IS_CONSTANT_ARRAY) || - (zo->op2.op_type == IS_CONST && - zo->op2.u.constant.type == IS_CONSTANT_ARRAY)) { - if(flags != NULL) { - flags->deep_copy = 1; - } - } - break; - } -#endif - if(!(my_copy_zend_op(dst->opcodes+i, src->opcodes+i, allocate, deallocate))) { - int ii; - for(ii = i-1; ii>=0; ii--) { - my_destroy_zend_op(dst->opcodes+ii, deallocate); - } - goto cleanup; - } -#ifdef ZEND_ENGINE_2 -/* This code breaks apc's rule#1 - cache what you compile */ - if(APCG(fpstat)==0) { - if((zo->opcode == ZEND_INCLUDE_OR_EVAL) && - (zo->op1.op_type == IS_CONST && zo->op1.u.constant.type == IS_STRING)) { - /* constant includes */ - if(!IS_ABSOLUTE_PATH(Z_STRVAL_P(&zo->op1.u.constant),Z_STRLEN_P(&zo->op1.u.constant))) { - if (apc_search_paths(Z_STRVAL_P(&zo->op1.u.constant), PG(include_path), &fileinfo) == 0) { - if((fullpath = realpath(fileinfo.fullpath, canon_path))) { - /* everything has to go through a realpath() */ - zend_op *dzo = &(dst->opcodes[i]); - deallocate(dzo->op1.u.constant.value.str.val); - dzo->op1.u.constant.value.str.len = strlen(fullpath); - dzo->op1.u.constant.value.str.val = apc_xstrdup(fullpath, allocate); - } - } - } - } - } -#endif - } - -#ifdef ZEND_ENGINE_2 - if(flags == NULL || flags->has_jumps) { - apc_fixup_op_array_jumps(dst,src); - } -#endif - - /* copy the break-continue array */ - if (src->brk_cont_array) { - if(!(dst->brk_cont_array = - apc_xmemcpy(src->brk_cont_array, - sizeof(src->brk_cont_array[0]) * src->last_brk_cont, - allocate))) { - goto cleanup_opcodes; - } - } - - /* copy the table of static variables */ - if (src->static_variables) { - if(!(dst->static_variables = my_copy_static_variables(src, allocate, deallocate))) { - goto cleanup_opcodes; - } - } - -#ifdef ZEND_ENGINE_2 - if (src->try_catch_array) { - if(!(dst->try_catch_array = - apc_xmemcpy(src->try_catch_array, - sizeof(src->try_catch_array[0]) * src->last_try_catch, - allocate))) { - goto cleanup_opcodes; - } - } -#endif - -#ifdef ZEND_ENGINE_2_1 /* PHP 5.1 */ - if (src->vars) { - if(!(dst->vars = apc_xmemcpy(src->vars, - sizeof(src->vars[0]) * src->last_var, - allocate))) { - goto cleanup_opcodes; - } - - for(i = 0; i < src->last_var; i++) dst->vars[i].name = NULL; - - for(i = 0; i < src->last_var; i++) { - if(!(dst->vars[i].name = apc_xmemcpy(src->vars[i].name, - src->vars[i].name_len + 1, - allocate))) { - dst->last_var = i; - goto cleanup_opcodes; - } - } - } -#endif - -#ifdef ZEND_ENGINE_2 - if (src->doc_comment) { - if (!(dst->doc_comment - = apc_xmemcpy(src->doc_comment, src->doc_comment_len+1, allocate))) { - goto cleanup_opcodes; - } - } -#endif - - return dst; - -cleanup_opcodes: - if(dst->opcodes) { - for(i=0; i < src->last; i++) my_destroy_zend_op(dst->opcodes+i, deallocate); - } -cleanup: - if(dst->function_name) deallocate(dst->function_name); - if(dst->refcount) deallocate(dst->refcount); - if(dst->filename) deallocate(dst->filename); -#ifdef ZEND_ENGINE_2 - if(dst->arg_info) my_free_arg_info_array(dst->arg_info, dst->num_args, deallocate); - if(dst->try_catch_array) deallocate(dst->try_catch_array); - if(dst->doc_comment) deallocate(dst->doc_comment); -#else - if(dst->arg_types) deallocate(dst->arg_types); -#endif - if(dst->opcodes) deallocate(dst->opcodes); - if(dst->brk_cont_array) deallocate(dst->brk_cont_array); - if(dst->static_variables) my_free_hashtable(dst->static_variables, (ht_free_fun_t)my_free_zval_ptr, (apc_free_t)deallocate); -#ifdef ZEND_ENGINE_2_1 - if (dst->vars) { - for(i=0; i < dst->last_var; i++) { - if(dst->vars[i].name) deallocate(dst->vars[i].name); - } - deallocate(dst->vars); - } -#endif - if(local_dst_alloc) deallocate(dst); - return NULL; -} -/* }}} */ - -/* {{{ apc_copy_new_functions */ -apc_function_t* apc_copy_new_functions(int old_count, apc_malloc_t allocate, apc_free_t deallocate TSRMLS_DC) -{ - apc_function_t* array; - int new_count; /* number of new functions in table */ - int i; - - new_count = zend_hash_num_elements(CG(function_table)) - old_count; - assert(new_count >= 0); - - CHECK(array = - (apc_function_t*) - allocate(sizeof(apc_function_t) * (new_count+1))); - - if (new_count == 0) { - array[0].function = NULL; - return array; - } - - /* Skip the first `old_count` functions in the table */ - zend_hash_internal_pointer_reset(CG(function_table)); - for (i = 0; i < old_count; i++) { - zend_hash_move_forward(CG(function_table)); - } - - /* Add the next `new_count` functions to our array */ - for (i = 0; i < new_count; i++) { - char* key; - uint key_size; - zend_function* fun; - - zend_hash_get_current_key_ex(CG(function_table), - &key, - &key_size, - NULL, - 0, - NULL); - - zend_hash_get_current_data(CG(function_table), (void**) &fun); - - if(!(array[i].name = apc_xmemcpy(key, (int) key_size, allocate))) { - int ii; - for(ii=i-1; ii>=0; ii--) { - deallocate(array[ii].name); - my_free_function(array[ii].function, deallocate); - } - deallocate(array); - return NULL; - } - array[i].name_len = (int) key_size-1; - if(!(array[i].function = my_copy_function(NULL, fun, allocate, deallocate))) { - int ii; - deallocate(array[i].name); - for(ii=i-1; ii>=0; ii--) { - deallocate(array[ii].name); - my_free_function(array[ii].function, deallocate); - } - deallocate(array); - return NULL; - } - zend_hash_move_forward(CG(function_table)); - } - - array[i].function = NULL; - return array; -} -/* }}} */ - -/* {{{ apc_copy_new_classes */ -apc_class_t* apc_copy_new_classes(zend_op_array* op_array, int old_count, apc_malloc_t allocate, apc_free_t deallocate TSRMLS_DC) -{ - apc_class_t* array; - int new_count; /* number of new classes in table */ - int i; - - new_count = zend_hash_num_elements(CG(class_table)) - old_count; - assert(new_count >= 0); - - CHECK(array = - (apc_class_t*) - allocate(sizeof(apc_class_t)*(new_count+1))); - - if (new_count == 0) { - array[0].class_entry = NULL; - return array; - } - - /* Skip the first `old_count` classes in the table */ - zend_hash_internal_pointer_reset(CG(class_table)); - for (i = 0; i < old_count; i++) { - zend_hash_move_forward(CG(class_table)); - } - - /* Add the next `new_count` classes to our array */ - for (i = 0; i < new_count; i++) { - char* key; - uint key_size; - zend_class_entry* elem = NULL; - - array[i].class_entry = NULL; - - zend_hash_get_current_key_ex(CG(class_table), - &key, - &key_size, - NULL, - 0, - NULL); - - zend_hash_get_current_data(CG(class_table), (void**) &elem); - - -#ifdef ZEND_ENGINE_2 - elem = *((zend_class_entry**)elem); -#endif - - if(!(array[i].name = apc_xmemcpy(key, (int) key_size, allocate))) { - int ii; - - for(ii=i-1; ii>=0; ii--) { - deallocate(array[ii].name); - my_destroy_class_entry(array[ii].class_entry, deallocate); - deallocate(array[ii].class_entry); - } - deallocate(array); - return NULL; - } - array[i].name_len = (int) key_size-1; - if(!(array[i].class_entry = my_copy_class_entry(NULL, elem, allocate, deallocate))) { - int ii; - - deallocate(array[i].name); - for(ii=i-1; ii>=0; ii--) { - deallocate(array[ii].name); - my_destroy_class_entry(array[ii].class_entry, deallocate); - deallocate(array[ii].class_entry); - } - deallocate(array); - return NULL; - } - - /* - * If the class has a pointer to its parent class, save the parent - * name so that we can enable compile-time inheritance when we reload - * the child class; otherwise, set the parent name to null and scan - * the op_array to determine if this class inherits from some base - * class at execution-time. - */ - - if (elem->parent) { - if(!(array[i].parent_name = - apc_xstrdup(elem->parent->name, allocate))) { - int ii; - - for(ii=i; ii>=0; ii--) { - deallocate(array[ii].name); - my_destroy_class_entry(array[ii].class_entry, deallocate); - deallocate(array[ii].class_entry); - if(ii==i) continue; - if(array[ii].parent_name) deallocate(array[ii].parent_name); - } - deallocate(array); - return NULL; - } - array[i].is_derived = 1; - } - else { - array[i].parent_name = NULL; - array[i].is_derived = is_derived_class(op_array, key, key_size); - } - - zend_hash_move_forward(CG(class_table)); - } - - array[i].class_entry = NULL; - return array; -} -/* }}} */ - -/* {{{ my_destroy_zval_ptr */ -static void my_destroy_zval_ptr(zval** src, apc_free_t deallocate) -{ - assert(src != NULL); - if(my_destroy_zval(src[0], deallocate) == SUCCESS) { - deallocate(src[0]); - } -} -/* }}} */ - -/* {{{ my_destroy_zval */ -static int my_destroy_zval(zval* src, apc_free_t deallocate) -{ - zval **tmp; - TSRMLS_FETCH(); - - switch (src->type & ~IS_CONSTANT_INDEX) { - case IS_RESOURCE: - case IS_BOOL: - case IS_LONG: - case IS_DOUBLE: - case IS_NULL: - break; - - case IS_CONSTANT: - case IS_STRING: -#ifndef ZEND_ENGINE_2 - case FLAG_IS_BC: -#endif - deallocate(src->value.str.val); - break; - - case IS_ARRAY: - - /* Maintain a list of zvals we've copied to properly handle recursive structures */ - if(APCG(copied_zvals)) { - if(zend_hash_index_find(APCG(copied_zvals), (ulong)src, (void**)&tmp) == SUCCESS) { - Z_DELREF_PP(tmp); - return FAILURE; - } - zend_hash_index_update(APCG(copied_zvals), (ulong)src, (void**)&src, sizeof(zval*), NULL); - } - /* fall through */ - - case IS_CONSTANT_ARRAY: - my_free_hashtable(src->value.ht, - (ht_free_fun_t) my_free_zval_ptr, - deallocate); - break; - - case IS_OBJECT: -#ifndef ZEND_ENGINE_2 - my_destroy_class_entry(src->value.obj.ce, deallocate); - deallocate(src->value.obj.ce); - my_free_hashtable(src->value.obj.properties, - (ht_free_fun_t) my_free_zval_ptr, - deallocate); -#endif - break; - - default: - assert(0); - } - - return SUCCESS; -} -/* }}} */ - -/* {{{ my_destroy_znode */ -static void my_destroy_znode(znode* src, apc_free_t deallocate) -{ - if (src->op_type == IS_CONST) { - my_destroy_zval(&src->u.constant, deallocate); - } -} -/* }}} */ - -/* {{{ my_destroy_zend_op */ -static void my_destroy_zend_op(zend_op* src, apc_free_t deallocate) -{ - my_destroy_znode(&src->result, deallocate); - my_destroy_znode(&src->op1, deallocate); - my_destroy_znode(&src->op2, deallocate); -} -/* }}} */ - -/* {{{ my_destroy_function */ -static void my_destroy_function(zend_function* src, apc_free_t deallocate) -{ - assert(src != NULL); - - switch (src->type) { - case ZEND_INTERNAL_FUNCTION: - case ZEND_OVERLOADED_FUNCTION: - break; - - case ZEND_USER_FUNCTION: - case ZEND_EVAL_CODE: - my_destroy_op_array(&src->op_array, deallocate); - break; - - default: - assert(0); - } -} -/* }}} */ - -/* {{{ my_destroy_function_entry */ -static void my_destroy_function_entry(zend_function_entry* src, apc_free_t deallocate) -{ - assert(src != NULL); - - deallocate((char*)src->fname); -#ifdef ZEND_ENGINE_2 - if (src->arg_info) { - my_free_arg_info_array((zend_arg_info*)src->arg_info, src->num_args, deallocate); - } -#else - if (src->func_arg_types) { - deallocate(src->func_arg_types); - } -#endif -} -/* }}} */ - -#ifdef ZEND_ENGINE_2 -/* {{{ my_destroy_property_info*/ -static void my_destroy_property_info(zend_property_info* src, apc_free_t deallocate) -{ - assert(src != NULL); - - deallocate(src->name); -#if defined(ZEND_ENGINE_2) && PHP_MINOR_VERSION > 0 - if(src->doc_comment) deallocate(src->doc_comment); -#endif -} -/* }}} */ - -/* {{{ my_destroy_arg_info_array */ -static void my_destroy_arg_info_array(zend_arg_info* src, uint num_args, apc_free_t deallocate) -{ - int i = 0; - - assert(src != NULL); - - for(i=0; i < num_args; i++) { - my_destroy_arg_info(&src[i], deallocate); - } -} -/* }}} */ - -/* {{{ my_destroy_arg_info */ -static void my_destroy_arg_info(zend_arg_info* src, apc_free_t deallocate) -{ - assert(src != NULL); - - deallocate((char*)src->name); - deallocate((char*)src->class_name); -} -/* }}} */ -#endif - -/* {{{ my_destroy_class_entry */ -static void my_destroy_class_entry(zend_class_entry* src, apc_free_t deallocate) -{ - uint i; - - assert(src != NULL); - - deallocate(src->name); -#ifndef ZEND_ENGINE_2 - deallocate(src->refcount); -#else - if(src->doc_comment) deallocate(src->doc_comment); - if(src->filename) deallocate(src->filename); -#endif - - my_destroy_hashtable(&src->function_table, - (ht_free_fun_t) my_free_function, - deallocate); - - my_destroy_hashtable(&src->default_properties, - (ht_free_fun_t) my_free_zval_ptr, - deallocate); - -#ifdef ZEND_ENGINE_2 - my_destroy_hashtable(&src->properties_info, - (ht_free_fun_t) my_free_property_info, - deallocate); - if(src->static_members) - { - my_destroy_hashtable(src->static_members, - (ht_free_fun_t) my_free_zval_ptr, - deallocate); - if(src->static_members != &(src->default_static_members)) - { - deallocate(src->static_members); - } - } - - my_destroy_hashtable(&src->constants_table, - (ht_free_fun_t) my_free_zval_ptr, - deallocate); -#endif - - if (src->builtin_functions) { - for (i = 0; src->builtin_functions[i].fname != NULL; i++) { - my_destroy_function_entry((zend_function_entry*)(&src->builtin_functions[i]), deallocate); - } - deallocate((zend_function_entry*)src->builtin_functions); - } -} -/* }}} */ - -/* {{{ my_destroy_hashtable */ -static void my_destroy_hashtable(HashTable* src, ht_free_fun_t free_fn, apc_free_t deallocate) -{ - int i; - - assert(src != NULL); - - for (i = 0; i < src->nTableSize; i++) { - Bucket* p = src->arBuckets[i]; - while (p != NULL) { - Bucket* q = p; - p = p->pNext; - free_fn(q->pData, deallocate); - deallocate(q); - } - } - - deallocate(src->arBuckets); -} -/* }}} */ - -/* {{{ my_destroy_op_array */ -static void my_destroy_op_array(zend_op_array* src, apc_free_t deallocate) -{ - int i; - - assert(src != NULL); - -#ifdef ZEND_ENGINE_2 - if (src->arg_info) { - my_free_arg_info_array(src->arg_info, src->num_args, deallocate); - } -#else - if (src->arg_types) { - deallocate(src->arg_types); - } -#endif - - deallocate(src->function_name); - deallocate(src->filename); - deallocate(src->refcount); - - for (i = 0; i < src->last; i++) { - my_destroy_zend_op(src->opcodes + i, deallocate); - } - deallocate(src->opcodes); - - if (src->brk_cont_array) { - deallocate(src->brk_cont_array); - } - - if (src->static_variables) { - my_free_hashtable(src->static_variables, - (ht_free_fun_t) my_free_zval_ptr, - deallocate); - } - -#ifdef ZEND_ENGINE_2_1 - if (src->vars) { - for(i=0; i < src->last_var; i++) { - if(src->vars[i].name) deallocate(src->vars[i].name); - } - deallocate(src->vars); - } -#endif -#ifdef ZEND_ENGINE_2 - if(src->try_catch_array) { - deallocate(src->try_catch_array); - } - if (src->doc_comment) { - deallocate(src->doc_comment); - } -#endif -} -/* }}} */ - -/* {{{ my_free_zval_ptr */ -static void my_free_zval_ptr(zval** src, apc_free_t deallocate) -{ - my_destroy_zval_ptr(src, deallocate); - deallocate(src); -} -/* }}} */ - -#ifdef ZEND_ENGINE_2 -/* {{{ my_free_property_info */ -static void my_free_property_info(zend_property_info* src, apc_free_t deallocate) -{ - my_destroy_property_info(src, deallocate); - deallocate(src); -} -/* }}} */ - -/* {{{ my_free_arg_info_array */ -static void my_free_arg_info_array(zend_arg_info* src, uint num_args, apc_free_t deallocate) -{ - my_destroy_arg_info_array(src, num_args, deallocate); - deallocate(src); -} -/* }}} */ - -/* {{{ my_free_arg_info */ -static void my_free_arg_info(zend_arg_info* src, apc_free_t deallocate) -{ - my_destroy_arg_info(src, deallocate); - deallocate(src); -} -/* }}} */ -#endif - -/* {{{ my_free_function */ -static void my_free_function(zend_function* src, apc_free_t deallocate) -{ - my_destroy_function(src, deallocate); - deallocate(src); -} -/* }}} */ - -/* {{{ my_free_hashtable */ -static void my_free_hashtable(HashTable* src, ht_free_fun_t free_fn, apc_free_t deallocate) -{ - my_destroy_hashtable(src, free_fn, deallocate); - deallocate(src); -} -/* }}} */ - -/* {{{ apc_free_op_array */ -void apc_free_op_array(zend_op_array* src, apc_free_t deallocate) -{ - if (src != NULL) { - my_destroy_op_array(src, deallocate); - deallocate(src); - } -} -/* }}} */ - -/* {{{ apc_free_functions */ -void apc_free_functions(apc_function_t* src, apc_free_t deallocate) -{ - int i; - - if (src != NULL) { - for (i = 0; src[i].function != NULL; i++) { - deallocate(src[i].name); - my_destroy_function(src[i].function, deallocate); - deallocate(src[i].function); - } - deallocate(src); - } -} -/* }}} */ - -/* {{{ apc_free_classes */ -void apc_free_classes(apc_class_t* src, apc_free_t deallocate) -{ - int i; - - if (src != NULL) { - for (i = 0; src[i].class_entry != NULL; i++) { - deallocate(src[i].name); - deallocate(src[i].parent_name); - my_destroy_class_entry(src[i].class_entry, deallocate); - deallocate(src[i].class_entry); - } - deallocate(src); - } -} -/* }}} */ - -/* {{{ apc_free_zval */ -void apc_free_zval(zval* src, apc_free_t deallocate) -{ - if (src != NULL) { - if(my_destroy_zval(src, deallocate) == SUCCESS) { - deallocate(src); - } - } -} -/* }}} */ - - -/* Used only by my_prepare_op_array_for_execution */ -#define APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION() \ - /* The fetch is only required if auto_globals_jit=1 */ \ - if(zo->op2.u.EA.type == ZEND_FETCH_GLOBAL && \ - zo->op1.op_type == IS_CONST && \ - zo->op1.u.constant.type == IS_STRING && \ - zo->op1.u.constant.value.str.val[0] == '_') { \ - \ - znode* varname = &zo->op1; \ - (void)zend_is_auto_global(varname->u.constant.value.str.val, \ - varname->u.constant.value.str.len \ - TSRMLS_CC); \ - } \ - -/* {{{ my_prepare_op_array_for_execution */ -static int my_prepare_op_array_for_execution(zend_op_array* dst, zend_op_array* src TSRMLS_DC) -{ - /* combine my_fetch_global_vars and my_copy_data_exceptions. - * - Pre-fetch superglobals which would've been pre-fetched in parse phase. - * - If the opcode stream contain mutable data, ensure a copy. - * - Fixup array jumps in the same loop. - */ - int i=src->last; - zend_op *zo; - zend_op *dzo; -#ifdef ZEND_ENGINE_2 - apc_opflags_t * flags = APCG(reserved_offset) != -1 ? - (apc_opflags_t*) & (src->reserved[APCG(reserved_offset)]) : NULL; - int needcopy = flags ? flags->deep_copy : 1; - /* auto_globals_jit was not in php4 */ - int do_prepare_fetch_global = PG(auto_globals_jit) && (flags == NULL || flags->unknown_global); - -#define FETCH_AUTOGLOBAL(member) do { \ - if(flags && flags->member == 1) { \ - zend_is_auto_global(#member,\ - (sizeof(#member) - 1)\ - TSRMLS_CC);\ - } \ -}while(0); - - FETCH_AUTOGLOBAL(_GET); - FETCH_AUTOGLOBAL(_POST); - FETCH_AUTOGLOBAL(_COOKIE); - FETCH_AUTOGLOBAL(_SERVER); - FETCH_AUTOGLOBAL(_ENV); - FETCH_AUTOGLOBAL(_FILES); - FETCH_AUTOGLOBAL(_REQUEST); - -#else - int needcopy = 0; - int do_prepare_fetch_global = 0; - int j = 0; - - for(j = 0; j < src->last; j++) { - zo = &src->opcodes[j]; - - if( ((zo->op1.op_type == IS_CONST && - zo->op1.u.constant.type == IS_CONSTANT_ARRAY)) || - ((zo->op2.op_type == IS_CONST && - zo->op2.u.constant.type == IS_CONSTANT_ARRAY))) { - needcopy = 1; - } - } -#endif - - if(needcopy) { - - dst->opcodes = (zend_op*) apc_xmemcpy(src->opcodes, - sizeof(zend_op) * src->last, - apc_php_malloc); - zo = src->opcodes; - dzo = dst->opcodes; - while(i > 0) { - - if( ((zo->op1.op_type == IS_CONST && - zo->op1.u.constant.type == IS_CONSTANT_ARRAY)) || - ((zo->op2.op_type == IS_CONST && - zo->op2.u.constant.type == IS_CONSTANT_ARRAY))) { - - if(!(my_copy_zend_op(dzo, zo, apc_php_malloc, apc_php_free))) { - assert(0); /* emalloc failed or a bad constant array */ - } - } - -#ifdef ZEND_ENGINE_2 - switch(zo->opcode) { - case ZEND_JMP: - dzo->op1.u.jmp_addr = dst->opcodes + - (zo->op1.u.jmp_addr - src->opcodes); - break; - case ZEND_JMPZ: - case ZEND_JMPNZ: - case ZEND_JMPZ_EX: - case ZEND_JMPNZ_EX: - dzo->op2.u.jmp_addr = dst->opcodes + - (zo->op2.u.jmp_addr - src->opcodes); - break; - case ZEND_FETCH_R: - case ZEND_FETCH_W: - case ZEND_FETCH_IS: - case ZEND_FETCH_FUNC_ARG: - if(do_prepare_fetch_global) - { - APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION(); - } - break; - default: - break; - } -#endif - i--; - zo++; - dzo++; - } -#ifdef ZEND_ENGINE_2 - } else { /* !needcopy */ - /* The fetch is only required if auto_globals_jit=1 */ - if(do_prepare_fetch_global) - { - zo = src->opcodes; - while(i > 0) { - - if(zo->opcode == ZEND_FETCH_R || - zo->opcode == ZEND_FETCH_W || - zo->opcode == ZEND_FETCH_IS || - zo->opcode == ZEND_FETCH_FUNC_ARG - ) { - APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION(); - } - - i--; - zo++; - } - } -#endif - } - return 1; -} -/* }}} */ - -/* {{{ apc_copy_op_array_for_execution */ -zend_op_array* apc_copy_op_array_for_execution(zend_op_array* dst, zend_op_array* src TSRMLS_DC) -{ - if(dst == NULL) { - dst = (zend_op_array*) emalloc(sizeof(src[0])); - } - memcpy(dst, src, sizeof(src[0])); - dst->static_variables = my_copy_static_variables(src, apc_php_malloc, apc_php_free); - - dst->refcount = apc_xmemcpy(src->refcount, - sizeof(src->refcount[0]), - apc_php_malloc); - - my_prepare_op_array_for_execution(dst,src TSRMLS_CC); - - return dst; -} -/* }}} */ - -/* {{{ apc_copy_function_for_execution */ -zend_function* apc_copy_function_for_execution(zend_function* src) -{ - zend_function* dst; - TSRMLS_FETCH(); - - dst = (zend_function*) emalloc(sizeof(src[0])); - memcpy(dst, src, sizeof(src[0])); - apc_copy_op_array_for_execution(&(dst->op_array), &(src->op_array) TSRMLS_CC); - return dst; -} -/* }}} */ - -/* {{{ apc_copy_function_for_execution_ex */ -zend_function* apc_copy_function_for_execution_ex(void *dummy, zend_function* src, apc_malloc_t allocate, apc_free_t deallocate) -{ - if(src->type==ZEND_INTERNAL_FUNCTION || src->type==ZEND_OVERLOADED_FUNCTION) return src; - return apc_copy_function_for_execution(src); -} -/* }}} */ - -/* {{{ apc_copy_class_entry_for_execution */ -zend_class_entry* apc_copy_class_entry_for_execution(zend_class_entry* src, int is_derived) -{ - zend_class_entry* dst = (zend_class_entry*) emalloc(sizeof(src[0])); - memcpy(dst, src, sizeof(src[0])); - -#ifdef ZEND_ENGINE_2 - if(src->num_interfaces) - { - /* These are slots to be populated later by ADD_INTERFACE insns */ - dst->interfaces = apc_php_malloc( - sizeof(zend_class_entry*) * src->num_interfaces); - memset(dst->interfaces, 0, - sizeof(zend_class_entry*) * src->num_interfaces); - } - else - { - /* assert(dst->interfaces == NULL); */ - } -#endif - -#ifndef ZEND_ENGINE_2 - dst->refcount = apc_xmemcpy(src->refcount, - sizeof(src->refcount[0]), - apc_php_malloc); -#endif - - /* Deep-copy the class properties, because they will be modified */ - - my_copy_hashtable(&dst->default_properties, - &src->default_properties, - (ht_copy_fun_t) my_copy_zval_ptr, - (ht_free_fun_t) my_free_zval_ptr, - 1, - apc_php_malloc, apc_php_free); - - /* For derived classes, we must also copy the function hashtable (although - * we can merely bitwise copy the functions it contains) */ - - my_copy_hashtable(&dst->function_table, - &src->function_table, - (ht_copy_fun_t) apc_copy_function_for_execution_ex, - NULL, - 0, - apc_php_malloc, apc_php_free); -#ifdef ZEND_ENGINE_2 - my_fixup_hashtable(&dst->function_table, (ht_fixup_fun_t)my_fixup_function_for_execution, src, dst); - - /* zend_do_inheritance merges properties_info. - * Need only shallow copying as it doesn't hold the pointers. - */ - my_copy_hashtable(&dst->properties_info, - &src->properties_info, - (ht_copy_fun_t) my_copy_property_info_for_execution, - NULL, - 0, - apc_php_malloc, apc_php_free); - -#ifdef ZEND_ENGINE_2_2 - /* php5.2 introduced a scope attribute for property info */ - my_fixup_hashtable(&dst->properties_info, (ht_fixup_fun_t)my_fixup_property_info_for_execution, src, dst); -#endif - - /* if inheritance results in a hash_del, it might result in - * a pefree() of the pointers here. Deep copying required. - */ - - my_copy_hashtable(&dst->constants_table, - &src->constants_table, - (ht_copy_fun_t) my_copy_zval_ptr, - NULL, - 1, - apc_php_malloc, apc_php_free); - - my_copy_hashtable(&dst->default_static_members, - &src->default_static_members, - (ht_copy_fun_t) my_copy_zval_ptr, - (ht_free_fun_t) my_free_zval_ptr, - 1, - apc_php_malloc, apc_php_free); - - if(src->static_members != &(src->default_static_members)) - { - dst->static_members = my_copy_hashtable(NULL, - src->static_members, - (ht_copy_fun_t) my_copy_zval_ptr, - (ht_free_fun_t) my_free_zval_ptr, - 1, - apc_php_malloc, apc_php_free); - } - else - { - dst->static_members = &(dst->default_static_members); - } - -#endif - - return dst; -} -/* }}} */ - -/* {{{ apc_free_class_entry_after_execution */ -void apc_free_class_entry_after_execution(zend_class_entry* src) -{ -#ifdef ZEND_ENGINE_2 - if(src->num_interfaces > 0 && src->interfaces) { - apc_php_free(src->interfaces); - src->interfaces = NULL; - src->num_interfaces = 0; - } - /* my_destroy_hashtable() does not play nice with refcounts */ - - zend_hash_clean(&src->default_static_members); - if(src->static_members != &(src->default_static_members)) - { - zend_hash_destroy(src->static_members); - apc_php_free(src->static_members); - src->static_members = NULL; - } - else - { - src->static_members = NULL; - } - zend_hash_clean(&src->default_properties); - zend_hash_clean(&src->constants_table); -#endif - - /* TODO: more cleanup */ -} -/* }}} */ - -#ifdef ZEND_ENGINE_2 - -/* {{{ my_fixup_function */ -static void my_fixup_function(Bucket *p, zend_class_entry *src, zend_class_entry *dst) -{ - zend_function* zf = p->pData; - - #define SET_IF_SAME_NAME(member) \ - do { \ - if(src->member && !strcmp(zf->common.function_name, src->member->common.function_name)) { \ - dst->member = zf; \ - } \ - } \ - while(0) - - if(zf->common.scope == src) - { - - /* Fixing up the default functions for objects here since - * we need to compare with the newly allocated functions - * - * caveat: a sub-class method can have the same name as the - * parent's constructor and create problems. - */ - - if(zf->common.fn_flags & ZEND_ACC_CTOR) dst->constructor = zf; - else if(zf->common.fn_flags & ZEND_ACC_DTOR) dst->destructor = zf; - else if(zf->common.fn_flags & ZEND_ACC_CLONE) dst->clone = zf; - else - { - SET_IF_SAME_NAME(__get); - SET_IF_SAME_NAME(__set); - SET_IF_SAME_NAME(__unset); - SET_IF_SAME_NAME(__isset); - SET_IF_SAME_NAME(__call); -#ifdef ZEND_ENGINE_2_2 - SET_IF_SAME_NAME(__tostring); -#endif - } - zf->common.scope = dst; - } - else - { - /* no other function should reach here */ - assert(0); - } - - #undef SET_IF_SAME_NAME -} -/* }}} */ - -#ifdef ZEND_ENGINE_2_2 -/* {{{ my_fixup_property_info */ -static void my_fixup_property_info(Bucket *p, zend_class_entry *src, zend_class_entry *dst) -{ - zend_property_info* property_info = (zend_property_info*)p->pData; - - if(property_info->ce == src) - { - property_info->ce = dst; - } - else - { - assert(0); /* should never happen */ - } -} -/* }}} */ -#endif - -/* {{{ my_fixup_hashtable */ -static void my_fixup_hashtable(HashTable *ht, ht_fixup_fun_t fixup, zend_class_entry *src, zend_class_entry *dst) -{ - Bucket *p; - - uint i; - - for (i = 0; i < ht->nTableSize; i++) { - if(!ht->arBuckets) break; - p = ht->arBuckets[i]; - while (p != NULL) { - fixup(p, src, dst); - p = p->pNext; - } - } -} -/* }}} */ - -#endif - -/* {{{ my_check_copy_function */ -static int my_check_copy_function(Bucket* p, va_list args) -{ - zend_class_entry* src = va_arg(args, zend_class_entry*); - zend_function* zf = (zend_function*)p->pData; -#ifndef ZEND_ENGINE_2 - zend_class_entry* parent = src->parent; - zend_function* parent_fn = NULL; -#endif - -#ifdef ZEND_ENGINE_2 - return (zf->common.scope == src); -#else - if (parent && - zend_hash_quick_find(&parent->function_table, p->arKey, - p->nKeyLength, p->h, (void **) &parent_fn)==SUCCESS) { - - if((parent_fn && zf) && - (parent_fn->op_array.refcount == zf->op_array.refcount)) - { - return 0; - } - } - return 1; -#endif -} -/* }}} */ - -/* {{{ my_check_copy_default_property */ -static int my_check_copy_default_property(Bucket* p, va_list args) -{ - zend_class_entry* src = va_arg(args, zend_class_entry*); - zend_class_entry* parent = src->parent; - zval ** child_prop = (zval**)p->pData; - zval ** parent_prop = NULL; - - if (parent && - zend_hash_quick_find(&parent->default_properties, p->arKey, - p->nKeyLength, p->h, (void **) &parent_prop)==SUCCESS) { - - if((parent_prop && child_prop) && (*parent_prop) == (*child_prop)) - { - return 0; - } - } - - /* possibly not in the parent */ - return 1; -} -/* }}} */ - -#ifdef ZEND_ENGINE_2 - -/* {{{ my_check_copy_property_info */ -static int my_check_copy_property_info(Bucket* p, va_list args) -{ - zend_class_entry* src = va_arg(args, zend_class_entry*); - zend_class_entry* parent = src->parent; - zend_property_info* child_info = (zend_property_info*)p->pData; - zend_property_info* parent_info = NULL; - -#ifdef ZEND_ENGINE_2_2 - /* so much easier */ - return (child_info->ce == src); -#endif - - if (parent && - zend_hash_quick_find(&parent->properties_info, p->arKey, p->nKeyLength, - p->h, (void **) &parent_info)==SUCCESS) { - if(parent_info->flags & ZEND_ACC_PRIVATE) - { - return 1; - } - if((parent_info->flags & ZEND_ACC_PPP_MASK) != - (child_info->flags & ZEND_ACC_PPP_MASK)) - { - /* TODO: figure out whether ACC_CHANGED is more appropriate - * here */ - return 1; - } - return 0; - } - - /* property doesn't exist in parent, copy into cached child */ - return 1; -} -/* }}} */ - -/* {{{ my_check_copy_static_member */ -static int my_check_copy_static_member(Bucket* p, va_list args) -{ - zend_class_entry* src = va_arg(args, zend_class_entry*); - HashTable * ht = va_arg(args, HashTable*); - zend_class_entry* parent = src->parent; - HashTable * parent_ht = NULL; - char * member_name; - char * class_name = NULL; - - zend_property_info *parent_info = NULL; - zend_property_info *child_info = NULL; - zval ** parent_prop = NULL; - zval ** child_prop = (zval**)(p->pData); - - if(!parent) { - return 1; - } - - /* these do not need free'ing */ -#ifdef ZEND_ENGINE_2_2 - zend_unmangle_property_name(p->arKey, p->nKeyLength-1, &class_name, &member_name); -#else - zend_unmangle_property_name(p->arKey, &class_name, &member_name); -#endif - - /* please refer do_inherit_property_access_check in zend_compile.c - * to understand why we lookup in properties_info. - */ - if((zend_hash_find(&parent->properties_info, member_name, - strlen(member_name)+1, (void**)&parent_info) == SUCCESS) - && - (zend_hash_find(&src->properties_info, member_name, - strlen(member_name)+1, (void**)&child_info) == SUCCESS)) - { - if(child_info->flags & ZEND_ACC_STATIC && - (parent_info->flags & ZEND_ACC_PROTECTED && - child_info->flags & ZEND_ACC_PUBLIC)) - { - /* Do not copy into static_members. zend_do_inheritance - * will automatically insert a NULL value. - * TODO: decrement refcount or fixup when copying out for exec ? - */ - return 0; - } - if(ht == &(src->default_static_members)) - { - parent_ht = &parent->default_static_members; - } - else - { - parent_ht = parent->static_members; - } - - if(zend_hash_quick_find(parent_ht, p->arKey, - p->nKeyLength, p->h, (void**)&parent_prop) == SUCCESS) - { - /* they point to the same zval */ - if(*parent_prop == *child_prop) - { - return 0; - } - } - } - - return 1; -} -/* }}} */ -#endif - -/* {{{ apc_register_optimizer(apc_optimize_function_t optimizer) - * register a optimizer callback function, returns the previous callback - */ -apc_optimize_function_t apc_register_optimizer(apc_optimize_function_t optimizer TSRMLS_DC) { - apc_optimize_function_t old_optimizer = APCG(apc_optimize_function); - APCG(apc_optimize_function) = optimizer; - return old_optimizer; -} - -/* - * 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 - */ diff --git a/apc_compile.h b/apc_compile.h deleted file mode 100644 index 53fbd58..0000000 --- a/apc_compile.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | Arun C. Murthy | - | Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - 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_compile.h,v 3.19.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_COMPILE_H -#define APC_COMPILE_H - -/* - * This module encapsulates most of the complexity involved in deep-copying - * the Zend compiler data structures. The routines are allocator-agnostic, so - * the same function can be used for copying to and from shared memory. - */ - -#include "apc.h" -#include "apc_php.h" - -/* {{{ struct definition: apc_function_t */ -typedef struct apc_function_t apc_function_t; -struct apc_function_t { - char* name; /* the function name */ - int name_len; /* length of name */ - zend_function* function; /* the zend function data structure */ -}; -/* }}} */ - -/* {{{ struct definition: apc_class_t */ -typedef struct apc_class_t apc_class_t; -struct apc_class_t { - char* name; /* the class name */ - int name_len; /* length of name */ - int is_derived; /* true if this is a derived class */ - char* parent_name; /* the parent class name */ - zend_class_entry* class_entry; /* the zend class data structure */ -}; -/* }}} */ - -/* {{{ struct definition: apc_opflags_t */ -typedef struct apc_opflags_t apc_opflags_t; -struct apc_opflags_t { - unsigned int has_jumps : 1; /* has jump offsets */ - unsigned int deep_copy : 1; /* needs deep copy */ - - /* autoglobal bits */ - unsigned int _POST : 1; - unsigned int _GET : 1; - unsigned int _COOKIE : 1; - unsigned int _SERVER : 1; - unsigned int _ENV : 1; - unsigned int _FILES : 1; - unsigned int _REQUEST : 1; - unsigned int unknown_global : 1; -}; -/* }}} */ - -/* - * These are the top-level copy functions. - */ - -extern zend_op_array* apc_copy_op_array(zend_op_array* dst, zend_op_array* src, apc_malloc_t allocate, apc_free_t deallocate TSRMLS_DC); -extern zend_class_entry* apc_copy_class_entry(zend_class_entry* dst, zend_class_entry* src, apc_malloc_t allocate, apc_free_t deallocate); -extern apc_function_t* apc_copy_new_functions(int old_count, apc_malloc_t allocate, apc_free_t deallocate TSRMLS_DC); -extern apc_class_t* apc_copy_new_classes(zend_op_array* op_array, int old_count, apc_malloc_t allocate, apc_free_t deallocate TSRMLS_DC); -extern zval* apc_copy_zval(zval* dst, const zval* src, apc_malloc_t allocate, apc_free_t deallocate); - -/* - * Deallocation functions corresponding to the copy functions above. - */ - -extern void apc_free_op_array(zend_op_array* src, apc_free_t deallocate); -extern void apc_free_functions(apc_function_t* src, apc_free_t deallocate); -extern void apc_free_classes(apc_class_t* src, apc_free_t deallocate); -extern void apc_free_zval(zval* src, apc_free_t deallocate); - -/* - * These "copy-for-execution" functions must be called after retrieving an - * object from the shared cache. They do the minimal amount of work necessary - * to allow multiple processes to concurrently execute the same VM data - * structures. - */ - -extern zend_op_array* apc_copy_op_array_for_execution(zend_op_array* dst, zend_op_array* src TSRMLS_DC); -extern zend_function* apc_copy_function_for_execution(zend_function* src); -extern zend_class_entry* apc_copy_class_entry_for_execution(zend_class_entry* src, int is_derived); - -/* - * The "free-after-execution" function performs a cursory clean up of the class data - * This is required to minimize memory leak warnings and to ensure correct destructor - * ordering of some variables. - */ -extern void apc_free_class_entry_after_execution(zend_class_entry* src); - -/* - * Optimization callback definition and registration function. - */ -typedef zend_op_array* (*apc_optimize_function_t) (zend_op_array* TSRMLS_DC); -extern apc_optimize_function_t apc_register_optimizer(apc_optimize_function_t optimizer TSRMLS_DC); - -#endif - -/* - * 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 - */ diff --git a/apc_debug.c b/apc_debug.c deleted file mode 100644 index 9925aef..0000000 --- a/apc_debug.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | Arun C. Murthy | - | Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - 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_debug.c,v 3.6.2.1 2008/05/11 18:57:00 rasmus Exp $ */ -#include "apc.h" -#include -#include "zend_compile.h" - -#ifdef __DEBUG_APC__ - -#include - -/* keep track of vld_dump_oparray() signature */ -typedef void (*vld_dump_f) (zend_op_array * TSRMLS_DC); - -#endif - -void dump(zend_op_array *op_array TSRMLS_DC) -{ -#ifdef __DEBUG_APC__ - vld_dump_f dump_op_array = dlsym(NULL, "vld_dump_oparray"); - - if(dump_op_array) - { - dump_op_array(op_array TSRMLS_CC); - } - else - { - apc_wprint("vld is not installed or something even worse."); - } -#endif -} diff --git a/apc_debug.h b/apc_debug.h deleted file mode 100644 index 4e286e7..0000000 --- a/apc_debug.h +++ /dev/null @@ -1 +0,0 @@ -void dump(zend_op_array * TSRMLS_DC); diff --git a/apc_fcntl.c b/apc_fcntl.c deleted file mode 100644 index 218a24c..0000000 --- a/apc_fcntl.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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: George Schlossnagle | - | Rasmus Lerdorf | - +----------------------------------------------------------------------+ - - 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_fcntl.c,v 3.25.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_fcntl.h" -#include "apc.h" -#include -#include - -int apc_fcntl_create(const char* pathname) -{ - int fd; - if(pathname == NULL) { - char lock_path[] = "/tmp/.apc.XXXXXX"; - mktemp(lock_path); - fd = open(lock_path, O_RDWR|O_CREAT, 0666); - if(fd > 0 ) { - unlink(lock_path); - return fd; - } else { - apc_eprint("apc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", lock_path); - return -1; - } - } - fd = open(pathname, O_RDWR|O_CREAT, 0666); - if(fd > 0 ) { - unlink(pathname); - return fd; - } - apc_eprint("apc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", pathname); - return -1; -} - -void apc_fcntl_destroy(int fd) -{ - close(fd); -} - -static int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len) -{ - int ret; - struct flock lock; - - lock.l_type = type; - lock.l_start = offset; - lock.l_whence = whence; - lock.l_len = len; - lock.l_pid = 0; - - do { ret = fcntl(fd, cmd, &lock) ; } - while(ret < 0 && errno == EINTR); - return(ret); -} - -void apc_fcntl_lock(int fd) -{ - if(lock_reg(fd, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) { - apc_eprint("apc_fcntl_lock failed:"); - } -} - -void apc_fcntl_rdlock(int fd) -{ - if(lock_reg(fd, F_SETLKW, F_RDLCK, 0, SEEK_SET, 0) < 0) { - apc_eprint("apc_fcntl_rdlock failed:"); - } -} - -zend_bool apc_fcntl_nonblocking_lock(int fd) -{ - if(lock_reg(fd, F_SETLK, F_WRLCK, 0, SEEK_SET, 0) < 0) { - if(errno==EACCES||errno==EAGAIN) return 0; - else apc_eprint("apc_fcntl_lock failed:"); - } - return 1; -} - -void apc_fcntl_unlock(int fd) -{ - if(lock_reg(fd, F_SETLKW, F_UNLCK, 0, SEEK_SET, 0) < 0) { - apc_eprint("apc_fcntl_unlock failed:"); - } -} - -/* - * 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 - */ diff --git a/apc_fcntl.h b/apc_fcntl.h deleted file mode 100644 index 1879adc..0000000 --- a/apc_fcntl.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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: George Schlossnagle | - | Rasmus Lerdorf | - +----------------------------------------------------------------------+ - - 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_fcntl.h,v 3.14.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_FCNTL_H -#define APC_FCNTL_H - - -extern int apc_fcntl_create(const char* pathname); -extern void apc_fcntl_destroy(int fd); -extern void apc_fcntl_lock(int fd); -extern void apc_fcntl_rdlock(int fd); -extern void apc_fcntl_unlock(int fd); -extern unsigned char apc_fcntl_nonblocking_lock(int fd); -#endif - -/* - * 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 - */ diff --git a/apc_fcntl_win32.c b/apc_fcntl_win32.c deleted file mode 100644 index 916b823..0000000 --- a/apc_fcntl_win32.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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: George Schlossnagle | - | Edin Kadribasic | - +----------------------------------------------------------------------+ - - 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_fcntl_win32.c,v 3.6.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_fcntl.h" -#include "apc.h" -#include -#include -#include -#include -#include -#include - -int apc_fcntl_create(const char* pathname) -{ - char *lock_file = emalloc(MAXPATHLEN); - HANDLE fd; - DWORD tmplen; - static int i=0; - - tmplen = GetTempPath(MAXPATHLEN, lock_file); - if (!tmplen) { - efree(lock_file); - return -1; - } - - snprintf(lock_file + tmplen, MAXPATHLEN - tmplen - 1, "apc.lock.%d", i++); - - fd = CreateFile(lock_file, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - - - if (fd == INVALID_HANDLE_VALUE) { - apc_eprint("apc_fcntl_create: could not open %s", lock_file); - efree(lock_file); - return -1; - } - - efree(lock_file); - return (int)fd; -} - -void apc_fcntl_destroy(int fd) -{ - CloseHandle((HANDLE)fd); -} - -void apc_fcntl_lock(int fd) -{ - OVERLAPPED offset = {0, 0, 0, 0, NULL}; - - if (!LockFileEx((HANDLE)fd, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &offset)) { - apc_eprint("apc_fcntl_lock failed errno:%d", GetLastError()); - } -} - -void apc_fcntl_rdlock(int fd) -{ - OVERLAPPED offset = {0, 0, 0, 0, NULL}; - - if (!LockFileEx((HANDLE)fd, 0, 0, 1, 0, &offset)) { - apc_eprint("apc_fcntl_rdlock failed errno:%d", GetLastError()); - } -} - -void apc_fcntl_unlock(int fd) -{ - OVERLAPPED offset = {0, 0, 0, 0, NULL}; - - if (!UnlockFileEx((HANDLE)fd, 0, 1, 0, &offset)) { - DWORD error_code = GetLastError(); - /* Ignore already unlocked error */ - if (error_code != ERROR_NOT_LOCKED) { - apc_eprint("apc_fcntl_unlock failed errno:%d", error_code); - } - } -} - -/* - * 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 - */ diff --git a/apc_futex.c b/apc_futex.c deleted file mode 100644 index 61ccc76..0000000 --- a/apc_futex.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - */ - -/* $Id: apc_futex.c,v 3.2.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -/*************************************************************************** -* Futex (Fast Userspace Mutex) support for APC -* -* Futex support provides user space locking with system calls only -* for the contended cases. Some required reading for this functionality is: -* -* 'Fuss, Futexes and Furwocks: Fast Userlevel Locking in Linux' -* by Hubertus Franke, Rusty Russell, and Matthew Kirkwood -* http://www.realitydiluted.com/nptl-uclibc/docs/futex.pdf -* -* 'Futexes are Tricky' by Ulrich Drepper -* http://people.redhat.com/drepper/futex.pdf -* -* -* This implementation is optimized and designed for the i386 and x86_64 -* architectures. Other architectures may require additional design -* to efficiently and safely implement this functionality. -* -* Lock values are: -* 0 = Unlocked -* 1 = Locked without any waiting processes -* 2 = Locked with an unknown number of waiting processes -* -***************************************************************************/ - -#include "apc.h" -#include "apc_futex.h" - -#ifdef APC_FUTEX_LOCKS - - -inline int apc_futex_create() -{ - return 0; -} - -inline void apc_futex_destroy(volatile int* lock) -{ - return; -} - -void apc_futex_lock(volatile int* lock) -{ - int c; - - /* Attempt to obtain a lock if not currently locked. If the previous - * value was not 0 then we did not obtain the lock, and must wait. - * If the previous value was 1 (has no waiting processes) then we - * set the lock to 2 before blocking on the futex wait operation. - * This implementation suffers from the possible difficulty of - * efficently implementing the atomic xchg operation on some - * architectures, and could also cause unecessary wake operations by - * setting the lock to 2 when there are no additional waiters. - */ - if((c = apc_cmpxchg(lock, 0, 1)) != 0) { - if(c != 2) { - c = apc_xchg(lock, 2); - } - while(c != 0) { - apc_futex_wait(lock, 2); - c = apc_xchg(lock, 2); - } - } - -} - -/* non-blocking lock returns 1 when the lock has been obtained, 0 if it would block */ -inline zend_bool apc_futex_nonblocking_lock(volatile int* lock) -{ - return apc_cmpxchg(lock, 0, 1) == 0; -} - - -inline void apc_futex_unlock(volatile int* lock) -{ - /* set the lock to 0, if it's previous values was not 1 (no waiters) - * then perform a wake operation on one process letting it know the lock - * is available. This is an optimization to save wake calls if there - * are no waiting processes for the lock - */ - if(apc_xchg(lock,0) != 1) { - apc_futex_wake(lock, 1); - } -} - -#endif - -/* - * 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 - */ diff --git a/apc_futex.h b/apc_futex.h deleted file mode 100644 index 5b99501..0000000 --- a/apc_futex.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - */ - -/* $Id: apc_futex.h,v 3.2.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_FUTEX_H -#define APC_FUTEX_H - -#include "apc.h" - -#ifdef APC_FUTEX_LOCKS - -#include -#include -#include - -#include "arch/atomic.h" - -#define sys_futex(futex, op, val, timeout) syscall(SYS_futex, futex, op, val, timeout) -#define apc_futex_wait(val, oldval) sys_futex((void*)val, FUTEX_WAIT, oldval, NULL) -#define apc_futex_wake(val, count) sys_futex((void*)val, FUTEX_WAKE, count, NULL) - -int apc_futex_create(); -void apc_futex_destroy(volatile int* lock); -void apc_futex_lock(volatile int* lock); -void apc_futex_unlock(volatile int* lock); - -#endif - -#endif - -/* - * 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 - */ diff --git a/apc_globals.h b/apc_globals.h deleted file mode 100644 index 3908158..0000000 --- a/apc_globals.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | George Schlossnagle | - | Rasmus Lerdorf | - | Arun C. Murthy | - | Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - 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_globals.h,v 3.70.2.8 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_GLOBALS_H -#define APC_GLOBALS_H - -#define APC_VERSION "3.0.19" - -#include "apc_cache.h" -#include "apc_stack.h" -#include "apc_php.h" - -ZEND_BEGIN_MODULE_GLOBALS(apc) - /* configuration parameters */ - zend_bool enabled; /* if true, apc is enabled (defaults to true) */ - long shm_segments; /* number of shared memory segments to use */ - long shm_size; /* size of each shared memory segment (in MB) */ - long num_files_hint; /* parameter to apc_cache_create */ - long user_entries_hint; - long gc_ttl; /* parameter to apc_cache_create */ - long ttl; /* parameter to apc_cache_create */ - long user_ttl; -#if APC_MMAP - char *mmap_file_mask; /* mktemp-style file-mask to pass to mmap */ -#endif - char** filters; /* array of regex filters that prevent caching */ - - /* module variables */ - zend_bool initialized; /* true if module was initialized */ - apc_stack_t* cache_stack; /* the stack of cached executable code */ - zend_bool cache_by_default; /* true if files should be cached unless filtered out */ - /* false if files should only be cached if filtered in */ - long slam_defense; /* Probability of a process not caching an uncached file */ - size_t* mem_size_ptr; /* size of blocks allocated to file being cached (NULL outside my_compile_file) */ - long file_update_protection; /* Age in seconds before a file is eligible to be cached - 0 to disable */ - zend_bool enable_cli; /* Flag to override turning APC off for CLI */ - long max_file_size; /* Maximum size of file, in bytes that APC will be allowed to cache */ - long slam_rand; /* A place to store the slam rand value for the request */ - zend_bool fpstat; /* true if fullpath includes should be stat'ed */ - zend_bool stat_ctime; /* true if ctime in addition to mtime should be checked */ - zend_bool write_lock; /* true for a global write lock */ - zend_bool report_autofilter; /* true for auto-filter warnings */ - zend_bool include_once; /* Override the ZEND_INCLUDE_OR_EVAL opcode handler to avoid pointless fopen()s [still experimental] */ - apc_optimize_function_t apc_optimize_function; /* optimizer function callback */ -#ifdef MULTIPART_EVENT_FORMDATA - zend_bool rfc1867; /* Flag to enable rfc1867 handler */ - char* rfc1867_prefix; /* Key prefix */ - char* rfc1867_name; /* Name of hidden field to activate upload progress/key suffix */ - double rfc1867_freq; /* Update frequency as percentage or bytes */ -#endif - HashTable *copied_zvals; /* my_copy recursion detection list */ -#ifdef ZEND_ENGINE_2 - int reserved_offset; /* offset for apc info in op_array->reserved[] */ -#endif - zend_bool force_file_update; /* force files to be updated during apc_compile_file */ - char canon_path[MAXPATHLEN]; /* canonical path for key data */ -#if APC_FILEHITS - zval *filehits; /* Files that came from the cache for this request */ -#endif - zend_bool coredump_unmap; /* Trap signals that coredump and unmap shared memory */ -ZEND_END_MODULE_GLOBALS(apc) - -/* (the following declaration is defined in php_apc.c) */ -ZEND_EXTERN_MODULE_GLOBALS(apc) - -#ifdef ZTS -# define APCG(v) TSRMG(apc_globals_id, zend_apc_globals *, v) -#else -# define APCG(v) (apc_globals.v) -#endif - -/* True globals */ -extern apc_cache_t* apc_cache; /* the global compiler cache */ -extern apc_cache_t* apc_user_cache; /* the global user content cache */ -extern void* apc_compiled_filters; /* compiled filters */ - -#endif - -/* - * 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 - */ diff --git a/apc_lock.h b/apc_lock.h deleted file mode 100644 index 1472714..0000000 --- a/apc_lock.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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: George Schlossnagle | - | Rasmus Lerdorf | - +----------------------------------------------------------------------+ - - 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_lock.h,v 3.20.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_LOCK -#define APC_LOCK - -#include "apc_sem.h" -#include "apc_fcntl.h" -#include "apc_pthreadmutex.h" -#include "apc_futex.h" -#include "apc_spin.h" -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef TSRM_LOCKS -#define RDLOCK_AVAILABLE 0 -#define NONBLOCKING_LOCK_AVAILABLE 0 -/* quick & dirty: use TSRM mutex locks for now */ -#define apc_lck_create(a,b,c,d) d=(int)tsrm_mutex_alloc() -#define apc_lck_destroy(a) tsrm_mutex_free((MUTEX_T)a) -#define apc_lck_lock(a) tsrm_mutex_lock((MUTEX_T)a) -#define apc_lck_rdlock(a) tsrm_mutex_lock((MUTEX_T)a) -#define apc_lck_unlock(a) tsrm_mutex_unlock((MUTEX_T)a) -#elif defined(APC_SEM_LOCKS) -#define RDLOCK_AVAILABLE 0 -#define NONBLOCKING_LOCK_AVAILABLE 0 -#define apc_lck_t int -#define apc_lck_create(a,b,c,d) d=apc_sem_create(NULL,(b),(c)) -#define apc_lck_destroy(a) apc_sem_destroy(a) -#define apc_lck_lock(a) apc_sem_lock(a) -#define apc_lck_rdlock(a) apc_sem_lock(a) -#define apc_lck_unlock(a) apc_sem_unlock(a) -#elif defined(APC_PTHREADMUTEX_LOCKS) -#define RDLOCK_AVAILABLE 0 -#define NONBLOCKING_LOCK_AVAILABLE 1 -#define apc_lck_t pthread_mutex_t -#define apc_lck_create(a,b,c,d) apc_pthreadmutex_create((pthread_mutex_t*)&d) -#define apc_lck_destroy(a) apc_pthreadmutex_destroy(&a) -#define apc_lck_lock(a) apc_pthreadmutex_lock(&a) -#define apc_lck_nb_lock(a) apc_pthreadmutex_nonblocking_lock(&a) -#define apc_lck_rdlock(a) apc_pthreadmutex_lock(&a) -#define apc_lck_unlock(a) apc_pthreadmutex_unlock(&a) -#elif defined(APC_FUTEX_LOCKS) -#define NONBLOCKING_LOCK_AVAILABLE 1 -#define apc_lck_t int -#define apc_lck_create(a,b,c,d) d=apc_futex_create() -#define apc_lck_destroy(a) apc_futex_destroy(&a) -#define apc_lck_lock(a) apc_futex_lock(&a) -#define apc_lck_nb_lock(a) apc_futex_nonblocking_lock(&a) -#define apc_lck_rdlock(a) apc_futex_lock(&a) -#define apc_lck_unlock(a) apc_futex_unlock(&a) -#elif defined(APC_SPIN_LOCKS) -#define NONBLOCKING_LOCK_AVAILABLE APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE -#define apc_lck_t slock_t -#define apc_lck_create(a,b,c,d) apc_slock_create((slock_t*)&(d)) -#define apc_lck_destroy(a) apc_slock_destroy(&a) -#define apc_lck_lock(a) apc_slock_lock(&a) -#define apc_lck_nb_lock(a) apc_slock_nonblocking_lock(&a) -#define apc_lck_rdlock(a) apc_slock_lock(&a) -#define apc_lck_unlock(a) apc_slock_unlock(&a) -#else -#define RDLOCK_AVAILABLE 1 -#ifdef PHP_WIN32 -#define NONBLOCKING_LOCK_AVAILABLE 0 -#else -#define NONBLOCKING_LOCK_AVAILABLE 1 -#endif -#define apc_lck_t int -#define apc_lck_create(a,b,c,d) d=apc_fcntl_create((a)) -#define apc_lck_destroy(a) apc_fcntl_destroy(a) -#define apc_lck_lock(a) apc_fcntl_lock(a) -#define apc_lck_nb_lock(a) apc_fcntl_nonblocking_lock(a) -#define apc_lck_rdlock(a) apc_fcntl_rdlock(a) -#define apc_lck_unlock(a) apc_fcntl_unlock(a) -#endif - -#endif diff --git a/apc_main.c b/apc_main.c deleted file mode 100644 index 3825399..0000000 --- a/apc_main.c +++ /dev/null @@ -1,688 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | Rasmus Lerdorf | - | Arun C. Murthy | - | Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - 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_main.c,v 3.103.2.7 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_php.h" -#include "apc_main.h" -#include "apc.h" -#include "apc_lock.h" -#include "apc_cache.h" -#include "apc_compile.h" -#include "apc_globals.h" -#include "apc_sma.h" -#include "apc_stack.h" -#include "apc_zend.h" -#include "SAPI.h" -#if PHP_API_VERSION <= 20020918 -#if HAVE_APACHE -#ifdef APC_PHP4_STAT -#undef XtOffsetOf -#include "httpd.h" -#endif -#endif -#endif - -/* {{{ module variables */ - -/* pointer to the original Zend engine compile_file function */ -typedef zend_op_array* (zend_compile_t)(zend_file_handle*, int TSRMLS_DC); -static zend_compile_t *old_compile_file; - -/* }}} */ - -/* {{{ get/set old_compile_file (to interact with other extensions that need the compile hook) */ -static zend_compile_t* set_compile_hook(zend_compile_t *ptr) -{ - zend_compile_t *retval = old_compile_file; - - if (ptr != NULL) old_compile_file = ptr; - return retval; -} -/* }}} */ - -/* {{{ install_function */ -static int install_function(apc_function_t fn TSRMLS_DC) -{ - zend_function *func; - int status; - - func = apc_copy_function_for_execution(fn.function); - - status = zend_hash_add(EG(function_table), - fn.name, - fn.name_len+1, - func, - sizeof(fn.function[0]), - NULL); - - efree(func); - - if (status == FAILURE) { - /* apc_eprint("Cannot redeclare %s()", fn.name); */ - } - - return status; -} -/* }}} */ - -/* {{{ install_class */ -static int install_class(apc_class_t cl TSRMLS_DC) -{ - zend_class_entry* class_entry = cl.class_entry; - zend_class_entry* parent = NULL; - int status; -#ifdef ZEND_ENGINE_2 - zend_class_entry** allocated_ce = NULL; -#endif - - - /* Special case for mangled names. Mangled names are unique to a file. - * There is no way two classes with the same mangled name will occur, - * unless a file is included twice. And if in case, a file is included - * twice, all mangled name conflicts can be ignored and the class redeclaration - * error may be deferred till runtime of the corresponding DECLARE_CLASS - * calls. - */ - - if(cl.name_len != 0 && cl.name[0] == '\0') { - if(zend_hash_exists(CG(class_table), cl.name, cl.name_len+1)) { - return SUCCESS; - } - } - -#ifdef ZEND_ENGINE_2 - /* - * XXX: We need to free this somewhere... - */ - allocated_ce = apc_php_malloc(sizeof(zend_class_entry*)); - - if(!allocated_ce) { - return FAILURE; - } - - *allocated_ce = -#endif - class_entry = - apc_copy_class_entry_for_execution(cl.class_entry, - cl.is_derived); - - - /* restore parent class pointer for compile-time inheritance */ - if (cl.parent_name != NULL) { -#ifdef ZEND_ENGINE_2 - zend_class_entry** parent_ptr = NULL; - /* - * zend_lookup_class has to be due to presence of __autoload, - * just looking up the EG(class_table) is not enough in php5! - * Even more dangerously, thanks to __autoload and people using - * class names as filepaths for inclusion, this has to be case - * sensitive. zend_lookup_class automatically does a case_fold - * internally, but passes the case preserved version to __autoload. - * Aside: Do NOT pass *strlen(cl.parent_name)+1* because - * zend_lookup_class does it internally anyway! - */ - status = zend_lookup_class(cl.parent_name, - strlen(cl.parent_name), - &parent_ptr TSRMLS_CC); -#else - status = zend_hash_find(EG(class_table), - cl.parent_name, - strlen(cl.parent_name)+1, - (void**) &parent); -#endif - if (status == FAILURE) { - if(APCG(report_autofilter)) { - apc_wprint("Dynamic inheritance detected for class %s", cl.name); - } - class_entry->parent = NULL; - return status; - } - else { -#ifdef ZEND_ENGINE_2 - parent = *parent_ptr; -#endif - class_entry->parent = parent; -#ifdef ZEND_ENGINE_2 - zend_do_inheritance(class_entry, parent TSRMLS_CC); -#else - zend_do_inheritance(class_entry, parent); -#endif - } - - - } - -#ifdef ZEND_ENGINE_2 - status = zend_hash_add(EG(class_table), - cl.name, - cl.name_len+1, - allocated_ce, - sizeof(zend_class_entry*), - NULL); -#else - status = zend_hash_add(EG(class_table), - cl.name, - cl.name_len+1, - class_entry, - sizeof(zend_class_entry), - NULL); -#endif - - if (status == FAILURE) { - apc_eprint("Cannot redeclare class %s", cl.name); - } - return status; -} -/* }}} */ - -/* {{{ uninstall_class */ -static int uninstall_class(apc_class_t cl TSRMLS_DC) -{ - int status; - -#ifdef ZEND_ENGINE_2 - status = zend_hash_del(EG(class_table), - cl.name, - cl.name_len+1); -#else - status = zend_hash_del(EG(class_table), - cl.name, - cl.name_len+1); -#endif - if (status == FAILURE) { - apc_eprint("Cannot delete class %s", cl.name); - } - return status; -} -/* }}} */ - -/* {{{ compare_file_handles */ -static int compare_file_handles(void* a, void* b) -{ - zend_file_handle* fh1 = (zend_file_handle*)a; - zend_file_handle* fh2 = (zend_file_handle*)b; - return (fh1->type == fh2->type && - fh1->filename == fh2->filename && - fh1->opened_path == fh2->opened_path); -} -/* }}} */ - -/* {{{ cached_compile */ -static zend_op_array* cached_compile(zend_file_handle* h, - int type TSRMLS_DC) -{ - apc_cache_entry_t* cache_entry; - int i, ii; - - cache_entry = (apc_cache_entry_t*) apc_stack_top(APCG(cache_stack)); - assert(cache_entry != NULL); - - if (cache_entry->data.file.classes) { - for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) { - if(install_class(cache_entry->data.file.classes[i] TSRMLS_CC) == FAILURE) { - goto default_compile; - } - } - } - - if (cache_entry->data.file.functions) { - for (i = 0; cache_entry->data.file.functions[i].function != NULL; i++) { - install_function(cache_entry->data.file.functions[i] TSRMLS_CC); - } - } - - - return apc_copy_op_array_for_execution(NULL, cache_entry->data.file.op_array TSRMLS_CC); - -default_compile: - - if(APCG(report_autofilter)) { - apc_wprint("Autofiltering %s", h->opened_path); - } - - if(cache_entry->data.file.classes) { - for(ii = 0; ii < i ; ii++) { - uninstall_class(cache_entry->data.file.classes[ii] TSRMLS_CC); - } - } - - apc_stack_pop(APCG(cache_stack)); /* pop out cache_entry */ - - apc_cache_release(apc_cache, cache_entry); - - /* cannot free up cache data yet, it maybe in use */ - - zend_llist_del_element(&CG(open_files), h, compare_file_handles); /* We leak fds without this hack */ - - h->type = ZEND_HANDLE_FILENAME; - - return NULL; -} -/* }}} */ - -/* {{{ my_compile_file - Overrides zend_compile_file */ -static zend_op_array* my_compile_file(zend_file_handle* h, - int type TSRMLS_DC) -{ - apc_cache_key_t key; - apc_cache_entry_t* cache_entry; - zend_op_array* op_array; - int num_functions, num_classes, ret; - zend_op_array* alloc_op_array; - apc_function_t* alloc_functions; - apc_class_t* alloc_classes; - time_t t; - char *path; - size_t mem_size; - - if (!APCG(enabled) || apc_cache_busy(apc_cache)) { - return old_compile_file(h, type TSRMLS_CC); - } - - /* check our regular expression filters */ - if (APCG(filters) && apc_compiled_filters) { - int ret = apc_regex_match_array(apc_compiled_filters, h->filename); - if(ret == APC_NEGATIVE_MATCH || (ret != APC_POSITIVE_MATCH && !APCG(cache_by_default))) { - return old_compile_file(h, type TSRMLS_CC); - } - } else if(!APCG(cache_by_default)) { - return old_compile_file(h, type TSRMLS_CC); - } - -#if PHP_API_VERSION < 20041225 -#if HAVE_APACHE && defined(APC_PHP4_STAT) - t = ((request_rec *)SG(server_context))->request_time; -#else - t = time(0); -#endif -#else - t = sapi_get_request_time(TSRMLS_C); -#endif - -#ifdef __DEBUG_APC__ - fprintf(stderr,"1. h->opened_path=[%s] h->filename=[%s]\n", h->opened_path?h->opened_path:"null",h->filename); -#endif - - /* try to create a cache key; if we fail, give up on caching */ - if (!apc_cache_make_file_key(&key, h->filename, PG(include_path), t TSRMLS_CC)) { - return old_compile_file(h, type TSRMLS_CC); - } - - - if(!APCG(force_file_update)) { - /* search for the file in the cache */ - cache_entry = apc_cache_find(apc_cache, key, t); - } else { - cache_entry = NULL; - } - - if (cache_entry != NULL) { - int dummy = 1; - if (h->opened_path == NULL) { - h->opened_path = estrdup(cache_entry->data.file.filename); - } - zend_hash_add(&EG(included_files), h->opened_path, strlen(h->opened_path)+1, (void *)&dummy, sizeof(int), NULL); - - zend_llist_add_element(&CG(open_files), h); /* We leak fds without this hack */ - - apc_stack_push(APCG(cache_stack), cache_entry); - op_array = cached_compile(h, type TSRMLS_CC); - if(op_array) { -#ifdef APC_FILEHITS - /* If the file comes from the cache, add it to the global request file list */ - add_next_index_string(APCG(filehits), h->filename, 1); -#endif - return op_array; - } - if(APCG(report_autofilter)) { - apc_wprint("Recompiling %s", h->opened_path); - } - /* TODO: check what happens with EG(included_files) */ - } - - /* remember how many functions and classes existed before compilation */ - num_functions = zend_hash_num_elements(CG(function_table)); - num_classes = zend_hash_num_elements(CG(class_table)); - - /* compile the file using the default compile function */ - op_array = old_compile_file(h, type TSRMLS_CC); - if (op_array == NULL) { - return NULL; - } - /* - * Basically this will cause a file only to be cached on a percentage - * of the attempts. This is to avoid cache slams when starting up a - * very busy server or when modifying files on a very busy live server. - * There is no point having many processes all trying to cache the same - * file at the same time. By introducing a chance of being cached - * we theoretically cut the cache slam problem by the given percentage. - * For example if apc.slam_defense is set to 66 then 2/3 of the attempts - * to cache an uncached file will be ignored. - */ - if(APCG(slam_defense)) { - if(APCG(slam_rand)==-1) { - APCG(slam_rand) = (int)(100.0*rand()/(RAND_MAX+1.0)); - } - if(APCG(slam_rand) < APCG(slam_defense)) { - return op_array; - } - } - - /* Make sure the mtime reflects the files last known mtime in the case of fpstat==0 */ - if(key.type == APC_CACHE_KEY_FPFILE) { - apc_fileinfo_t fileinfo; - struct stat *tmp_buf = NULL; - if(!strcmp(SG(request_info).path_translated, h->filename)) { - tmp_buf = sapi_get_stat(TSRMLS_C); /* Apache has already done this stat() for us */ - } - if(tmp_buf) { - fileinfo.st_buf.sb = *tmp_buf; - } else { - if (apc_search_paths(h->filename, PG(include_path), &fileinfo) != 0) { -#ifdef __DEBUG_APC__ - fprintf(stderr,"Stat failed %s - bailing (%s) (%d)\n",filename,SG(request_info).path_translated); -#endif - return op_array; - } - } - key.mtime = fileinfo.st_buf.sb.st_mtime; - } - - HANDLE_BLOCK_INTERRUPTIONS(); - -#if NONBLOCKING_LOCK_AVAILABLE - if(APCG(write_lock)) { - if(!apc_cache_write_lock(apc_cache)) { - HANDLE_UNBLOCK_INTERRUPTIONS(); - return op_array; - } - } -#endif - - mem_size = 0; - APCG(mem_size_ptr) = &mem_size; - if(!(alloc_op_array = apc_copy_op_array(NULL, op_array, apc_sma_malloc, apc_sma_free TSRMLS_CC))) { - apc_cache_expunge(apc_cache,t); - apc_cache_expunge(apc_user_cache,t); - APCG(mem_size_ptr) = NULL; -#if NONBLOCKING_LOCK_AVAILABLE - if(APCG(write_lock)) { - apc_cache_write_unlock(apc_cache); - } -#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - return op_array; - } - - if(!(alloc_functions = apc_copy_new_functions(num_functions, apc_sma_malloc, apc_sma_free TSRMLS_CC))) { - apc_free_op_array(alloc_op_array, apc_sma_free); - apc_cache_expunge(apc_cache,t); - apc_cache_expunge(apc_user_cache,t); - APCG(mem_size_ptr) = NULL; -#if NONBLOCKING_LOCK_AVAILABLE - if(APCG(write_lock)) { - apc_cache_write_unlock(apc_cache); - } -#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - return op_array; - } - if(!(alloc_classes = apc_copy_new_classes(op_array, num_classes, apc_sma_malloc, apc_sma_free TSRMLS_CC))) { - apc_free_op_array(alloc_op_array, apc_sma_free); - apc_free_functions(alloc_functions, apc_sma_free); - apc_cache_expunge(apc_cache,t); - apc_cache_expunge(apc_user_cache,t); - APCG(mem_size_ptr) = NULL; -#if NONBLOCKING_LOCK_AVAILABLE - if(APCG(write_lock)) { - apc_cache_write_unlock(apc_cache); - } -#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - return op_array; - } - - path = h->opened_path; - if(!path) path=h->filename; - -#ifdef __DEBUG_APC__ - fprintf(stderr,"2. h->opened_path=[%s] h->filename=[%s]\n", h->opened_path?h->opened_path:"null",h->filename); -#endif - - if(!(cache_entry = apc_cache_make_file_entry(path, alloc_op_array, alloc_functions, alloc_classes))) { - apc_free_op_array(alloc_op_array, apc_sma_free); - apc_free_functions(alloc_functions, apc_sma_free); - apc_free_classes(alloc_classes, apc_sma_free); - apc_cache_expunge(apc_cache,t); - apc_cache_expunge(apc_user_cache,t); - APCG(mem_size_ptr) = NULL; -#if NONBLOCKING_LOCK_AVAILABLE - if(APCG(write_lock)) { - apc_cache_write_unlock(apc_cache); - } -#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - return op_array; - } - APCG(mem_size_ptr) = NULL; - cache_entry->mem_size = mem_size; - - if ((ret = apc_cache_insert(apc_cache, key, cache_entry, t)) != 1) { - apc_cache_free_entry(cache_entry); - if(ret==-1) { - apc_cache_expunge(apc_cache,t); - apc_cache_expunge(apc_user_cache,t); - } - } - -#if NONBLOCKING_LOCK_AVAILABLE - if(APCG(write_lock)) { - apc_cache_write_unlock(apc_cache); - } -#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - - return op_array; -} -/* }}} */ - -/* {{{ module init and shutdown */ - -int apc_module_init(int module_number TSRMLS_DC) -{ - /* apc initialization */ -#if APC_MMAP - apc_sma_init(APCG(shm_segments), APCG(shm_size)*1024*1024, APCG(mmap_file_mask)); -#else - apc_sma_init(APCG(shm_segments), APCG(shm_size)*1024*1024, NULL); -#endif - apc_cache = apc_cache_create(APCG(num_files_hint), APCG(gc_ttl), APCG(ttl)); - apc_user_cache = apc_cache_create(APCG(user_entries_hint), APCG(gc_ttl), APCG(user_ttl)); - - apc_compiled_filters = apc_regex_compile_array(APCG(filters)); - - /* override compilation */ - old_compile_file = zend_compile_file; - zend_compile_file = my_compile_file; - REGISTER_LONG_CONSTANT("\000apc_magic", (long)&set_compile_hook, CONST_PERSISTENT | CONST_CS); - - APCG(initialized) = 1; - return 0; -} - -int apc_module_shutdown(TSRMLS_D) -{ - if (!APCG(initialized)) - return 0; - - /* restore compilation */ - zend_compile_file = old_compile_file; - - /* - * In case we got interrupted by a SIGTERM or something else during execution - * we may have cache entries left on the stack that we need to check to make - * sure that any functions or classes these may have added to the global function - * and class tables are removed before we blow away the memory that hold them. - * - * This is merely to remove memory leak warnings - as the process is terminated - * immediately after shutdown. The following while loop can be removed without - * affecting anything else. - */ - while (apc_stack_size(APCG(cache_stack)) > 0) { - int i; - apc_cache_entry_t* cache_entry = (apc_cache_entry_t*) apc_stack_pop(APCG(cache_stack)); - if (cache_entry->data.file.functions) { - for (i = 0; cache_entry->data.file.functions[i].function != NULL; i++) { - zend_hash_del(EG(function_table), - cache_entry->data.file.functions[i].name, - cache_entry->data.file.functions[i].name_len+1); - } - } - if (cache_entry->data.file.classes) { - for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) { - zend_hash_del(EG(class_table), - cache_entry->data.file.classes[i].name, - cache_entry->data.file.classes[i].name_len+1); - } - } - apc_cache_release(apc_cache, cache_entry); - } - - apc_cache_destroy(apc_cache); - apc_cache_destroy(apc_user_cache); - apc_sma_cleanup(); - - APCG(initialized) = 0; - return 0; -} - -/* }}} */ - -/* {{{ process init and shutdown */ -int apc_process_init(int module_number TSRMLS_DC) -{ - return 0; -} - -int apc_process_shutdown(TSRMLS_D) -{ - return 0; -} -/* }}} */ - -/* {{{ apc_deactivate */ -static void apc_deactivate(TSRMLS_D) -{ - /* The execution stack was unwound, which prevented us from decrementing - * the reference counts on active cache entries in `my_execute`. - */ - while (apc_stack_size(APCG(cache_stack)) > 0) { - int i; - zend_class_entry* zce = NULL; - void ** centry = (void*)(&zce); -#ifdef ZEND_ENGINE_2 - zend_class_entry** pzce = NULL; -#endif - - apc_cache_entry_t* cache_entry = - (apc_cache_entry_t*) apc_stack_pop(APCG(cache_stack)); - - if (cache_entry->data.file.classes) { - for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) { -#ifdef ZEND_ENGINE_2 - centry = (void**)&pzce; /* a triple indirection to get zend_class_entry*** */ -#endif - if(zend_hash_find(EG(class_table), - cache_entry->data.file.classes[i].name, - cache_entry->data.file.classes[i].name_len+1, - (void**)centry) == FAILURE) - { - /* double inclusion of conditional classes ends up failing - * this lookup the second time around. - */ - continue; - } - -#ifdef ZEND_ENGINE_2 - zce = *pzce; -#endif - zend_hash_del(EG(class_table), - cache_entry->data.file.classes[i].name, - cache_entry->data.file.classes[i].name_len+1); - - apc_free_class_entry_after_execution(zce); - } - } - apc_cache_release(apc_cache, cache_entry); - } - -} -/* }}} */ - -/* {{{ request init and shutdown */ - -int apc_request_init(TSRMLS_D) -{ - apc_stack_clear(APCG(cache_stack)); - APCG(slam_rand) = -1; - APCG(copied_zvals) = NULL; - -#ifdef APC_FILEHITS - ALLOC_INIT_ZVAL(APCG(filehits)); - array_init(APCG(filehits)); -#endif - - return 0; -} - -int apc_request_shutdown(TSRMLS_D) -{ - apc_deactivate(TSRMLS_C); - -#ifdef APC_FILEHITS - zval_ptr_dtor(&APCG(filehits)); -#endif - - return 0; -} - -/* }}} */ - - -/* - * 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 - */ diff --git a/apc_main.h b/apc_main.h deleted file mode 100644 index 3d8d435..0000000 --- a/apc_main.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | George Schlossnagle | - | Rasmus Lerdorf | - | Arun C. Murthy | - | Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - 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_main.h,v 3.9.2.2 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_MAIN_H -#define APC_MAIN_H - -/* - * This module provides the primary interface between PHP and APC. - */ - -extern int apc_module_init(int module_number TSRMLS_DC); -extern int apc_module_shutdown(TSRMLS_D); -extern int apc_process_init(int module_number TSRMLS_DC); -extern int apc_process_shutdown(TSRMLS_D); -extern int apc_request_init(TSRMLS_D); -extern int apc_request_shutdown(TSRMLS_D); - -#endif - -/* - * 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 - */ diff --git a/apc_mmap.c b/apc_mmap.c deleted file mode 100644 index f29de88..0000000 --- a/apc_mmap.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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: Rasmus Lerdorf | - +----------------------------------------------------------------------+ - - 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_mmap.c,v 3.7.2.2 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc.h" - -#if APC_MMAP - -#include -#include -#include - -/* - * Some operating systems (like FreeBSD) have a MAP_NOSYNC flag that - * tells whatever update daemons might be running to not flush dirty - * vm pages to disk unless absolutely necessary. My guess is that - * most systems that don't have this probably default to only synching - * to disk when absolutely necessary. - */ -#ifndef MAP_NOSYNC -#define MAP_NOSYNC 0 -#endif - -void *apc_mmap(char *file_mask, size_t size) -{ - void* shmaddr; /* the shared memory address */ - - /* If no filename was provided, do an anonymous mmap */ - if(!file_mask || (file_mask && !strlen(file_mask))) { - shmaddr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); - } else { - int fd; - - /* - * If the filemask contains .shm we try to do a POSIX-compliant shared memory - * backed mmap which should avoid synchs on some platforms. At least on - * FreeBSD this implies MAP_NOSYNC and on Linux it is equivalent of mmap'ing - * a file in a mounted shmfs. For this to work on Linux you need to make sure - * you actually have shmfs mounted. Also on Linux, make sure the file_mask you - * pass in has a leading / and no other /'s. eg. /apc.shm.XXXXXX - * On FreeBSD these are mapped onto the regular filesystem so you can put whatever - * path you want here. - */ - if(strstr(file_mask,".shm")) { - mktemp(file_mask); - fd = shm_open(file_mask, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); - if(fd == -1) { - apc_eprint("apc_mmap: shm_open on %s failed:", file_mask); - return (void *)-1; - } - if (ftruncate(fd, size) < 0) { - close(fd); - shm_unlink(file_mask); - apc_eprint("apc_mmap: ftruncate failed:"); - return (void *)-1; - } - shmaddr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - shm_unlink(file_mask); - close(fd); - } - /* - * Support anonymous mmap through the /dev/zero interface as well - */ - else if(!strcmp(file_mask,"/dev/zero")) { - fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR); - if(fd == -1) { - apc_eprint("apc_mmap: open on /dev/zero failed:"); - return (void *)-1; - } - shmaddr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - close(fd); - } - /* - * Otherwise we do a normal filesystem mmap - */ - else { - fd = mkstemp(file_mask); - if(fd == -1) { - apc_eprint("apc_mmap: mkstemp on %s failed:", file_mask); - return (void *)-1; - } - if (ftruncate(fd, size) < 0) { - close(fd); - unlink(file_mask); - apc_eprint("apc_mmap: ftruncate failed:"); - } - shmaddr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NOSYNC, fd, 0); - close(fd); - unlink(file_mask); - } - } - if((long)shmaddr == -1) { - apc_eprint("apc_mmap: mmap failed:"); - } - return shmaddr; -} - -void apc_unmap(void* shmaddr, size_t size) -{ - if (munmap(shmaddr, size) < 0) { - apc_wprint("apc_unmap: munmap failed:"); - } -} - -#endif - -/* - * 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 - */ diff --git a/apc_php.h b/apc_php.h deleted file mode 100644 index 1263525..0000000 --- a/apc_php.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | George Schlossnagle | - | Rasmus Lerdorf | - | Arun C. Murthy | - | Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - 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_php.h,v 3.10.2.2 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_PHP_H -#define APC_PHP_H - -/* - * The purpose of this header file is to include all PHP and Zend headers that - * are typically needed elsewhere in APC. This makes it easy to insure that - * all required headers are available. - */ - -#include "php.h" -#include "zend.h" -#include "zend_API.h" -#include "zend_compile.h" -#include "zend_hash.h" -#include "zend_extensions.h" - -#if ZEND_MODULE_API_NO > 20060613 -#define ZEND_ENGINE_2_3 -#endif -#if ZEND_MODULE_API_NO > 20050922 -#define ZEND_ENGINE_2_2 -#endif -#if ZEND_MODULE_API_NO > 20050921 -#define ZEND_ENGINE_2_1 -#endif -#ifdef ZEND_ENGINE_2_1 -#include "zend_vm.h" -#endif - -#include "rfc1867.h" - -#endif - -/* - * 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 - */ diff --git a/apc_pool.c b/apc_pool.c deleted file mode 100644 index 1d12258..0000000 --- a/apc_pool.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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: Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - This software was contributed to PHP by Yahoo! Inc. in 2008. - - Future revisions and derivatives of this source code must acknowledge - Yahoo! 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_pool.c,v 3.3 2008/01/09 12:30:39 gopalv Exp $ */ - - -#include "apc_pool.h" -#include - -#ifdef HAVE_VALGRIND_MEMCHECK_H -#include -#endif - -/* {{{ typedefs */ -typedef struct _pool_block -{ - size_t avail; - size_t capacity; - unsigned char *mark; - struct _pool_block *next; - unsigned :0; /* this should align to word */ - unsigned char data[0]; -}pool_block; - -/* - parts in ? are optional and turned on for fun, memory loss, - and for something else that I forgot about ... ah, debugging - - |--------> data[0] |<-- non word boundary (too) - +-------------+--------------+-----------+-------------+-------------->>> - | pool_block | ?sizeinfo<1> | block<1> | ?redzone<1> | ?sizeinfo<2> - | | (size_t) | | padded left | - +-------------+--------------+-----------+-------------+-------------->>> - */ - -struct _apc_pool -{ - apc_malloc_t allocate; - apc_free_t deallocate; - - size_t dsize; - void *owner; - - struct - { - unsigned int redzones:1; - unsigned int sizeinfo:1; - } options; - - pool_block *head; -}; -/* }}} */ - -/* {{{ redzone code */ -static const unsigned char decaff[] = { - 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad, - 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad, - 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad, - 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad -}; - -/* a redzone is at least 4 (0xde,0xca,0xc0,0xff) bytes */ -#define REDZONE_SIZE(size) \ - ((ALIGNWORD((size)) > ((size) + 4)) ? \ - (ALIGNWORD((size)) - (size)) : /* does not change realsize */\ - ALIGNWORD((size)) - (size) + ALIGNWORD((sizeof(char)))) /* adds 1 word to realsize */ - -#define SIZEINFO_SIZE ALIGNWORD(sizeof(size_t)) - -#define MARK_REDZONE(block, redsize) do {\ - memcpy(block, decaff, redsize );\ - } while(0) - -#define CHECK_REDZONE(block, redsize) (memcmp(block, decaff, redsize) == 0) - -/* }}} */ - -#define APC_POOL_OPTION(pool, option) ((pool)->options.option) - -/* {{{ create_pool_block */ -static pool_block* create_pool_block(apc_pool *pool, size_t size) -{ - size_t realsize = sizeof(pool_block) + ALIGNWORD(size); - - pool_block* entry = pool->allocate(realsize); - - entry->avail = entry->capacity = size; - - entry->mark = entry->data; - - entry->next = pool->head; - - pool->head = entry; - - return entry; -} -/* }}} */ - -/* {{{ apc_pool_create */ -apc_pool* apc_pool_create(apc_pool_type pool_type, - apc_malloc_t allocate, - apc_free_t deallocate) -{ - apc_pool* pool = NULL; - size_t dsize = 0; - - /* sanity checks */ - assert(sizeof(decaff) > REDZONE_SIZE(ALIGNWORD(sizeof(char)))); - assert(sizeof(pool_block) == ALIGNWORD(sizeof(pool_block))); - - assert(APC_POOL_SIZE_MASK & (APC_POOL_SIZEINFO | APC_POOL_REDZONES) == 0); - - switch(pool_type & APC_POOL_SIZE_MASK) { - case APC_SMALL_POOL: - dsize = 512; - break; - - case APC_LARGE_POOL: - dsize = 8192; - break; - - case APC_MEDIUM_POOL: - dsize = 4096; - break; - - default: - return NULL; - } - - pool = (apc_pool*)allocate(sizeof(apc_pool)); - - if(!pool) { - return NULL; - } - - pool->allocate = allocate; - pool->deallocate = deallocate; - pool->dsize = dsize; - pool->head = NULL; - - APC_POOL_OPTION(pool, redzones) = (pool_type & APC_POOL_REDZONES) != 0; - APC_POOL_OPTION(pool, sizeinfo) = (pool_type & APC_POOL_SIZEINFO) != 0; - - if(!create_pool_block(pool, dsize)) { - deallocate(pool); - return NULL; - } - - return pool; -} -/* }}} */ - -/* {{{ apc_pool_destroy */ -void apc_pool_destroy(apc_pool *pool) -{ - - apc_free_t deallocate = pool->deallocate; - pool_block *entry; - pool_block *tmp; - - entry = pool->head; - - while(entry != NULL) { - tmp = entry->next; - deallocate(entry); - entry = tmp; - } - - deallocate(pool); -} -/* }}} */ - -/* {{{ apc_pool_alloc */ -void* apc_pool_alloc(apc_pool *pool, size_t size) -{ - unsigned char *p = NULL; - size_t realsize = ALIGNWORD(size); - size_t poolsize; - unsigned char *redzone = NULL; - size_t redsize = 0; - size_t *sizeinfo= NULL; - - pool_block *entry; - - - if(APC_POOL_OPTION(pool, redzones)) { - redsize = REDZONE_SIZE(size); /* redsize might be re-using word size padding */ - realsize = size + redsize; /* recalculating realsize */ - } else { - redsize = realsize - size; /* use padding space */ - } - - if(APC_POOL_OPTION(pool, sizeinfo)) { - realsize += ALIGNWORD(sizeof(size_t)); - } - - - for(entry = pool->head; entry != NULL; entry = entry->next) { - if(entry->avail >= realsize) { - goto found; - } - } - - poolsize = ALIGNSIZE(realsize, pool->dsize); - - entry = create_pool_block(pool, poolsize); - - if(!entry) { - return NULL; - } - -found: - p = entry->mark; - - if(APC_POOL_OPTION(pool, sizeinfo)) { - sizeinfo = (size_t*)p; - p += SIZEINFO_SIZE; - *sizeinfo = size; - } - - redzone = p + size; - - if(APC_POOL_OPTION(pool, redzones)) { - MARK_REDZONE(redzone, redsize); - } - -#ifdef VALGRIND_MAKE_MEM_NOACCESS - if(redsize != 0) { - VALGRIND_MAKE_MEM_NOACCESS(redzone, redsize); - } -#endif - - entry->avail -= realsize; - entry->mark += realsize; - -#ifdef VALGRIND_MAKE_MEM_UNDEFINED - /* need to write before reading data off this */ - VALGRIND_MAKE_MEM_UNDEFINED(p, size); -#endif - - return (void*)p; -} -/* }}} */ - -/* {{{ apc_pool_free */ -/* - * free does not do anything other than - * check for redzone values when free'ing - * data areas. - */ -void apc_pool_free(apc_pool *pool, void *p) -{ - if(!APC_POOL_OPTION(pool, sizeinfo) || - !APC_POOL_OPTION(pool, redzones)) { - } -} -/* }}} */ - -/* {{{ apc_pool_check_integrity */ -/* - * Checking integrity at runtime, does an - * overwrite check only when the sizeinfo - * is set. - */ -int apc_pool_check_integrity(apc_pool *pool) -{ - pool_block *entry; - size_t *sizeinfo = NULL; - unsigned char *start; - size_t realsize; - unsigned char *redzone; - size_t redsize; - - for(entry = pool->head; entry != NULL; entry = entry->next) { - start = (unsigned char *)entry + ALIGNWORD(sizeof(pool_block)); - if((entry->mark - start) != (entry->capacity - entry->avail)) { - return 0; - } - } - - if(!APC_POOL_OPTION(pool, sizeinfo) || - !APC_POOL_OPTION(pool, redzones)) { - return 1; - } - - for(entry = pool->head; entry != NULL; entry = entry->next) { - start = (unsigned char *)entry + ALIGNWORD(sizeof(pool_block)); - - while(start < entry->mark) { - sizeinfo = (size_t*)start; - /* redzone starts where real data ends, in a non-word boundary - * redsize is at least 4 bytes + whatever's needed to make it - * to another word boundary. - */ - redzone = start + SIZEINFO_SIZE + (*sizeinfo); - redsize = REDZONE_SIZE(*sizeinfo); - if(!CHECK_REDZONE(redzone, redsize)) - { - /* - fprintf(stderr, "Redzone check failed for %p\n", - start + ALIGNWORD(sizeof(size_t)));*/ - return 0; - } - realsize = SIZEINFO_SIZE + *sizeinfo + redsize; - start += realsize; - } - } - - 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 - */ diff --git a/apc_pool.h b/apc_pool.h deleted file mode 100644 index deec2c8..0000000 --- a/apc_pool.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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: Gopal Vijayaraghavan | - +----------------------------------------------------------------------+ - - This software was contributed to PHP by Yahoo! Inc. in 2008. - - Future revisions and derivatives of this source code must acknowledge - Yahoo! 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_pool.h,v 3.3 2008/01/09 12:30:39 gopalv Exp $ */ - -#ifndef APC_POOL_H -#define APC_POOL_H - -#include "apc.h" -#include "apc_sma.h" - -typedef enum { - APC_SMALL_POOL = 0x1, - APC_MEDIUM_POOL = 0x2, - APC_LARGE_POOL = 0x3, - APC_POOL_SIZE_MASK = 0x7, /* waste a bit */ - APC_POOL_REDZONES = 0x08, - APC_POOL_SIZEINFO = 0x10, - APC_POOL_OPT_MASK = 0x18 -} apc_pool_type; - -typedef struct _apc_pool apc_pool; - -extern apc_pool* apc_pool_create(apc_pool_type pool_type, - apc_malloc_t allocate, - apc_free_t deallocate); - - -extern void apc_pool_destroy(apc_pool *pool); -extern void* apc_pool_alloc(apc_pool *pool, size_t size); -extern void apc_pool_free(apc_pool *pool, void *ptr); -extern int apc_pool_check_integrity(apc_pool *pool); - -#endif diff --git a/apc_pthreadmutex.c b/apc_pthreadmutex.c deleted file mode 100644 index f6b8c77..0000000 --- a/apc_pthreadmutex.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - */ - -/* $Id: apc_pthreadmutex.c,v 3.3.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_pthreadmutex.h" - -#ifdef APC_PTHREADMUTEX_LOCKS - -pthread_mutex_t *apc_pthreadmutex_create(pthread_mutex_t *lock) -{ - int result; - pthread_mutexattr_t* attr; - attr = malloc(sizeof(pthread_mutexattr_t)); - - result = pthread_mutexattr_init(attr); - if(result == ENOMEM) { - apc_eprint("pthread mutex error: Insufficient memory exists to create the mutex attribute object."); - } else if(result == EINVAL) { - apc_eprint("pthread mutex error: attr does not point to writeable memory."); - } else if(result == EFAULT) { - apc_eprint("pthread mutex error: attr is an invalid pointer."); - } - -#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP - result = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_ADAPTIVE_NP); - if (result == EINVAL) { - apc_eprint("pthread_mutexattr_settype: unable to set adaptive mutexes"); - } -#endif - - /* pthread_mutexattr_settype(attr, PTHREAD_MUTEX_ERRORCHECK); */ - result = pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED); - if(result == EINVAL) { - apc_eprint("pthread mutex error: attr is not an initialized mutex attribute object, or pshared is not a valid process-shared state setting."); - } else if(result == EFAULT) { - apc_eprint("pthread mutex error: attr is an invalid pointer."); - } else if(result == ENOTSUP) { - apc_eprint("pthread mutex error: pshared was set to PTHREAD_PROCESS_SHARED."); - } - - if(pthread_mutex_init(lock, attr)) { - apc_eprint("unable to initialize pthread lock"); - } - return lock; -} - -void apc_pthreadmutex_destroy(pthread_mutex_t *lock) -{ - return; /* we don't actually destroy the mutex, as it would destroy it for all processes */ -} - -void apc_pthreadmutex_lock(pthread_mutex_t *lock) -{ - int result; - result = pthread_mutex_lock(lock); - if(result == EINVAL) { - apc_eprint("unable to obtain pthread lock (EINVAL)"); - } else if(result == EDEADLK) { - apc_eprint("unable to obtain pthread lock (EDEADLK)"); - } -} - -void apc_pthreadmutex_unlock(pthread_mutex_t *lock) -{ - if(pthread_mutex_unlock(lock)) { - apc_eprint("unable to unlock pthread lock"); - } -} - -zend_bool apc_pthreadmutex_nonblocking_lock(pthread_mutex_t *lock) -{ - int rval; - rval = pthread_mutex_trylock(lock); - if(rval == EBUSY) { /* Lock is already held */ - return 0; - } else if(rval == 0) { /* Obtained lock */ - return 1; - } else { /* Other error */ - apc_eprint("unable to obtain pthread trylock"); - return 0; - } -} - - -#endif - -/* - * 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 - */ diff --git a/apc_pthreadmutex.h b/apc_pthreadmutex.h deleted file mode 100644 index 57e189a..0000000 --- a/apc_pthreadmutex.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - */ - -/* $Id: apc_pthreadmutex.h,v 3.3.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_PTHREADMUTEX_H -#define APC_PTHREADMUTEX_H - -#include "apc.h" - -#ifdef APC_PTHREADMUTEX_LOCKS - -#include - -pthread_mutex_t *apc_pthreadmutex_create(); -void apc_pthreadmutex_destroy(pthread_mutex_t *lock); -void apc_pthreadmutex_lock(pthread_mutex_t *lock); -void apc_pthreadmutex_unlock(pthread_mutex_t *lock); -zend_bool apc_pthreadmutex_nonblocking_lock(pthread_mutex_t *lock); - -#endif - -#endif - -/* - * 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 - */ diff --git a/apc_rfc1867.c b/apc_rfc1867.c deleted file mode 100644 index 466f700..0000000 --- a/apc_rfc1867.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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: Rasmus Lerdorf | - +----------------------------------------------------------------------+ - - 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_rfc1867.c,v 3.12.2.1 2008/05/11 18:57:00 rasmus Exp $*/ - -#include "apc.h" -#include "apc_globals.h" -#include "rfc1867.h" - -#ifdef PHP_WIN32 -#include "win32/time.h" -#endif - -#ifdef MULTIPART_EVENT_FORMDATA -extern int _apc_store(char *strkey, int strkey_len, const zval *val, const unsigned int ttl, const int exclusive TSRMLS_DC); - -static double my_time() { - struct timeval a; - double t; - gettimeofday(&a, NULL); - t = a.tv_sec + (a.tv_usec/1000000.00); - return t; -} - -void apc_rfc1867_progress(unsigned int event, void *event_data, void **extra TSRMLS_DC) { - static char tracking_key[64]; - static int key_length = 0; - static size_t content_length = 0; - static char filename[128]; - static char name[64]; - static char *temp_filename=NULL; - static int cancel_upload = 0; - static double start_time; - static size_t bytes_processed = 0; - static size_t prev_bytes_processed = 0; - static int update_freq = 0; - static double rate; - zval *track = NULL; - - switch (event) { - case MULTIPART_EVENT_START: - { - multipart_event_start *data = (multipart_event_start *) event_data; - content_length = data->content_length; - *tracking_key = '\0'; - *name = '\0'; - cancel_upload = 0; - temp_filename = NULL; - *filename= '\0'; - key_length = 0; - start_time = my_time(); - bytes_processed = 0; - rate = 0; - update_freq = APCG(rfc1867_freq); - if(update_freq < 0) { // frequency is a percentage, not bytes - update_freq = content_length * APCG(rfc1867_freq) / 100; - } - } - break; - - case MULTIPART_EVENT_FORMDATA: - { - int prefix_len = strlen(APCG(rfc1867_prefix)); - multipart_event_formdata *data = (multipart_event_formdata *) event_data; - if(data->name && !strncasecmp(data->name, APCG(rfc1867_name), strlen(APCG(rfc1867_name))) && data->value && data->length && data->length < sizeof(tracking_key) - prefix_len) { - strlcat(tracking_key, APCG(rfc1867_prefix), 63); - strlcat(tracking_key, *data->value, 63); - key_length = data->length + prefix_len; - bytes_processed = data->post_bytes_processed; - } - } - break; - - case MULTIPART_EVENT_FILE_START: - if(*tracking_key) { - multipart_event_file_start *data = (multipart_event_file_start *) event_data; - - bytes_processed = data->post_bytes_processed; - strncpy(filename,*data->filename,127); - temp_filename = NULL; - strncpy(name,data->name,63); - ALLOC_INIT_ZVAL(track); - array_init(track); - add_assoc_long(track, "total", content_length); - add_assoc_long(track, "current", bytes_processed); - add_assoc_string(track, "filename", filename, 1); - add_assoc_string(track, "name", name, 1); - add_assoc_long(track, "done", 0); - add_assoc_double(track, "start_time", start_time); - _apc_store(tracking_key, key_length, track, 3600, 0 TSRMLS_CC); - zval_ptr_dtor(&track); - } - break; - - case MULTIPART_EVENT_FILE_DATA: - if(*tracking_key) { - multipart_event_file_data *data = (multipart_event_file_data *) event_data; - bytes_processed = data->post_bytes_processed; - ALLOC_INIT_ZVAL(track); - array_init(track); - add_assoc_long(track, "total", content_length); - add_assoc_long(track, "current", bytes_processed); - add_assoc_string(track, "filename", filename, 1); - add_assoc_string(track, "name", name, 1); - add_assoc_long(track, "done", 0); - add_assoc_double(track, "start_time", start_time); - if(bytes_processed - prev_bytes_processed > update_freq) { - _apc_store(tracking_key, key_length, track, 3600, 0 TSRMLS_CC); - prev_bytes_processed = bytes_processed; - } - zval_ptr_dtor(&track); - } - break; - - case MULTIPART_EVENT_FILE_END: - if(*tracking_key) { - multipart_event_file_end *data = (multipart_event_file_end *) event_data; - bytes_processed = data->post_bytes_processed; - cancel_upload = data->cancel_upload; - temp_filename = data->temp_filename; - ALLOC_INIT_ZVAL(track); - array_init(track); - add_assoc_long(track, "total", content_length); - add_assoc_long(track, "current", bytes_processed); - add_assoc_string(track, "filename", filename, 1); - add_assoc_string(track, "name", name, 1); - add_assoc_string(track, "temp_filename", temp_filename, 1); - add_assoc_long(track, "cancel_upload", cancel_upload); - add_assoc_long(track, "done", 0); - add_assoc_double(track, "start_time", start_time); - _apc_store(tracking_key, key_length, track, 3600, 0 TSRMLS_CC); - zval_ptr_dtor(&track); - } - break; - - case MULTIPART_EVENT_END: - if(*tracking_key) { - double now = my_time(); - multipart_event_end *data = (multipart_event_end *) event_data; - bytes_processed = data->post_bytes_processed; - if(now>start_time) rate = 8.0*bytes_processed/(now-start_time); - else rate = 8.0*bytes_processed; /* Too quick */ - ALLOC_INIT_ZVAL(track); - array_init(track); - add_assoc_long(track, "total", content_length); - add_assoc_long(track, "current", bytes_processed); - add_assoc_double(track, "rate", rate); - add_assoc_string(track, "filename", filename, 1); - add_assoc_string(track, "name", name, 1); - if(temp_filename) { - add_assoc_string(track, "temp_filename", temp_filename, 1); - } - add_assoc_long(track, "cancel_upload", cancel_upload); - add_assoc_long(track, "done", 1); - add_assoc_double(track, "start_time", start_time); - _apc_store(tracking_key, key_length, track, 3600, 0 TSRMLS_CC); - zval_ptr_dtor(&track); - } - break; - } -} - -#endif -/* - * 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 - */ diff --git a/apc_sem.c b/apc_sem.c deleted file mode 100644 index e76ca20..0000000 --- a/apc_sem.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - 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_sem.c,v 3.16.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_sem.h" -#include "apc.h" -#include "php.h" -#include -#include -#include -#include -#include - -#if HAVE_SEMUN -/* we have semun, no need to define */ -#else -#undef HAVE_SEMUN -union semun { - int val; /* value for SETVAL */ - struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ - unsigned short *array; /* array for GETALL, SETALL */ - /* Linux specific part: */ - struct seminfo *__buf; /* buffer for IPC_INFO */ -}; -#define HAVE_SEMUN 1 -#endif - -#ifndef SEM_R -# define SEM_R 0444 -#endif -#ifndef SEM_A -# define SEM_A 0222 -#endif - -/* always use SEM_UNDO, otherwise we risk deadlock */ -#define USE_SEM_UNDO - -#ifdef USE_SEM_UNDO -# define UNDO SEM_UNDO -#else -# define UNDO 0 -#endif - -int apc_sem_create(const char* pathname, int proj, int initval) -{ - int semid; - int perms; - union semun arg; - key_t key; - - perms = 0777; - - key = IPC_PRIVATE; - if (pathname != NULL) { - if ((key = ftok(pathname, proj)) < 0) { - apc_eprint("apc_sem_create: ftok(%s,%d) failed:", pathname, proj); - } - } - - if ((semid = semget(key, 1, IPC_CREAT | IPC_EXCL | perms)) >= 0) { - /* sempahore created for the first time, initialize now */ - arg.val = initval; - if (semctl(semid, 0, SETVAL, arg) < 0) { - apc_eprint("apc_sem_create: semctl(%d,...) failed:", semid); - } - } - else if (errno == EEXIST) { - /* sempahore already exists, don't initialize */ - if ((semid = semget(key, 1, perms)) < 0) { - apc_eprint("apc_sem_create: semget(%u,...) failed:", key); - } - /* insert here */ - } - else { - apc_eprint("apc_sem_create: semget(%u,...) failed:", key); - } - - return semid; -} - -void apc_sem_destroy(int semid) -{ - /* we expect this call to fail often, so we do not check */ - union semun arg; - semctl(semid, 0, IPC_RMID, arg); -} - -void apc_sem_lock(int semid) -{ - struct sembuf op; - - op.sem_num = 0; - op.sem_op = -1; - op.sem_flg = UNDO; - - if (semop(semid, &op, 1) < 0) { - if (errno != EINTR) { - apc_eprint("apc_sem_lock: semop(%d) failed:", semid); - } - } -} - -void apc_sem_unlock(int semid) -{ - struct sembuf op; - - op.sem_num = 0; - op.sem_op = 1; - op.sem_flg = UNDO; - - if (semop(semid, &op, 1) < 0) { - if (errno != EINTR) { - apc_eprint("apc_sem_unlock: semop(%d) failed:", semid); - } - } -} - -void apc_sem_wait_for_zero(int semid) -{ - struct sembuf op; - - op.sem_num = 0; - op.sem_op = 0; - op.sem_flg = UNDO; - - if (semop(semid, &op, 1) < 0) { - if (errno != EINTR) { - apc_eprint("apc_sem_waitforzero: semop(%d) failed:", semid); - } - } -} - -int apc_sem_get_value(int semid) -{ - union semun arg; - unsigned short val[1]; - - arg.array = val; - if (semctl(semid, 0, GETALL, arg) < 0) { - apc_eprint("apc_sem_getvalue: semctl(%d,...) failed:", semid); - } - return val[0]; -} - -/* - * 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 - */ diff --git a/apc_sem.h b/apc_sem.h deleted file mode 100644 index c366b6f..0000000 --- a/apc_sem.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - 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_sem.h,v 3.6.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_SEM_H -#define APC_SEM_H - -/* Wrapper functions for SysV sempahores */ - -extern int apc_sem_create(const char* pathname, int proj, int initval); -extern void apc_sem_destroy(int semid); -extern void apc_sem_lock(int semid); -extern void apc_sem_unlock(int semid); -extern void apc_sem_wait_for_zero(int semid); -extern int apc_sem_get_value(int semid); - -#endif - -/* - * 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 - */ diff --git a/apc_shm.c b/apc_shm.c deleted file mode 100644 index a6a27c5..0000000 --- a/apc_shm.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | Rasmus Lerdorf | - +----------------------------------------------------------------------+ - - 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_shm.c,v 3.11.2.2 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_shm.h" -#include "apc.h" -#ifdef PHP_WIN32 -/* shm functions are available in TSRM */ -#include -#define key_t long -#else -#include -#include -#include -#endif - -#ifndef SHM_R -# define SHM_R 0444 /* read permission */ -#endif -#ifndef SHM_A -# define SHM_A 0222 /* write permission */ -#endif - -int apc_shm_create(const char* pathname, int proj, size_t size) -{ - int shmid; /* shared memory id */ - int oflag; /* permissions on shm */ - key_t key; /* shm key returned by ftok */ - - key = IPC_PRIVATE; -#ifndef PHP_WIN32 - /* no ftok yet for win32 */ - if (pathname != NULL) { - if ((key = ftok(pathname, proj)) < 0) { - apc_eprint("apc_shm_create: ftok failed:"); - } - } -#endif - - oflag = IPC_CREAT | SHM_R | SHM_A; - if ((shmid = shmget(key, size, oflag)) < 0) { - apc_eprint("apc_shm_create: shmget(%d, %d, %d) failed: %s. It is possible that the chosen SHM segment size is higher than the operation system allows. Linux has usually a default limit of 32MB per segment.", key, size, oflag, strerror(errno)); - } - - return shmid; -} - -void apc_shm_destroy(int shmid) -{ - /* we expect this call to fail often, so we do not check */ - shmctl(shmid, IPC_RMID, 0); -} - -void* apc_shm_attach(int shmid) -{ - void* shmaddr; /* the shared memory address */ - - if ((long)(shmaddr = shmat(shmid, 0, 0)) == -1) { - apc_eprint("apc_shm_attach: shmat failed:"); - } - - /* - * We set the shmid for removal immediately after attaching to it. The - * segment won't disappear until all processes have detached from it. - */ - apc_shm_destroy(shmid); - return shmaddr; -} - -void apc_shm_detach(void* shmaddr) -{ - if (shmdt(shmaddr) < 0) { - apc_eprint("apc_shm_detach: shmdt failed:"); - } -} - -/* - * 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 - */ diff --git a/apc_shm.h b/apc_shm.h deleted file mode 100644 index bb34af9..0000000 --- a/apc_shm.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - 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_shm.h,v 3.8.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_SHM_H -#define APC_SHM_H - -#include -#ifdef PHP_WIN32 -#include -#endif - -/* Wrapper functions for unix shared memory */ - -extern int apc_shm_create(const char* name, int proj, size_t size); -extern void apc_shm_destroy(int shmid); -extern void* apc_shm_attach(int shmid); -extern void apc_shm_detach(void* shmaddr); - -#endif - -/* - * 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 - */ diff --git a/apc_signal.c b/apc_signal.c deleted file mode 100644 index 7db2ef9..0000000 --- a/apc_signal.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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: Lucas Nealan | - +----------------------------------------------------------------------+ - - This software was contributed to PHP by Facebook Inc. in 2007. - - Future revisions and derivatives of this source code must acknowledge - Facebook 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_signal.c,v 1.2.2.3 2008/05/11 18:57:00 rasmus Exp $ */ - - /* Allows apc to install signal handlers and maintain signalling - to already registered handlers. Registers all signals that - coredump by default and unmaps the shared memory segment - before the coredump. Note: PHP module init is called before - signals are set by Apache and thus apc_set_signals should - be called in request init (RINIT) - */ - -#include -#include "apc_globals.h" -#include "apc_sma.h" -#include "apc_signal.h" - -static apc_signal_info_t apc_signal_info = {0}; - -static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*)); -static void apc_rehandle_signal(int signo, siginfo_t *siginfo, void *context); -static void apc_core_unmap(int signo, siginfo_t *siginfo, void *context); - -/* {{{ apc_core_unmap - * Coredump signal handler, unmaps shm and calls previously installed handlers - */ -static void apc_core_unmap(int signo, siginfo_t *siginfo, void *context) -{ - apc_sma_cleanup(); - apc_rehandle_signal(signo, siginfo, context); - -#if !defined(WIN32) && !defined(NETWARE) - kill(getpid(), signo); -#else - raise(signo); -#endif -} /* }}} */ - -/* {{{ apc_rehandle_signal - * Call the previously registered handler for a signal - */ -static void apc_rehandle_signal(int signo, siginfo_t *siginfo, void *context) -{ - int i; - apc_signal_entry_t p_sig = {0}; - - for (i=0; (i < apc_signal_info.installed && p_sig.signo != signo); i++) { - p_sig = *apc_signal_info.prev[i]; - if (p_sig.signo == signo) { - if (p_sig.siginfo) { - (*(void (*)(int, siginfo_t*, void*))p_sig.handler)(signo, siginfo, context); - } else { - (*(void (*)(int))p_sig.handler)(signo); - } - } - } - -} /* }}} */ - -/* {{{ apc_register_signal - * Set a handler for a previously installed signal and save so we can - * callback when handled - */ -static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*)) -{ -#if HAVE_SIGACTION - struct sigaction sa = {{0}}; - apc_signal_entry_t p_sig = {0}; - - if (sigaction(signo, NULL, &sa) == 0) { - if ((void*)sa.sa_handler == (void*)handler) { - return SUCCESS; - } - - if (sa.sa_handler != SIG_ERR && sa.sa_handler != SIG_DFL && sa.sa_handler != SIG_IGN) { - p_sig.signo = signo; - p_sig.siginfo = ((sa.sa_flags & SA_SIGINFO) == SA_SIGINFO); - p_sig.handler = (void *)sa.sa_handler; - - apc_signal_info.prev = (apc_signal_entry_t **)apc_erealloc(apc_signal_info.prev, (apc_signal_info.installed+1)*sizeof(apc_signal_entry_t *)); - apc_signal_info.prev[apc_signal_info.installed] = (apc_signal_entry_t *)apc_emalloc(sizeof(apc_signal_entry_t)); - *apc_signal_info.prev[apc_signal_info.installed++] = p_sig; - } else { - /* inherit flags and mask if already set */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_flags |= SA_SIGINFO; /* we'll use a siginfo handler */ -#if defined(SA_ONESHOT) - sa.sa_flags = SA_ONESHOT; -#elif defined(SA_RESETHAND) - sa.sa_flags = SA_RESETHAND; -#endif - } - sa.sa_handler = (void*)handler; - - if (sigaction(signo, &sa, NULL) < 0) { - apc_wprint("Error installing apc signal handler for %d", signo); - } - - return SUCCESS; - } -#endif - return FAILURE; -} /* }}} */ - -/* {{{ apc_set_signals - * Install our signal handlers */ -void apc_set_signals(TSRMLS_D) -{ - if (APCG(coredump_unmap) && apc_signal_info.installed == 0) { - /* ISO C standard signals that coredump */ - apc_register_signal(SIGSEGV, apc_core_unmap); - apc_register_signal(SIGABRT, apc_core_unmap); - apc_register_signal(SIGFPE, apc_core_unmap); - apc_register_signal(SIGILL, apc_core_unmap); - /* extended signals that coredump */ -#ifdef SIGBUS - apc_register_signal(SIGBUS, apc_core_unmap); -#endif -#ifdef SIGABORT - apc_register_signal(SIGABORT, apc_core_unmap); -#endif -#ifdef SIGEMT - apc_register_signal(SIGEMT, apc_core_unmap); -#endif -#ifdef SIGIOT - apc_register_signal(SIGIOT, apc_core_unmap); -#endif -#ifdef SIGQUIT - apc_register_signal(SIGQUIT, apc_core_unmap); -#endif -#ifdef SIGSYS - apc_register_signal(SIGSYS, apc_core_unmap); -#endif -#ifdef SIGTRAP - apc_register_signal(SIGTRAP, apc_core_unmap); -#endif -#ifdef SIGXCPU - apc_register_signal(SIGXCPU, apc_core_unmap); -#endif -#ifdef SIGXFSZ - apc_register_signal(SIGXFSZ, apc_core_unmap); -#endif - } -} /* }}} */ - -/* {{{ apc_set_signals - * cleanup signals for shutdown */ -void apc_shutdown_signals() -{ - int i=0; - if (apc_signal_info.installed > 0) { - for (i=0; (i < apc_signal_info.installed); i++) { - apc_efree(apc_signal_info.prev[i]); - } - apc_efree(apc_signal_info.prev); - apc_signal_info.installed = 0; /* just in case */ - } -} - -/* - * 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 - */ diff --git a/apc_signal.h b/apc_signal.h deleted file mode 100644 index 46d65be..0000000 --- a/apc_signal.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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: Lucas Nealan | - +----------------------------------------------------------------------+ - - */ - -/* $Id: apc_signal.h,v 1.1.2.2 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_SIGNAL_H -#define APC_SIGNAL_H - -#include "apc.h" -#include "apc_php.h" - -typedef struct apc_signal_entry_t { - int signo; /* signal number */ - int siginfo; /* siginfo style handler calling */ - void* handler; /* signal handler */ -} apc_signal_entry_t; - -typedef struct apc_signal_info_t { - int installed; /* How many signals we've installed handles for */ - apc_signal_entry_t **prev; /* Previous signal handlers */ -} apc_signal_info_t; - -void apc_set_signals(TSRMLS_D); -void apc_shutdown_signals(); - -#endif - -/* - * 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 - */ diff --git a/apc_sma.c b/apc_sma.c deleted file mode 100644 index b8f61aa..0000000 --- a/apc_sma.c +++ /dev/null @@ -1,635 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | Rasmus Lerdorf | - +----------------------------------------------------------------------+ - - 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_sma.c,v 1.69.2.4 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_sma.h" -#include "apc.h" -#include "apc_globals.h" -#include "apc_lock.h" -#include "apc_shm.h" -#include "apc_cache.h" -#include -#if APC_MMAP -void *apc_mmap(char *file_mask, size_t size); -void apc_unmap(void* shmaddr, size_t size); -#endif - -#ifdef HAVE_VALGRIND_MEMCHECK_H -#include -#endif - -/* {{{ locking macros */ -#define LOCK(c) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lck_lock(c); } -#define RDLOCK(c) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lck_rdlock(c); } -#define UNLOCK(c) { apc_lck_unlock(c); HANDLE_UNBLOCK_INTERRUPTIONS(); } -/* }}} */ - -enum { DEFAULT_NUMSEG=1, DEFAULT_SEGSIZE=30*1024*1024 }; - -static int sma_initialized = 0; /* true if the sma has been initialized */ -static unsigned int sma_numseg; /* number of shm segments to allow */ -static size_t sma_segsize; /* size of each shm segment */ -static size_t* sma_segments; /* array of shm segment ids */ -static void** sma_shmaddrs; /* array of shm segment addresses */ -static int sma_lastseg = 0; /* index of MRU segment */ - -typedef struct header_t header_t; -struct header_t { - apc_lck_t sma_lock; /* segment lock, MUST BE ALIGNED for futex locks */ - size_t segsize; /* size of entire segment */ - size_t avail; /* bytes available (not necessarily contiguous) */ - size_t nfoffset; /* start next fit search from this offset */ -#if ALLOC_DISTRIBUTION - size_t adist[30]; -#endif -}; - - -/* do not enable for threaded http servers */ -/* #define __APC_SMA_DEBUG__ 1 */ - -#ifdef __APC_SMA_DEBUG__ -/* global counter for identifying blocks - * Technically it is possible to do the same - * using offsets, but double allocations of the - * same offset can happen. */ -static volatile size_t block_id = 0; -#endif - -#define APC_SMA_CANARIES 1 - -typedef struct block_t block_t; -struct block_t { - size_t size; /* size of this block */ - size_t next; /* offset in segment of next free block */ -#ifdef APC_SMA_CANARIES - size_t canary; /* canary to check for memory overwrites */ -#endif -#ifdef __APC_SMA_DEBUG__ - size_t id; /* identifier for the memory block */ -#endif -}; - -/* The macros BLOCKAT and OFFSET are used for convenience throughout this - * module. Both assume the presence of a variable shmaddr that points to the - * beginning of the shared memory segment in question. */ - -#define BLOCKAT(offset) ((block_t*)((char *)shmaddr + offset)) -#define OFFSET(block) ((size_t)(((char*)block) - (char*)shmaddr)) - -/* Canary macros for setting, checking and resetting memory canaries */ -#ifdef APC_SMA_CANARIES - #define SET_CANARY(v) (v)->canary = 0x42424242 - #define CHECK_CANARY(v) assert((v)->canary == 0x42424242) - #define RESET_CANARY(v) (v)->canary = -42 -#else - #define SET_CANARY(v) - #define CHECK_CANARY(v) - #define RESET_CANARY(v) -#endif - - -/* {{{ MINBLOCKSIZE */ -#define MINBLOCKSIZE (ALIGNWORD(1) + ALIGNWORD(sizeof(block_t))) -/* }}} */ - -/* {{{ sma_allocate: tries to allocate size bytes in a segment */ -static size_t sma_allocate(void* shmaddr, size_t size) -{ - header_t* header; /* header of shared memory segment */ - block_t* prv; /* block prior to working block */ - block_t* cur; /* working block in list */ - block_t* prvnextfit; /* block before next fit */ - size_t realsize; /* actual size of block needed, including header */ - size_t last_offset; /* save the last search offset */ - int wrapped=0; - const size_t block_size = ALIGNWORD(sizeof(struct block_t)); - - realsize = ALIGNWORD(size + block_size); - - /* - * First, insure that the segment contains at least realsize free bytes, - * even if they are not contiguous. - */ - header = (header_t*) shmaddr; - if (header->avail < realsize) { - return -1; - } - - prvnextfit = 0; /* initially null (no fit) */ - last_offset = 0; - - /* If we have a next fit offset, start searching from there */ - if(header->nfoffset) { - prv = BLOCKAT(header->nfoffset); - /* if prv is the last block, jump to the beginning */ - if(prv->next == 0) { - prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); - wrapped = 1; - } - } else { - prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); - } - - CHECK_CANARY(prv); - - while (prv->next != header->nfoffset) { - cur = BLOCKAT(prv->next); -#ifdef __APC_SMA_DEBUG__ - CHECK_CANARY(cur); -#endif - /* If it can fit realiszie bytes in cur block, stop searching */ - if (cur->size >= realsize) { - prvnextfit = prv; - break; - } - last_offset = prv->next; - prv = cur; - if(wrapped && (prv->next >= header->nfoffset)) break; - - /* Check to see if we need to wrap around and search from the top */ - if(header->nfoffset && prv->next == 0) { - prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); -#ifdef __APC_SMA_DEBUG__ - CHECK_CANARY(prv); -#endif - last_offset = 0; - wrapped = 1; - } - } - - if (prvnextfit == 0) { - header->nfoffset = 0; - return -1; - } - - prv = prvnextfit; - cur = BLOCKAT(prv->next); - - CHECK_CANARY(prv); - CHECK_CANARY(cur); - - if (cur->size == realsize || (cur->size > realsize && cur->size < (realsize + (MINBLOCKSIZE * 2)))) { - /* cur is big enough for realsize, but too small to split - unlink it */ - prv->next = cur->next; - } - else { - block_t* nxt; /* the new block (chopped part of cur) */ - size_t nxtoffset; /* offset of the block currently after cur */ - size_t oldsize; /* size of cur before split */ - - /* nextfit is too big; split it into two smaller blocks */ - nxtoffset = cur->next; - oldsize = cur->size; - prv->next += realsize; /* skip over newly allocated block */ - cur->size = realsize; /* Set the size of this new block */ - nxt = BLOCKAT(prv->next); - nxt->next = nxtoffset; /* Re-link the shortened block */ - nxt->size = oldsize - realsize; /* and fix the size */ - SET_CANARY(nxt); -#ifdef __APC_SMA_DEBUG__ - nxt->id = -1; -#endif - } - - /* update the block header */ - header->avail -= cur->size; -#if ALLOC_DISTRIBUTION - header->adist[(int)(log(size)/log(2))]++; -#endif - - header->nfoffset = last_offset; - - SET_CANARY(cur); -#ifdef __APC_SMA_DEBUG__ - cur->id = ++block_id; - fprintf(stderr, "allocate(realsize=%d,size=%d,id=%d)\n", (int)(size), (int)(cur->size), cur->id); -#endif - - return OFFSET(cur) + block_size; -} -/* }}} */ - -/* {{{ sma_deallocate: deallocates the block at the given offset */ -static size_t sma_deallocate(void* shmaddr, size_t offset) -{ - header_t* header; /* header of shared memory segment */ - block_t* cur; /* the new block to insert */ - block_t* prv; /* the block before cur */ - block_t* nxt; /* the block after cur */ - size_t size; /* size of deallocated block */ - - offset -= ALIGNWORD(sizeof(struct block_t)); - assert(offset >= 0); - - /* find position of new block in free list */ - cur = BLOCKAT(offset); - prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); - - CHECK_CANARY(cur); - -#ifdef __APC_SMA_DEBUG__ - CHECK_CANARY(prv); - fprintf(stderr, "free(%p, size=%d,id=%d)\n", cur, (int)(cur->size), cur->id); -#endif - while (prv->next != 0 && prv->next < offset) { - prv = BLOCKAT(prv->next); -#ifdef __APC_SMA_DEBUG__ - CHECK_CANARY(prv); -#endif - } - - CHECK_CANARY(prv); - - /* insert new block after prv */ - cur->next = prv->next; - prv->next = offset; - -#ifdef __APC_SMA_DEBUG__ - CHECK_CANARY(cur); - cur->id = -1; -#endif - - /* update the block header */ - header = (header_t*) shmaddr; - header->avail += cur->size; - size = cur->size; - - if (((char *)prv) + prv->size == (char *) cur) { - /* cur and prv share an edge, combine them */ - prv->size += cur->size; - prv->next = cur->next; - RESET_CANARY(cur); - cur = prv; - } - - nxt = BLOCKAT(cur->next); - - if (((char *)cur) + cur->size == (char *) nxt) { - /* cur and nxt shared an edge, combine them */ - cur->size += nxt->size; - cur->next = nxt->next; -#ifdef __APC_SMA_DEBUG__ - CHECK_CANARY(nxt); - nxt->id = -1; /* assert this or set it ? */ -#endif - RESET_CANARY(nxt); - } - header->nfoffset = 0; /* Reset the next fit search marker */ - - return size; -} -/* }}} */ - -/* {{{ apc_sma_init */ - -void apc_sma_init(int numseg, size_t segsize, char *mmap_file_mask) -{ - int i; - - if (sma_initialized) { - return; - } - sma_initialized = 1; - -#if APC_MMAP - /* - * I don't think multiple anonymous mmaps makes any sense - * so force sma_numseg to 1 in this case - */ - if(!mmap_file_mask || - (mmap_file_mask && !strlen(mmap_file_mask)) || - (mmap_file_mask && !strcmp(mmap_file_mask, "/dev/zero"))) { - sma_numseg = 1; - } else { - sma_numseg = numseg > 0 ? numseg : DEFAULT_NUMSEG; - } -#else - sma_numseg = numseg > 0 ? numseg : DEFAULT_NUMSEG; -#endif - - sma_segsize = segsize > 0 ? segsize : DEFAULT_SEGSIZE; - - sma_segments = (size_t*) apc_emalloc(sma_numseg*sizeof(size_t)); - sma_shmaddrs = (void**) apc_emalloc(sma_numseg*sizeof(void*)); - - for (i = 0; i < sma_numseg; i++) { - header_t* header; - block_t* block; - void* shmaddr; - -#if APC_MMAP - sma_segments[i] = sma_segsize; - sma_shmaddrs[i] = apc_mmap(mmap_file_mask, sma_segsize); - if(sma_numseg != 1) memcpy(&mmap_file_mask[strlen(mmap_file_mask)-6], "XXXXXX", 6); -#else - sma_segments[i] = apc_shm_create(NULL, i, sma_segsize); - sma_shmaddrs[i] = apc_shm_attach(sma_segments[i]); -#endif - shmaddr = sma_shmaddrs[i]; - - header = (header_t*) shmaddr; - apc_lck_create(NULL, 0, 1, header->sma_lock); - header->segsize = sma_segsize; - header->avail = sma_segsize - ALIGNWORD(sizeof(header_t)) - ALIGNWORD(sizeof(block_t)); - header->nfoffset = 0; -#if ALLOC_DISTRIBUTION - { - int j; - for(j=0; j<30; j++) header->adist[j] = 0; - } -#endif - block = BLOCKAT(ALIGNWORD(sizeof(header_t))); - block->size = 0; - block->next = ALIGNWORD(sizeof(header_t)) + ALIGNWORD(sizeof(block_t)); - SET_CANARY(block); -#ifdef __APC_SMA_DEBUG__ - block->id = -1; -#endif - block = BLOCKAT(block->next); - block->size = header->avail; - block->next = 0; - SET_CANARY(block); -#ifdef __APC_SMA_DEBUG__ - block->id = -1; -#endif - } -} -/* }}} */ - -/* {{{ apc_sma_cleanup */ -void apc_sma_cleanup() -{ - int i; - - assert(sma_initialized); - - for (i = 0; i < sma_numseg; i++) { - apc_lck_destroy(((header_t*)sma_shmaddrs[i])->sma_lock); -#if APC_MMAP - apc_unmap(sma_shmaddrs[i], sma_segments[i]); -#else - apc_shm_detach(sma_shmaddrs[i]); -#endif - } - sma_initialized = 0; - apc_efree(sma_segments); - apc_efree(sma_shmaddrs); -} -/* }}} */ - -/* {{{ apc_sma_malloc */ -void* apc_sma_malloc(size_t n) -{ - size_t off; - int i; - - TSRMLS_FETCH(); - assert(sma_initialized); - LOCK(((header_t*)sma_shmaddrs[sma_lastseg])->sma_lock); - - off = sma_allocate(sma_shmaddrs[sma_lastseg], n); - if (off != -1) { - void* p = (void *)(((char *)(sma_shmaddrs[sma_lastseg])) + off); - if (APCG(mem_size_ptr) != NULL) { *(APCG(mem_size_ptr)) += n; } - UNLOCK(((header_t*)sma_shmaddrs[sma_lastseg])->sma_lock); -#ifdef VALGRIND_MALLOCLIKE_BLOCK - VALGRIND_MALLOCLIKE_BLOCK(p, n, 0, 0); -#endif - return p; - } - UNLOCK(((header_t*)sma_shmaddrs[sma_lastseg])->sma_lock); - - for (i = 0; i < sma_numseg; i++) { - if (i == sma_lastseg) { - continue; - } - LOCK(((header_t*)sma_shmaddrs[i])->sma_lock); - off = sma_allocate(sma_shmaddrs[i], n); - if (off != -1) { - void* p = (void *)(((char *)(sma_shmaddrs[i])) + off); - if (APCG(mem_size_ptr) != NULL) { *(APCG(mem_size_ptr)) += n; } - UNLOCK(((header_t*)sma_shmaddrs[i])->sma_lock); - sma_lastseg = i; -#ifdef VALGRIND_MALLOCLIKE_BLOCK - VALGRIND_MALLOCLIKE_BLOCK(p, n, 0, 0); -#endif - return p; - } - UNLOCK(((header_t*)sma_shmaddrs[i])->sma_lock); - } - - return NULL; -} -/* }}} */ - -/* {{{ apc_sma_realloc */ -void* apc_sma_realloc(void *p, size_t n) -{ - apc_sma_free(p); - return apc_sma_malloc(n); -} -/* }}} */ - -/* {{{ apc_sma_strdup */ -char* apc_sma_strdup(const char* s) -{ - void* q; - int len; - - if(!s) return NULL; - - len = strlen(s)+1; - q = apc_sma_malloc(len); - if(!q) return NULL; - memcpy(q, s, len); - return q; -} -/* }}} */ - -/* {{{ apc_sma_free */ -void apc_sma_free(void* p) -{ - int i; - size_t offset; - size_t d_size; - TSRMLS_FETCH(); - - if (p == NULL) { - return; - } - - assert(sma_initialized); - - for (i = 0; i < sma_numseg; i++) { - LOCK(((header_t*)sma_shmaddrs[i])->sma_lock); - offset = (size_t)((char *)p - (char *)(sma_shmaddrs[i])); - if (p >= sma_shmaddrs[i] && offset < sma_segsize) { - d_size = sma_deallocate(sma_shmaddrs[i], offset); - if (APCG(mem_size_ptr) != NULL) { *(APCG(mem_size_ptr)) -= d_size; } - UNLOCK(((header_t*)sma_shmaddrs[i])->sma_lock); -#ifdef VALGRIND_FREELIKE_BLOCK - VALGRIND_FREELIKE_BLOCK(p, 0); -#endif - return; - } - UNLOCK(((header_t*)sma_shmaddrs[i])->sma_lock); - } - - apc_eprint("apc_sma_free: could not locate address %p", p); -} -/* }}} */ - -/* {{{ apc_sma_info */ -apc_sma_info_t* apc_sma_info(zend_bool limited) -{ - apc_sma_info_t* info; - apc_sma_link_t** link; - int i; - char* shmaddr; - block_t* prv; - - if (!sma_initialized) { - return NULL; - } - - info = (apc_sma_info_t*) apc_emalloc(sizeof(apc_sma_info_t)); - info->num_seg = sma_numseg; - info->seg_size = sma_segsize - ALIGNWORD(sizeof(header_t)) - ALIGNWORD(sizeof(block_t)); - - info->list = apc_emalloc(info->num_seg * sizeof(apc_sma_link_t*)); - for (i = 0; i < sma_numseg; i++) { - info->list[i] = NULL; - } - - if(limited) return info; - - /* For each segment */ - for (i = 0; i < sma_numseg; i++) { - RDLOCK(((header_t*)sma_shmaddrs[i])->sma_lock); - shmaddr = sma_shmaddrs[i]; - prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); - - link = &info->list[i]; - - /* For each block in this segment */ - while (prv->next != 0) { - block_t* cur = BLOCKAT(prv->next); -#ifdef __APC_SMA_DEBUG__ - CHECK_CANARY(cur); -#endif - - *link = apc_emalloc(sizeof(apc_sma_link_t)); - (*link)->size = cur->size; - (*link)->offset = prv->next; - (*link)->next = NULL; - link = &(*link)->next; - - prv = cur; - } - UNLOCK(((header_t*)sma_shmaddrs[i])->sma_lock); - } - - return info; -} -/* }}} */ - -/* {{{ apc_sma_free_info */ -void apc_sma_free_info(apc_sma_info_t* info) -{ - int i; - - for (i = 0; i < info->num_seg; i++) { - apc_sma_link_t* p = info->list[i]; - while (p) { - apc_sma_link_t* q = p; - p = p->next; - apc_efree(q); - } - } - apc_efree(info->list); - apc_efree(info); -} -/* }}} */ - -/* {{{ apc_sma_get_avail_mem */ -size_t apc_sma_get_avail_mem() -{ - size_t avail_mem = 0; - int i; - - for (i = 0; i < sma_numseg; i++) { - header_t* header = (header_t*) sma_shmaddrs[i]; - avail_mem += header->avail; - } - return avail_mem; -} -/* }}} */ - -#if ALLOC_DISTRIBUTION -size_t *apc_sma_get_alloc_distribution(void) { - header_t* header = (header_t*) sma_shmaddrs[0]; - return header->adist; -} -#endif - -#if 0 -/* {{{ apc_sma_check_integrity */ -void apc_sma_check_integrity() -{ - int i; - - /* For each segment */ - for (i = 0; i < sma_numseg; i++) { - char* shmaddr = sma_shmaddrs[i]; - header_t* header = (header_t*) shmaddr; - block_t* prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); - int avail = 0; - - /* For each block in this segment */ - while (prv->next != 0) { - block_t* cur = BLOCKAT(prv->next); - avail += cur->size; - prv = cur; - } - - assert(avail == header->avail); - } -} -/* }}} */ -#endif - -/* - * 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 - */ diff --git a/apc_sma.h b/apc_sma.h deleted file mode 100644 index 2f20b1f..0000000 --- a/apc_sma.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - 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_sma.h,v 1.18.2.2 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_SMA_H -#define APC_SMA_H - -#define ALLOC_DISTRIBUTION 0 - -#include "apc.h" - -/* Simple shared memory allocator */ - -extern void apc_sma_init(int numseg, size_t segsize, char *mmap_file_mask); -extern void apc_sma_cleanup(); -extern void* apc_sma_malloc(size_t size); -extern void* apc_sma_realloc(void* p, size_t size); -extern char* apc_sma_strdup(const char *s); -extern void apc_sma_free(void* p); -#if ALLOC_DISTRIBUTION -extern size_t *apc_sma_get_alloc_distribution(); -#endif - -/* {{{ struct definition: apc_sma_link_t */ -typedef struct apc_sma_link_t apc_sma_link_t; -struct apc_sma_link_t { - long size; /* size of this free block */ - long offset; /* offset in segment of this block */ - apc_sma_link_t* next; /* link to next free block */ -}; -/* }}} */ - -/* {{{ struct definition: apc_sma_info_t */ -typedef struct apc_sma_info_t apc_sma_info_t; -struct apc_sma_info_t { - int num_seg; /* number of shared memory segments */ - long seg_size; /* size of each shared memory segment */ - apc_sma_link_t** list; /* there is one list per segment */ -}; -/* }}} */ - -extern apc_sma_info_t* apc_sma_info(zend_bool limited); -extern void apc_sma_free_info(apc_sma_info_t* info); - -extern size_t apc_sma_get_avail_mem(); -extern void apc_sma_check_integrity(); - -/* {{{ ALIGNWORD: pad up x, aligned to the system's word boundary */ -typedef union { void* p; int i; long l; double d; void (*f)(); } apc_word_t; -#define ALIGNSIZE(x, size) ((size) * (1 + (((x)-1)/(size)))) -#define ALIGNWORD(x) ALIGNSIZE(x, sizeof(apc_word_t)) -/* }}} */ - -#endif - -/* - * 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 - */ diff --git a/apc_spin.c b/apc_spin.c deleted file mode 100644 index bbeb0c6..0000000 --- a/apc_spin.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - */ - -/* $Id: apc_spin.c,v 3.1.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_spin.h" - -#ifdef APC_SPIN_LOCKS - -slock_t *apc_slock_create(slock_t *lock) -{ - S_INIT_LOCK(lock); -} - -void apc_slock_destroy(slock_t *lock) -{ - S_LOCK_FREE(lock); -} - -void apc_slock_lock(slock_t *lock) -{ - S_LOCK(lock); -} - -void apc_slock_unlock(slock_t *lock) -{ - S_UNLOCK(lock); -} - -zend_bool apc_slock_nonblocking_lock(slock_t *lock) -{ - /* Technically we aren't supposed to call this directly, but the original - * code provides no method for absolute non-blocking locks, so we'll call into - * the TAS (test and set) functionality directly - */ - return !(TAS(lock)); /* if TAS returns 0 we obtained the lock, otherwise we failed */ -} - - -#endif - -/* - * 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 - */ diff --git a/apc_spin.h b/apc_spin.h deleted file mode 100644 index bb0bd14..0000000 --- a/apc_spin.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - */ - -/* $Id: apc_spin.h,v 3.1.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_SPIN_H -#define APC_SPIN_H - -#include "apc.h" - -#ifdef APC_SPIN_LOCKS - -#include "pgsql_s_lock.h" - -pthread_mutex_t *apc_spin_create(); -void apc_spin_destroy(pthread_mutex_t *lock); -void apc_spin_lock(pthread_mutex_t *lock); -void apc_spin_unlock(pthread_mutex_t *lock); -zend_bool apc_spin_nonblocking_lock(pthread_mutex_t *lock); - -#endif - -#endif - -/* - * 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 - */ diff --git a/apc_stack.c b/apc_stack.c deleted file mode 100644 index a9d298b..0000000 --- a/apc_stack.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - 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_stack.c,v 3.4.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_stack.h" -#include "apc.h" - -struct apc_stack_t { - void** data; - int capacity; - int size; -}; - -apc_stack_t* apc_stack_create(int size_hint) -{ - apc_stack_t* stack = (apc_stack_t*) apc_emalloc(sizeof(apc_stack_t)); - - stack->capacity = (size_hint > 0) ? size_hint : 10; - stack->size = 0; - stack->data = (void**) apc_emalloc(sizeof(void*) * stack->capacity); - - return stack; -} - -void apc_stack_destroy(apc_stack_t* stack) -{ - if (stack != NULL) { - apc_efree(stack->data); - apc_efree(stack); - } -} - -void apc_stack_clear(apc_stack_t* stack) -{ - assert(stack != NULL); - stack->size = 0; -} - -void apc_stack_push(apc_stack_t* stack, void* item) -{ - assert(stack != NULL); - if (stack->size == stack->capacity) { - stack->capacity *= 2; - stack->data = apc_erealloc(stack->data, sizeof(void*)*stack->capacity); - } - stack->data[stack->size++] = item; -} - -void* apc_stack_pop(apc_stack_t* stack) -{ - assert(stack != NULL && stack->size > 0); - return stack->data[--stack->size]; -} - -void* apc_stack_top(apc_stack_t* stack) -{ - assert(stack != NULL && stack->size > 0); - return stack->data[stack->size-1]; -} - -void* apc_stack_get(apc_stack_t* stack, int n) -{ - assert(stack != NULL && stack->size > n); - return stack->data[n]; -} - -int apc_stack_size(apc_stack_t* stack) -{ - assert(stack != NULL); - return stack->size; -} - -/* - * 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 - */ diff --git a/apc_stack.h b/apc_stack.h deleted file mode 100644 index 91a6c01..0000000 --- a/apc_stack.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | George Schlossnagle | - +----------------------------------------------------------------------+ - - 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_stack.h,v 3.4.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_STACK_H -#define APC_STACK_H - -/* Basic stack datatype */ - -#define T apc_stack_t* -typedef struct apc_stack_t apc_stack_t; /* opaque stack type */ - -extern T apc_stack_create(int size_hint); -extern void apc_stack_destroy(T stack); -extern void apc_stack_clear(T stack); -extern void apc_stack_push(T stack, void* item); -extern void* apc_stack_pop(T stack); -extern void* apc_stack_top(T stack); -extern void* apc_stack_get(T stack, int n); -extern int apc_stack_size(T stack); - -#undef T -#endif - -/* - * 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 - */ diff --git a/apc_zend.c b/apc_zend.c deleted file mode 100644 index 5d944f1..0000000 --- a/apc_zend.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - 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_zend.c,v 3.14.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_zend.h" -#include "apc_globals.h" - -void* apc_php_malloc(size_t n) -{ - return emalloc(n); -} - -void apc_php_free(void* p) -{ - efree(p); -} - -#ifndef ZEND_VM_KIND_CALL /* Not currently defined by any ZE version */ -# define ZEND_VM_KIND_CALL 1 -#endif - -#ifndef ZEND_VM_KIND /* Indicates PHP < 5.1 */ -# define ZEND_VM_KIND ZEND_VM_KIND_CALL -#endif - -#if defined(ZEND_ENGINE_2) && (ZEND_VM_KIND == ZEND_VM_KIND_CALL) -# define APC_OPCODE_OVERRIDE -#endif - -#ifdef APC_OPCODE_OVERRIDE - -#ifdef ZEND_ENGINE_2_1 -/* Taken from Zend/zend_vm_execute.h */ -#define _CONST_CODE 0 -#define _TMP_CODE 1 -#define _VAR_CODE 2 -#define _UNUSED_CODE 3 -#define _CV_CODE 4 -static inline int _apc_opcode_handler_decode(zend_op *opline) -{ - static const int apc_vm_decode[] = { - _UNUSED_CODE, /* 0 */ - _CONST_CODE, /* 1 = IS_CONST */ - _TMP_CODE, /* 2 = IS_TMP_VAR */ - _UNUSED_CODE, /* 3 */ - _VAR_CODE, /* 4 = IS_VAR */ - _UNUSED_CODE, /* 5 */ - _UNUSED_CODE, /* 6 */ - _UNUSED_CODE, /* 7 */ - _UNUSED_CODE, /* 8 = IS_UNUSED */ - _UNUSED_CODE, /* 9 */ - _UNUSED_CODE, /* 10 */ - _UNUSED_CODE, /* 11 */ - _UNUSED_CODE, /* 12 */ - _UNUSED_CODE, /* 13 */ - _UNUSED_CODE, /* 14 */ - _UNUSED_CODE, /* 15 */ - _CV_CODE /* 16 = IS_CV */ - }; - return (opline->opcode * 25) + (apc_vm_decode[opline->op1.op_type] * 5) + apc_vm_decode[opline->op2.op_type]; -} - -# define APC_ZEND_OPLINE zend_op *opline = execute_data->opline; -# define APC_OPCODE_HANDLER_DECODE(opline) _apc_opcode_handler_decode(opline) -# if PHP_MAJOR_VERSION >= 6 -# define APC_OPCODE_HANDLER_COUNT ((25 * 152) + 1) -# else -# define APC_OPCODE_HANDLER_COUNT ((25 * 151) + 1) -# endif -# define APC_REPLACE_OPCODE(opname) { int i; for(i = 0; i < 25; i++) if (zend_opcode_handlers[(opname*25) + i]) zend_opcode_handlers[(opname*25) + i] = apc_op_##opname; } - -#else /* ZE2.0 */ -# define APC_ZEND_ONLINE -# define APC_OPCODE_HANDLER_DECODE(opline) (opline->opcode) -# define APC_OPCODE_HANDLER_COUNT 512 -# define APC_REPLACE_OPCODE(opname) zend_opcode_handlers[opname] = apc_op_##opname; -#endif - -static opcode_handler_t *apc_original_opcode_handlers; -static opcode_handler_t apc_opcode_handlers[APC_OPCODE_HANDLER_COUNT]; - -#define APC_EX_T(offset) (*(temp_variable *)((char*)execute_data->Ts + offset)) - -static zval *apc_get_zval_ptr(znode *node, zval **freeval, zend_execute_data *execute_data TSRMLS_DC) -{ - *freeval = NULL; - - switch (node->op_type) { - case IS_CONST: - return &(node->u.constant); - case IS_VAR: - return APC_EX_T(node->u.var).var.ptr; - case IS_TMP_VAR: - return (*freeval = &APC_EX_T(node->u.var).tmp_var); -#ifdef ZEND_ENGINE_2_1 - case IS_CV: - { - zval ***ret = &execute_data->CVs[node->u.var]; - - if (!*ret) { - zend_compiled_variable *cv = &EG(active_op_array)->vars[node->u.var]; - - if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void**)ret)==FAILURE) { - apc_nprint("Undefined variable: %s", cv->name); - return &EG(uninitialized_zval); - } - } - return **ret; - } -#endif - case IS_UNUSED: - default: - return NULL; - } -} - -static int apc_op_ZEND_INCLUDE_OR_EVAL(ZEND_OPCODE_HANDLER_ARGS) -{ - APC_ZEND_OPLINE - zval *freeop1 = NULL; - zval *inc_filename = NULL, tmp_inc_filename; - char realpath[MAXPATHLEN]; - php_stream_wrapper *wrapper; - char *path_for_open; - int ret = 0; - #ifdef ZEND_ENGINE_2 - apc_opflags_t* flags = NULL; - #endif - - if (Z_LVAL(opline->op2.u.constant) != ZEND_INCLUDE_ONCE && - Z_LVAL(opline->op2.u.constant) != ZEND_REQUIRE_ONCE) { - return apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - - inc_filename = apc_get_zval_ptr(&opline->op1, &freeop1, execute_data TSRMLS_CC); - if (Z_TYPE_P(inc_filename) != IS_STRING) { - tmp_inc_filename = *inc_filename; - zval_copy_ctor(&tmp_inc_filename); - convert_to_string(&tmp_inc_filename); - inc_filename = &tmp_inc_filename; - } - - wrapper = php_stream_locate_url_wrapper(Z_STRVAL_P(inc_filename), &path_for_open, 0 TSRMLS_CC); - if (wrapper != &php_plain_files_wrapper || - !IS_ABSOLUTE_PATH(path_for_open, strlen(path_for_open)) || - !expand_filepath(path_for_open, realpath TSRMLS_CC)) { - /* Fallback to original handler */ - if (inc_filename == &tmp_inc_filename) { - zval_dtor(&tmp_inc_filename); - } - return apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - - if (zend_hash_exists(&EG(included_files), realpath, strlen(realpath) + 1)) { - if (!(opline->result.u.EA.type & EXT_TYPE_UNUSED)) { - ALLOC_INIT_ZVAL(APC_EX_T(opline->result.u.var).var.ptr); - ZVAL_TRUE(APC_EX_T(opline->result.u.var).var.ptr); - } - if (inc_filename == &tmp_inc_filename) { - zval_dtor(&tmp_inc_filename); - } - if (freeop1) { - zval_dtor(freeop1); - } - execute_data->opline++; - return 0; - } - - if (inc_filename == &tmp_inc_filename) { - zval_dtor(&tmp_inc_filename); - } - - if(APCG(reserved_offset) != -1) { - /* Insanity alert: look into apc_compile.c for why a void** is cast to a apc_opflags_t* */ - flags = (apc_opflags_t*) & (execute_data->op_array->reserved[APCG(reserved_offset)]); - } - -#ifdef ZEND_ENGINE_2 - if(flags && flags->deep_copy == 1) { - /* Since the op array is a local copy, we can cheat our way through the file inclusion by temporarily - * changing the op to a plain require/include, calling its handler and finally restoring the opcode. - */ - Z_LVAL(opline->op2.u.constant) = (Z_LVAL(opline->op2.u.constant) == ZEND_INCLUDE_ONCE) ? ZEND_INCLUDE : ZEND_REQUIRE; - ret = apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - Z_LVAL(opline->op2.u.constant) = (Z_LVAL(opline->op2.u.constant) == ZEND_INCLUDE) ? ZEND_INCLUDE_ONCE : ZEND_REQUIRE_ONCE; -#else - if(0) { - /* do nothing, have nothing, be nothing */ -#endif - } else { - ret = apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - - return ret; -} - -void apc_zend_init(TSRMLS_D) -{ - zend_extension dummy_ext; -#ifdef ZEND_ENGINE_2 - APCG(reserved_offset) = zend_get_resource_handle(&dummy_ext); - assert(APCG(reserved_offset) == dummy_ext.resource_number); - assert(APCG(reserved_offset) != -1); - assert(sizeof(apc_opflags_t) <= sizeof(void*)); -#endif - if (!APCG(include_once)) { - /* If we're not overriding the INCLUDE_OR_EVAL handler, then just skip this malarkey */ - return; - } - - memcpy(apc_opcode_handlers, zend_opcode_handlers, sizeof(apc_opcode_handlers)); - - /* 5.0 exposes zend_opcode_handlers differently than 5.1 and later */ -#ifdef ZEND_ENGINE_2_1 - apc_original_opcode_handlers = zend_opcode_handlers; - zend_opcode_handlers = apc_opcode_handlers; -#else - apc_original_opcode_handlers = apc_opcode_handlers; -#endif - - APC_REPLACE_OPCODE(ZEND_INCLUDE_OR_EVAL); -} - -void apc_zend_shutdown(TSRMLS_D) -{ - if (!APCG(include_once)) { - /* Nothing changed, nothing to restore */ - return; - } - -#ifdef ZEND_ENGINE_2_1 - zend_opcode_handlers = apc_original_opcode_handlers; -#else - memcpy(zend_opcode_handlers, apc_original_opcode_handlers, sizeof(apc_opcode_handlers)); -#endif -} - -#else /* Opcode Overrides unavailable */ - -void apc_zend_init(TSRMLS_D) { } -void apc_zend_shutdown(TSRMLS_D) { } - -#endif /* APC_OPCODE_OVERRIDE */ - -/* - * 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 - */ diff --git a/apc_zend.h b/apc_zend.h deleted file mode 100644 index daebb52..0000000 --- a/apc_zend.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - +----------------------------------------------------------------------+ - - 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_zend.h,v 3.8.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef APC_ZEND_H -#define APC_ZEND_H - -/* Utilities for interfacing with the zend engine */ - -#include "apc.h" -#include "apc_php.h" - -extern void* apc_php_malloc(size_t n); -extern void apc_php_free(void* p); - -extern void apc_zend_init(TSRMLS_D); -extern void apc_zend_shutdown(TSRMLS_D); - -#endif - -/* - * 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 - */ diff --git a/arch/atomic.h b/arch/atomic.h deleted file mode 100644 index ac6feaf..0000000 --- a/arch/atomic.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2006 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 | - +----------------------------------------------------------------------+ - - */ - -/* $Id: atomic.h,v 1.1 2006/09/29 07:13:01 shire Exp $ */ - -#ifndef APC_ARCH_ATOMIC_H - -#define APC_ARCH_ATOMIC_H - -#if defined __x86_64__ -#include "x86_64/atomic.h" - -#elif defined __i386__ -#include "i386/atomic.h" - -#else -#error "Unknown or Unsupported Architecture. If you would like futex suupport for your architecture, please file a request at http://pecl.php.net/bugs/report.php?package=APC" - -#endif - - -#endif diff --git a/arch/i386/atomic.h b/arch/i386/atomic.h deleted file mode 100644 index 069a5b0..0000000 --- a/arch/i386/atomic.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2006 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 | - +----------------------------------------------------------------------+ - - */ - -/* $Id: atomic.h,v 1.1 2006/09/29 07:13:01 shire Exp $ */ - - -#include -#include -#include - -/* int sys_futex (void *futex, int op, int val, const struct timespec *timeout); */ -static inline long int apc_sys_futex(void *futex, int op, int val, const struct timespec *timeout) { - - long int ret; - - /* i386 system calls are performed with nt 80h operation. - * the argument order is a, b, c, d, S, D - */ - asm volatile ("int $0x80" - : "=a" (ret) - : "0" (SYS_futex), - "b" (futex), - "c" (op), - "d" (val), - "S" (timeout) - : "memory" - ); - - return ret; - -} - - -static inline int apc_cmpxchg(volatile int *ptr, int old, int new) { - - int prev; - - asm volatile ("LOCK cmpxchgl %1, %2" - : "=a" (prev) - : "r" (new), - "m" (*(ptr)), - "0"(old) - : "memory", "cc" - ); - - return prev; -} - -static inline int apc_xchg(volatile int *ptr, int new) { - - int ret; - - asm volatile ("LOCK xchgl %[new], %[ptr]" - : "=a" (ret) - : [new] "0" (new), - [ptr] "m" (*(ptr)) - : "memory" - ); - - return ret; - -} - diff --git a/arch/x86_64/atomic.h b/arch/x86_64/atomic.h deleted file mode 100644 index 4b882d5..0000000 --- a/arch/x86_64/atomic.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2006 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 | - +----------------------------------------------------------------------+ - - */ - -/* $Id: atomic.h,v 1.1 2006/09/29 07:13:01 shire Exp $ */ - - -#include -#include -#include - -/* int sys_futex (void *futex, int op, int val, const struct timespec *timeout); */ -static inline long int apc_sys_futex(void *futex, int op, int val, const struct timespec *timeout) { - - long int ret; - - /* x86_64 system calls are performed with the faster SYSCALL operation. - * the argument order is D, S, d, c, b, a rather than - * a, b, c, d, S, D as on the i386 int 80h call. - */ - asm volatile ("syscall" - : "=a" (ret) - : "0" (SYS_futex), - "D" (futex), - "S" (op), - "d" (val), - "c" (timeout) - : "r11", "rcx", "memory" - ); - - return ret; - -} - - -static inline int apc_cmpxchg(volatile int *ptr, int old, int new) { - - int prev; - - asm volatile ("LOCK cmpxchgl %1, %2" - : "=a" (prev) - : "r" (new), - "m" (*(ptr)), - "0"(old) - : "memory", "cc" - ); - - return prev; -} - -static inline int apc_xchg(volatile int *ptr, int new) { - - int ret; - - asm volatile ("LOCK xchgl %[new], %[ptr]" - : "=a" (ret) - : [new] "0" (new), - [ptr] "m" (*(ptr)) - : "memory" - ); - - return ret; - -} - diff --git a/config.m4 b/config.m4 deleted file mode 100644 index 19a07e7..0000000 --- a/config.m4 +++ /dev/null @@ -1,254 +0,0 @@ -dnl -dnl $Id: config.m4,v 3.30.2.2 2008/03/25 21:00:22 rasmus Exp $ -dnl - -AC_MSG_CHECKING(whether apc needs to get compiler flags from apxs) -AC_ARG_WITH(apxs, -[ --with-apxs[=FILE] Get compiler flags from apxs -q. Provide the - pathname to the Apache apxs tool; defaults to "apxs".],[ - if test "$withval" != "no"; then - if test "$withval" = "yes"; then - APXS=apxs - $APXS -q CFLAGS >/dev/null 2>&1 - if test "$?" != "0" && test -x /usr/sbin/apxs; then #SUSE 6.x - APXS=/usr/sbin/apxs - elif test -x /usr/bin/apxs2; then - APXS=/usr/bin/apxs2 - elif test -x /usr/sbin/apxs2; then - APXS=/usr/sbin/apxs2 - fi - else - PHP_EXPAND_PATH($withval, APXS) - fi - - $APXS -q CFLAGS >/dev/null 2>&1 - if test "$?" != "0"; then - AC_MSG_RESULT() - AC_MSG_RESULT() - AC_MSG_RESULT([Sorry, I was not able to successfully run APXS. Possible reasons:]) - AC_MSG_RESULT() - AC_MSG_RESULT([1. Perl is not installed;]) - AC_MSG_RESULT([2. Apache was not compiled with DSO support (--enable-module=so);]) - AC_MSG_RESULT([3. 'apxs' is not in your path. Try to use --with-apxs=/path/to/apxs]) - AC_MSG_RESULT([The output of $APXS follows]) - $APXS -q CFLAGS - AC_MSG_ERROR([Aborting]) - fi - - APC_CFLAGS=`$APXS -q CFLAGS` - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi -],[ - AC_MSG_RESULT(no) -]) - -PHP_ARG_ENABLE(apc, whether to enable APC support, -[ --enable-apc Enable APC support]) - -AC_MSG_CHECKING(Checking whether we should enable cache request file info) -AC_ARG_ENABLE(apc-filehits, -[ --enable-apc-filehits Enable per request file info about files used from the APC cache (ie: apc_cache_info('filehits')) ], -[ - PHP_APC_FILEHITS=$enableval - AC_MSG_RESULT($enableval) -], -[ - PHP_APC_FILEHITS=no - AC_MSG_RESULT(no) -]) - - - -AC_MSG_CHECKING(Checking whether we should use mmap) -AC_ARG_ENABLE(apc-mmap, -[ --disable-apc-mmap - Disable mmap support and use IPC shm instead], -[ - PHP_APC_MMAP=$enableval - AC_MSG_RESULT($enableval) -], [ - PHP_APC_MMAP=yes - AC_MSG_RESULT(yes) -]) - -AC_MSG_CHECKING(Checking whether we should use semaphore locking instead of fcntl) -AC_ARG_ENABLE(apc-sem, -[ --enable-apc-sem - Enable semaphore locks instead of fcntl], -[ - PHP_APC_SEM=$enableval - AC_MSG_RESULT($enableval) -], [ - PHP_APC_SEM=no - AC_MSG_RESULT(no) -]) - -AC_MSG_CHECKING(Checking whether we should use futex locking) -AC_ARG_ENABLE(apc-futex, -[ --enable-apc-futex - Enable linux futex based locks EXPERIMENTAL ], -[ - PHP_APC_FUTEX=$enableval - AC_MSG_RESULT($enableval) -], -[ - PHP_APC_FUTEX=no - AC_MSG_RESULT(no) -]) - -if test "$PHP_APC_FUTEX" != "no"; then - AC_CHECK_HEADER(linux/futex.h, , [ AC_MSG_ERROR([futex.h not found. Please verify you that are running a 2.5 or older linux kernel and that futex support is enabled.]); ] ) -fi - -AC_MSG_CHECKING(Checking whether we should use pthread mutex locking) -AC_ARG_ENABLE(apc-pthreadmutex, -[ --disable-apc-pthreadmutex - Disable pthread mutex locking ], -[ - PHP_APC_PTHREADMUTEX=$enableval - AC_MSG_RESULT($enableval) -], -[ - PHP_APC_PTHREADMUTEX=yes - AC_MSG_RESULT(yes) -]) -if test "$PHP_APC_PTHREADMUTEX" != "no"; then - orig_LIBS="$LIBS" - LIBS="$LIBS -lpthread" - AC_TRY_RUN( - [ - #include - #include - main() { - pthread_mutex_t mutex; - pthread_mutexattr_t attr; - - if(pthread_mutexattr_init(&attr)) { - puts("Unable to initialize pthread attributes (pthread_mutexattr_init)."); - return -1; - } - if(pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) { - puts("Unable to set PTHREAD_PROCESS_SHARED (pthread_mutexattr_setpshared), your system may not support shared mutex's."); - return -1; - } - if(pthread_mutex_init(&mutex, &attr)) { - puts("Unable to initialize the mutex (pthread_mutex_init)."); - return -1; - } - if(pthread_mutexattr_destroy(&attr)) { - puts("Unable to destroy mutex attributes (pthread_mutexattr_destroy)."); - return -1; - } - if(pthread_mutex_destroy(&mutex)) { - puts("Unable to destroy mutex (pthread_mutex_destroy)."); - return -1; - } - - puts("pthread mutex's are supported!"); - return 0; - } - ], - [ dnl -Success- - PHP_ADD_LIBRARY(pthread) - ], - [ dnl -Failure- - AC_MSG_WARN([It doesn't appear that pthread mutex's are supported on your system]) - PHP_APC_PTHREADMUTEX=no - ], - [ - PHP_ADD_LIBRARY(pthread) - ] - ) - LIBS="$orig_LIBS" -fi - -AC_MSG_CHECKING(Checking whether we should use spin locks) -AC_ARG_ENABLE(apc-spinlocks, -[ --enable-apc-spinlocks - Enable spin locks EXPERIMENTAL ], -[ - PHP_APC_SPINLOCKS=$enableval - AC_MSG_RESULT($enableval) -], -[ - PHP_APC_SPINLOCKS=no - AC_MSG_RESULT(no) -]) - -if test "$PHP_APC" != "no"; then - test "$PHP_APC_MMAP" != "no" && AC_DEFINE(APC_MMAP, 1, [ ]) - test "$PHP_APC_FILEHITS" != "no" && AC_DEFINE(APC_FILEHITS, 1, [ ]) - - if test "$PHP_APC_SEM" != "no"; then - AC_DEFINE(APC_SEM_LOCKS, 1, [ ]) - elif test "$PHP_APC_FUTEX" != "no"; then - AC_DEFINE(APC_FUTEX_LOCKS, 1, [ ]) - elif test "$PHP_APC_SPINLOCKS" != "no"; then - AC_DEFINE(APC_SPIN_LOCKS, 1, [ ]) - elif test "$PHP_APC_PTHREADMUTEX" != "no"; then - AC_DEFINE(APC_PTHREADMUTEX_LOCKS, 1, [ ]) - fi - - AC_CHECK_FUNCS(sigaction) - AC_CACHE_CHECK(for union semun, php_cv_semun, - [ - AC_TRY_COMPILE([ -#include -#include -#include - ], [union semun x;], [ - php_cv_semun=yes - ],[ - php_cv_semun=no - ]) - ]) - if test "$php_cv_semun" = "yes"; then - AC_DEFINE(HAVE_SEMUN, 1, [ ]) - else - AC_DEFINE(HAVE_SEMUN, 0, [ ]) - fi - - AC_MSG_CHECKING(whether we should enable valgrind support) - AC_ARG_ENABLE(valgrind-checks, - [ --enable-valgrind-checks - Enable valgrind based memory checks], - [ - PHP_APC_VALGRIND=$enableval - AC_MSG_RESULT($enableval) - AC_CHECK_HEADER(valgrind/memcheck.h, - [AC_DEFINE([HAVE_VALGRIND_MEMCHECK_H],1, [enable valgrind memchecks])]) - ], [ - PHP_APC_VALGRIND=no - AC_MSG_RESULT(no) - ]) - - - apc_sources="apc.c php_apc.c \ - apc_cache.c \ - apc_compile.c \ - apc_debug.c \ - apc_fcntl.c \ - apc_main.c \ - apc_mmap.c \ - apc_sem.c \ - apc_shm.c \ - apc_futex.c \ - apc_pthreadmutex.c \ - apc_spin.c \ - pgsql_s_lock.c \ - apc_sma.c \ - apc_stack.c \ - apc_zend.c \ - apc_rfc1867.c \ - apc_signal.c \ - apc_pool.c " - - PHP_CHECK_LIBRARY(rt, shm_open, [PHP_ADD_LIBRARY(rt,,APC_SHARED_LIBADD)]) - PHP_NEW_EXTENSION(apc, $apc_sources, $ext_shared,, \\$(APC_CFLAGS)) - PHP_SUBST(APC_SHARED_LIBADD) - PHP_SUBST(APC_CFLAGS) - AC_DEFINE(HAVE_APC, 1, [ ]) -fi - diff --git a/debian/changelog b/debian/changelog index d40b4f4..eea261a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +php5-apc (3.0.19-2) stable; urgency=low + + * php5-apc retained as dummy package. + * debian/control: + + depends on Debian package php-apc. + + -- Dragan Dosen Wed, 11 Feb 2009 22:00:48 +0100 + php5-apc (3.0.19-1) stable; urgency=low * New PHP5 APC - version 3.0.19, using PHP5 5.2.0-8+etch11, diff --git a/debian/control b/debian/control index 0c39ebf..781e5a3 100644 --- a/debian/control +++ b/debian/control @@ -3,18 +3,18 @@ Priority: optional Section: libs Origin: carnet Maintainer: Dragan Dosen -Build-Depends: debhelper (>= 4.2.32), php5-dev, apache2-prefork-dev, gawk | awk, autoconf +Build-Depends: debhelper (>= 4.2.32) Standards-Version: 3.7.2 Package: php5-apc Section: web -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, ${php:Depends} +Architecture: all +Depends: php-apc (>= 3.0.19-1~bpo40+1), ${shlibs:Depends}, ${misc:Depends}, ${php:Depends} Conflicts: php4-apc -Description: APC module for PHP5 - This package provides a module for APC functions. +Description: Dummy transition package for php-apc + The Alternative PHP Cache, also known as APC, is a free, open, and robust + framework for caching and optimizing PHP intermediate code. APC is a fast + solution for caching PHP code locally, it is not distributed like MemcacheD, + but they can be used together for optimal caching. . - The Alternative PHP Cache (APC) is a free, open, and robust framework - for caching and optimizing PHP intermediate code. This extension is - being released under the PHP License for complete compliance with PHP - and to encourage wide-spread use. + This package is obsolete. Once php-apc is installed, you can purge it. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index e948610..0000000 --- a/debian/copyright +++ /dev/null @@ -1,128 +0,0 @@ -This package was debianized by Dragan Dosen on -Fri, 21 Dec 2007 19:50:02 +0100 - -It was downloaded from http://pecl.php.net/package/APC - -The Alternative PHP Cache (APC) is a free and open opcode cache for PHP. -This extension is being released under the PHP License for complete compliance -with PHP and to encourage wide-spread use. It is our intention that this -project be kept open source and that all commercial spin-offs contribute their -modifications back into the public source-tree. - -Creators: - Daniel Cowgill - George Schlossnagle - -PHP5 support and major features by: - Arun C. Murthy - Gopal Vijayaraghavan - Rasmus Lerdorf - -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. - -We would like to thank Community Connect Inc. and Yahoo! Inc. for supporting -this project and providing a challenging and stimulating environment in -which exciting projects can happen. - -Contributors: - Mike Bretz bug fixes, GUI, and lots of work - Ricardo Galli changed read-write locks to prefer readers - Yann Grossel bug fixes - Thies Arntzen bug fixes - Sara Golemon optimizer work - -Special Thanks: - Florian Baumert help debugging phplib problems - Thomas Duffey help debugging inheritance issues - Vibol Hou help debugging phplib problems - Angel Li diffs for ANSI comment compliance - Christian Rishøj help debugging phplib problems - Sascha Schumann memory error bug fix - -You should have received a copy of the GNU General Public License -along with this package; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -On Debian systems, the complete text of the GNU General -Public License can be found in `/usr/share/common-licenses/GPL'. - - --------------------------------------------------------------------- - The PHP License, version 3.01 -Copyright (c) 1999 - 2006 The PHP Group. All rights reserved. --------------------------------------------------------------------- - -Redistribution and use in source and binary forms, with or without -modification, is permitted provided that the following conditions -are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - 3. The name "PHP" must not be used to endorse or promote products - derived from this software without prior written permission. For - written permission, please contact group@php.net. - - 4. Products derived from this software may not be called "PHP", nor - may "PHP" appear in their name, without prior written permission - from group@php.net. You may indicate that your software works in - conjunction with PHP by saying "Foo for PHP" instead of calling - it "PHP Foo" or "phpfoo" - - 5. The PHP Group may publish revised and/or new versions of the - license from time to time. Each version will be given a - distinguishing version number. - Once covered code has been published under a particular version - of the license, you may always continue to use it under the terms - of that version. You may also choose to use such covered code - under the terms of any subsequent version of the license - published by the PHP Group. No one other than the PHP Group has - the right to modify the terms applicable to covered code created - under this License. - - 6. Redistributions of any form whatsoever must retain the following - acknowledgment: - "This product includes PHP software, freely available from - ". - -THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND -ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP -DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - --------------------------------------------------------------------- - -This software consists of voluntary contributions made by many -individuals on behalf of the PHP Group. - -The PHP Group can be contacted via Email at group@php.net. - -For more information on the PHP Group and the PHP project, -please see . - -PHP includes the Zend Engine, freely available at -. - - -The Debian packaging is (C) 2006, root and -is licensed under the GPL, see above. -This is the NOTICE file that holds acknowledgements and stuff. diff --git a/debian/install b/debian/install deleted file mode 100644 index 7360645..0000000 --- a/debian/install +++ /dev/null @@ -1 +0,0 @@ -php5-apc/apc.ini /etc/php5/conf.d diff --git a/debian/php5-apc.postinst b/debian/php5-apc.postinst deleted file mode 100644 index 1050e89..0000000 --- a/debian/php5-apc.postinst +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -set -e - -if [ "$1" != "configure" ]; then - exit 0 -fi - -extension_re='^[[:space:]]*extension[[:space:]]*=[[:space:]]*apc\.so$' -for SAPI in apache apache2 cgi cli; do - ini_file="/etc/php5/$SAPI/php.ini" - if [ -f "$ini_file" ]; then - if grep -q "$extension_re" $ini_file; then - sed -i -e "/$extension_re/d" $ini_file - fi - fi -done - -exit 0 - diff --git a/debian/rules b/debian/rules index 630d7d4..e7f422a 100755 --- a/debian/rules +++ b/debian/rules @@ -6,64 +6,24 @@ # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. -# Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -export PHP_PREFIX="/usr" - -package=php5-apc -phpapiver=$(shell php-config5 --phpapi) - -CFLAGS = -Wall -g - -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CFLAGS += -O0 -else - CFLAGS += -O2 -endif - -# shared library versions, option 1 -version=2.0.5 -major=2 -# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so -#version=`ls src/.libs/lib*.so.* | \ -# awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'` -#major=`ls src/.libs/lib*.so.* | \ -# awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'` - configure: configure-stamp configure-stamp: dh_testdir - - phpize5 - ./configure \ - --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \ - --prefix=/usr \ - --enable-apc-mmap \ - --with-apxs \ - --with-php-config=$(PHP_PREFIX)/bin/php-config5 - touch configure-stamp - build: build-stamp + build-stamp: configure-stamp dh_testdir - - $(MAKE) - - touch $@ + touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp - - -$(MAKE) clean - - phpize5 --clean - - dh_clean + dh_clean install: build dh_testdir @@ -71,36 +31,35 @@ install: build dh_clean -k dh_installdirs - $(MAKE) install INSTALL_ROOT=$(CURDIR)/debian/$(package) - - -# Build architecture-independent files here. binary-indep: build install -# We have nothing to do by default. -# Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot + dh_installchangelogs + dh_installdocs dh_install -X.svn - dh_installchangelogs CHANGELOG - dh_installdocs TECHNOTES.txt TODO INSTALL - dh_installexamples - dh_installdebconf +# dh_installexamples +# dh_install +# dh_installmenu + dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman dh_link - dh_strip +# dh_strip dh_compress dh_fixperms - dh_makeshlibs +# dh_perl +# dh_python +# dh_makeshlibs dh_installdeb dh_shlibdeps - -# php api version we have been building against: - grep -v '^php:Depends' debian/${package}.substvars \ - > debian/${package}.substvars.$$ && \ - mv debian/${package}.substvars.$$ debian/${package}.substvars - echo "php:Depends=phpapi-$(phpapiver)" >> debian/${package}.substvars - dh_gencontrol dh_md5sums dh_builddeb diff --git a/pgsql_s_lock.c b/pgsql_s_lock.c deleted file mode 100644 index cfcd036..0000000 --- a/pgsql_s_lock.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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. | - +----------------------------------------------------------------------+ - | The following code was ported from the PostgreSQL project, please | - | see appropriate copyright notices that follow. | - | Initial conversion by Brian Shire | - +----------------------------------------------------------------------+ - - */ - -/* $Id: pgsql_s_lock.c,v 3.2.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -/*------------------------------------------------------------------------- - * - * s_lock.c - * Hardware-dependent implementation of spinlocks. - * - * - * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/lmgr/s_lock.c,v 1.47 2006/10/04 00:29:58 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -/* #include "postgres.h" -- Removed for APC */ - -/* -- Added for APC -- */ -#include "apc.h" -#ifdef APC_SPIN_LOCKS - -#ifdef S_LOCK_TEST -#include -#endif -#ifndef WIN32 -#include -#endif -/* ---- */ - -#include -#include - -/* #include "storage/s_lock.h" -- Removed for APC */ -#include "pgsql_s_lock.h" - -static int spins_per_delay = DEFAULT_SPINS_PER_DELAY; - - -/* -- APC specific additions ------------------------------*/ -/* The following dependencies have been copied from - * other pgsql source files. The original locations - * have been noted. - */ - -/* -- from include/c.h -- */ -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -/* -- from include/pg_config_manual.h -- */ -#define MAX_RANDOM_VALUE (0x7FFFFFFF) - -/* - * Max - * Return the maximum of two numbers. - */ -#define Max(x, y) ((x) > (y) ? (x) : (y)) - -/* -- from include/c.h -- */ -/* - * Min - * Return the minimum of two numbers. - */ -#define Min(x, y) ((x) < (y) ? (x) : (y)) - - -/* -- from backend/port/win32/signal.c -- */ -/* - * pg_usleep --- delay the specified number of microseconds. - * - * NOTE: although the delay is specified in microseconds, the effective - * resolution is only 1/HZ, or 10 milliseconds, on most Unixen. Expect - * the requested delay to be rounded up to the next resolution boundary. - * - * On machines where "long" is 32 bits, the maximum delay is ~2000 seconds. - */ -void -pg_usleep(long microsec) -{ - if (microsec > 0) - { -#ifndef WIN32 - struct timeval delay; - - delay.tv_sec = microsec / 1000000L; - delay.tv_usec = microsec % 1000000L; - (void) select(0, NULL, NULL, NULL, &delay); -#else - SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE); -#endif - } -} - -/* -- End APC specific additions ------------------------------*/ - - -/* - * s_lock_stuck() - complain about a stuck spinlock - */ -static void -s_lock_stuck(volatile slock_t *lock, const char *file, int line) -{ -#if defined(S_LOCK_TEST) - fprintf(stderr, - "\nStuck spinlock (%p) detected at %s:%d.\n", - lock, file, line); - exit(1); -#else - /* -- Removed for APC - elog(PANIC, "stuck spinlock (%p) detected at %s:%d", - lock, file, line); - */ - apc_eprint("Stuck spinlock (%p) detected", lock); -#endif -} - - -/* - * s_lock(lock) - platform-independent portion of waiting for a spinlock. - */ -void -s_lock(volatile slock_t *lock, const char *file, int line) -{ - /* - * We loop tightly for awhile, then delay using pg_usleep() and try again. - * Preferably, "awhile" should be a small multiple of the maximum time we - * expect a spinlock to be held. 100 iterations seems about right as an - * initial guess. However, on a uniprocessor the loop is a waste of - * cycles, while in a multi-CPU scenario it's usually better to spin a bit - * longer than to call the kernel, so we try to adapt the spin loop count - * depending on whether we seem to be in a uniprocessor or multiprocessor. - * - * Note: you might think MIN_SPINS_PER_DELAY should be just 1, but you'd - * be wrong; there are platforms where that can result in a "stuck - * spinlock" failure. This has been seen particularly on Alphas; it seems - * that the first TAS after returning from kernel space will always fail - * on that hardware. - * - * Once we do decide to block, we use randomly increasing pg_usleep() - * delays. The first delay is 1 msec, then the delay randomly increases to - * about one second, after which we reset to 1 msec and start again. The - * idea here is that in the presence of heavy contention we need to - * increase the delay, else the spinlock holder may never get to run and - * release the lock. (Consider situation where spinlock holder has been - * nice'd down in priority by the scheduler --- it will not get scheduled - * until all would-be acquirers are sleeping, so if we always use a 1-msec - * sleep, there is a real possibility of starvation.) But we can't just - * clamp the delay to an upper bound, else it would take a long time to - * make a reasonable number of tries. - * - * We time out and declare error after NUM_DELAYS delays (thus, exactly - * that many tries). With the given settings, this will usually take 2 or - * so minutes. It seems better to fix the total number of tries (and thus - * the probability of unintended failure) than to fix the total time - * spent. - * - * The pg_usleep() delays are measured in milliseconds because 1 msec is a - * common resolution limit at the OS level for newer platforms. On older - * platforms the resolution limit is usually 10 msec, in which case the - * total delay before timeout will be a bit more. - */ -#define MIN_SPINS_PER_DELAY 10 -#define MAX_SPINS_PER_DELAY 1000 -#define NUM_DELAYS 1000 -#define MIN_DELAY_MSEC 1 -#define MAX_DELAY_MSEC 1000 - - int spins = 0; - int delays = 0; - int cur_delay = 0; - - while (TAS(lock)) - { - /* CPU-specific delay each time through the loop */ - SPIN_DELAY(); - - /* Block the process every spins_per_delay tries */ - if (++spins >= spins_per_delay) - { - if (++delays > NUM_DELAYS) - s_lock_stuck(lock, file, line); - - if (cur_delay == 0) /* first time to delay? */ - cur_delay = MIN_DELAY_MSEC; - - pg_usleep(cur_delay * 1000L); - -#if defined(S_LOCK_TEST) - fprintf(stdout, "*"); - fflush(stdout); -#endif - - /* increase delay by a random fraction between 1X and 2X */ - cur_delay += (int) (cur_delay * - ((double) random() / (double) MAX_RANDOM_VALUE) + 0.5); - /* wrap back to minimum delay when max is exceeded */ - if (cur_delay > MAX_DELAY_MSEC) - cur_delay = MIN_DELAY_MSEC; - - spins = 0; - } - } - - /* - * If we were able to acquire the lock without delaying, it's a good - * indication we are in a multiprocessor. If we had to delay, it's a sign - * (but not a sure thing) that we are in a uniprocessor. Hence, we - * decrement spins_per_delay slowly when we had to delay, and increase it - * rapidly when we didn't. It's expected that spins_per_delay will - * converge to the minimum value on a uniprocessor and to the maximum - * value on a multiprocessor. - * - * Note: spins_per_delay is local within our current process. We want to - * average these observations across multiple backends, since it's - * relatively rare for this function to even get entered, and so a single - * backend might not live long enough to converge on a good value. That - * is handled by the two routines below. - */ - if (cur_delay == 0) - { - /* we never had to delay */ - if (spins_per_delay < MAX_SPINS_PER_DELAY) - spins_per_delay = Min(spins_per_delay + 100, MAX_SPINS_PER_DELAY); - } - else - { - if (spins_per_delay > MIN_SPINS_PER_DELAY) - spins_per_delay = Max(spins_per_delay - 1, MIN_SPINS_PER_DELAY); - } -} - - -#if 0 /* -- APC doesn't use the set_spins_per_delay or update_spins_per_delay -- */ -/* - * Set local copy of spins_per_delay during backend startup. - * - * NB: this has to be pretty fast as it is called while holding a spinlock - */ -void -set_spins_per_delay(int shared_spins_per_delay) -{ - spins_per_delay = shared_spins_per_delay; -} - -/* - * Update shared estimate of spins_per_delay during backend exit. - * - * NB: this has to be pretty fast as it is called while holding a spinlock - */ -int -update_spins_per_delay(int shared_spins_per_delay) -{ - /* - * We use an exponential moving average with a relatively slow adaption - * rate, so that noise in any one backend's result won't affect the shared - * value too much. As long as both inputs are within the allowed range, - * the result must be too, so we need not worry about clamping the result. - * - * We deliberately truncate rather than rounding; this is so that single - * adjustments inside a backend can affect the shared estimate (see the - * asymmetric adjustment rules above). - */ - return (shared_spins_per_delay * 15 + spins_per_delay) / 16; -} -#endif - -/* - * Various TAS implementations that cannot live in s_lock.h as no inline - * definition exists (yet). - * In the future, get rid of tas.[cso] and fold it into this file. - * - * If you change something here, you will likely need to modify s_lock.h too, - * because the definitions for these are split between this file and s_lock.h. - */ - - -#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ - - -#if defined(__GNUC__) - -/* - * All the gcc flavors that are not inlined - */ - - -/* - * Note: all the if-tests here probably ought to be testing gcc version - * rather than platform, but I don't have adequate info to know what to - * write. Ideally we'd flush all this in favor of the inline version. - */ -#if defined(__m68k__) && !defined(__linux__) -/* really means: extern int tas(slock_t* **lock); */ -static void -tas_dummy() -{ - __asm__ __volatile__( -#if defined(__NetBSD__) && defined(__ELF__) -/* no underscore for label and % for registers */ - "\ -.global tas \n\ -tas: \n\ - movel %sp@(0x4),%a0 \n\ - tas %a0@ \n\ - beq _success \n\ - moveq #-128,%d0 \n\ - rts \n\ -_success: \n\ - moveq #0,%d0 \n\ - rts \n" -#else - "\ -.global _tas \n\ -_tas: \n\ - movel sp@(0x4),a0 \n\ - tas a0@ \n\ - beq _success \n\ - moveq #-128,d0 \n\ - rts \n\ -_success: \n\ - moveq #0,d0 \n\ - rts \n" -#endif /* __NetBSD__ && __ELF__ */ - ); -} -#endif /* __m68k__ && !__linux__ */ -#else /* not __GNUC__ */ - -/* - * All non gcc - */ - - -#if defined(sun3) -static void -tas_dummy() /* really means: extern int tas(slock_t - * *lock); */ -{ - asm("LLA0:"); - asm(" .data"); - asm(" .text"); - asm("|#PROC# 04"); - asm(" .globl _tas"); - asm("_tas:"); - asm("|#PROLOGUE# 1"); - asm(" movel sp@(0x4),a0"); - asm(" tas a0@"); - asm(" beq LLA1"); - asm(" moveq #-128,d0"); - asm(" rts"); - asm("LLA1:"); - asm(" moveq #0,d0"); - asm(" rts"); - asm(" .data"); -} -#endif /* sun3 */ -#endif /* not __GNUC__ */ -#endif /* HAVE_SPINLOCKS */ - - - -/*****************************************************************************/ -#if defined(S_LOCK_TEST) - -/* - * test program for verifying a port's spinlock support. - */ - -struct test_lock_struct -{ - char pad1; - slock_t lock; - char pad2; -}; - -volatile struct test_lock_struct test_lock; - -int -main() -{ - srandom((unsigned int) time(NULL)); - - test_lock.pad1 = test_lock.pad2 = 0x44; - - S_INIT_LOCK(&test_lock.lock); - - if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44) - { - printf("S_LOCK_TEST: failed, declared datatype is wrong size\n"); - return 1; - } - - if (!S_LOCK_FREE(&test_lock.lock)) - { - printf("S_LOCK_TEST: failed, lock not initialized\n"); - return 1; - } - - S_LOCK(&test_lock.lock); - - if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44) - { - printf("S_LOCK_TEST: failed, declared datatype is wrong size\n"); - return 1; - } - - if (S_LOCK_FREE(&test_lock.lock)) - { - printf("S_LOCK_TEST: failed, lock not locked\n"); - return 1; - } - - S_UNLOCK(&test_lock.lock); - - if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44) - { - printf("S_LOCK_TEST: failed, declared datatype is wrong size\n"); - return 1; - } - - if (!S_LOCK_FREE(&test_lock.lock)) - { - printf("S_LOCK_TEST: failed, lock not unlocked\n"); - return 1; - } - - S_LOCK(&test_lock.lock); - - if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44) - { - printf("S_LOCK_TEST: failed, declared datatype is wrong size\n"); - return 1; - } - - if (S_LOCK_FREE(&test_lock.lock)) - { - printf("S_LOCK_TEST: failed, lock not re-locked\n"); - return 1; - } - - printf("S_LOCK_TEST: this will print %d stars and then\n", NUM_DELAYS); - printf(" exit with a 'stuck spinlock' message\n"); - printf(" if S_LOCK() and TAS() are working.\n"); - fflush(stdout); - - s_lock(&test_lock.lock, __FILE__, __LINE__); - - printf("S_LOCK_TEST: failed, lock not locked\n"); - return 1; -} - -#endif /* S_LOCK_TEST */ - -#endif /* APC_SPIN_LOCKS */ diff --git a/pgsql_s_lock.h b/pgsql_s_lock.h deleted file mode 100644 index 63162a3..0000000 --- a/pgsql_s_lock.h +++ /dev/null @@ -1,928 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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. | - +----------------------------------------------------------------------+ - | The following code was ported from the PostgreSQL project, please | - | see appropriate copyright notices that follow. | - | Initial conversion by Brian Shire | - +----------------------------------------------------------------------+ - - */ - -/* $Id: pgsql_s_lock.h,v 3.3.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -/*------------------------------------------------------------------------- - * - * s_lock.h - * Hardware-dependent implementation of spinlocks. - * - * NOTE: none of the macros in this file are intended to be called directly. - * Call them through the hardware-independent macros in spin.h. - * - * The following hardware-dependent macros must be provided for each - * supported platform: - * - * void S_INIT_LOCK(slock_t *lock) - * Initialize a spinlock (to the unlocked state). - * - * void S_LOCK(slock_t *lock) - * Acquire a spinlock, waiting if necessary. - * Time out and abort() if unable to acquire the lock in a - * "reasonable" amount of time --- typically ~ 1 minute. - * - * void S_UNLOCK(slock_t *lock) - * Unlock a previously acquired lock. - * - * bool S_LOCK_FREE(slock_t *lock) - * Tests if the lock is free. Returns TRUE if free, FALSE if locked. - * This does *not* change the state of the lock. - * - * void SPIN_DELAY(void) - * Delay operation to occur inside spinlock wait loop. - * - * Note to implementors: there are default implementations for all these - * macros at the bottom of the file. Check if your platform can use - * these or needs to override them. - * - * Usually, S_LOCK() is implemented in terms of an even lower-level macro - * TAS(): - * - * int TAS(slock_t *lock) - * Atomic test-and-set instruction. Attempt to acquire the lock, - * but do *not* wait. Returns 0 if successful, nonzero if unable - * to acquire the lock. - * - * TAS() is NOT part of the API, and should never be called directly. - * - * CAUTION: on some platforms TAS() may sometimes report failure to acquire - * a lock even when the lock is not locked. For example, on Alpha TAS() - * will "fail" if interrupted. Therefore TAS() should always be invoked - * in a retry loop, even if you are certain the lock is free. - * - * ANOTHER CAUTION: be sure that TAS() and S_UNLOCK() represent sequence - * points, ie, loads and stores of other values must not be moved across - * a lock or unlock. In most cases it suffices to make the operation be - * done through a "volatile" pointer. - * - * On most supported platforms, TAS() uses a tas() function written - * in assembly language to execute a hardware atomic-test-and-set - * instruction. Equivalent OS-supplied mutex routines could be used too. - * - * If no system-specific TAS() is available (ie, HAVE_SPINLOCKS is not - * defined), then we fall back on an emulation that uses SysV semaphores - * (see spin.c). This emulation will be MUCH MUCH slower than a proper TAS() - * implementation, because of the cost of a kernel call per lock or unlock. - * An old report is that Postgres spends around 40% of its time in semop(2) - * when using the SysV semaphore code. - * - * - * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.157 2006/06/07 22:24:45 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -#ifndef S_LOCK_H -#define S_LOCK_H - -/** APC namespace protection ************************************************/ -/* hack to protect against any possible runtime namespace collisions...*/ -#define pg_usleep apc_spin_pg_usleep -#define s_lock apc_spin_s_lock -#define spins_per_delay apc_spin_spins_per_delay -/****************************************************************************/ - - -/* #include "storage/pg_sema.h" -- Removed for APC */ - -#define HAVE_SPINLOCKS 1 /* -- Added for APC */ - -#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ - - -#if defined(__GNUC__) || defined(__ICC) -/************************************************************************* - * All the gcc inlines - * Gcc consistently defines the CPU as __cpu__. - * Other compilers use __cpu or __cpu__ so we test for both in those cases. - */ - -/*---------- - * Standard gcc asm format (assuming "volatile slock_t *lock"): - - __asm__ __volatile__( - " instruction \n" - " instruction \n" - " instruction \n" -: "=r"(_res), "+m"(*lock) // return register, in/out lock value -: "r"(lock) // lock pointer, in input register -: "memory", "cc"); // show clobbered registers here - - * The output-operands list (after first colon) should always include - * "+m"(*lock), whether or not the asm code actually refers to this - * operand directly. This ensures that gcc believes the value in the - * lock variable is used and set by the asm code. Also, the clobbers - * list (after third colon) should always include "memory"; this prevents - * gcc from thinking it can cache the values of shared-memory fields - * across the asm code. Add "cc" if your asm code changes the condition - * code register, and also list any temp registers the code uses. - *---------- - */ - - -#ifdef __i386__ /* 32-bit i386 */ -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - register slock_t _res = 1; - - /* - * Use a non-locking test before asserting the bus lock. Note that the - * extra test appears to be a small loss on some x86 platforms and a small - * win on others; it's by no means clear that we should keep it. - */ - __asm__ __volatile__( - " cmpb $0,%1 \n" - " jne 1f \n" - " lock \n" - " xchgb %0,%1 \n" - "1: \n" -: "+q"(_res), "+m"(*lock) -: -: "memory", "cc"); - return (int) _res; -} - -#define SPIN_DELAY() spin_delay() - -static __inline__ void -spin_delay(void) -{ - /* - * This sequence is equivalent to the PAUSE instruction ("rep" is - * ignored by old IA32 processors if the following instruction is - * not a string operation); the IA-32 Architecture Software - * Developer's Manual, Vol. 3, Section 7.7.2 describes why using - * PAUSE in the inner loop of a spin lock is necessary for good - * performance: - * - * The PAUSE instruction improves the performance of IA-32 - * processors supporting Hyper-Threading Technology when - * executing spin-wait loops and other routines where one - * thread is accessing a shared lock or semaphore in a tight - * polling loop. When executing a spin-wait loop, the - * processor can suffer a severe performance penalty when - * exiting the loop because it detects a possible memory order - * violation and flushes the core processor's pipeline. The - * PAUSE instruction provides a hint to the processor that the - * code sequence is a spin-wait loop. The processor uses this - * hint to avoid the memory order violation and prevent the - * pipeline flush. In addition, the PAUSE instruction - * de-pipelines the spin-wait loop to prevent it from - * consuming execution resources excessively. - */ - __asm__ __volatile__( - " rep; nop \n"); -} - -#endif /* __i386__ */ - - -#ifdef __x86_64__ /* AMD Opteron, Intel EM64T */ -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - register slock_t _res = 1; - - /* - * On Opteron, using a non-locking test before the locking instruction - * is a huge loss. On EM64T, it appears to be a wash or small loss, - * so we needn't bother to try to distinguish the sub-architectures. - */ - __asm__ __volatile__( - " lock \n" - " xchgb %0,%1 \n" -: "+q"(_res), "+m"(*lock) -: -: "memory", "cc"); - return (int) _res; -} - -#define SPIN_DELAY() spin_delay() - -static __inline__ void -spin_delay(void) -{ - /* - * Adding a PAUSE in the spin delay loop is demonstrably a no-op on - * Opteron, but it may be of some use on EM64T, so we keep it. - */ - __asm__ __volatile__( - " rep; nop \n"); -} - -#endif /* __x86_64__ */ - - -#if defined(__ia64__) || defined(__ia64) /* Intel Itanium */ -#define HAS_TEST_AND_SET - -typedef unsigned int slock_t; - -#define TAS(lock) tas(lock) - -#ifndef __INTEL_COMPILER - -static __inline__ int -tas(volatile slock_t *lock) -{ - long int ret; - - __asm__ __volatile__( - " xchg4 %0=%1,%2 \n" -: "=r"(ret), "+m"(*lock) -: "r"(1) -: "memory"); - return (int) ret; -} - -#else /* __INTEL_COMPILER */ - -static __inline__ int -tas(volatile slock_t *lock) -{ - int ret; - - ret = _InterlockedExchange(lock,1); /* this is a xchg asm macro */ - - return ret; -} - -#endif /* __INTEL_COMPILER */ -#endif /* __ia64__ || __ia64 */ - - -#if defined(__arm__) || defined(__arm) -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - register slock_t _res = 1; - - __asm__ __volatile__( - " swpb %0, %0, [%2] \n" -: "+r"(_res), "+m"(*lock) -: "r"(lock) -: "memory"); - return (int) _res; -} - -#endif /* __arm__ */ - - -/* S/390 and S/390x Linux (32- and 64-bit zSeries) */ -#if defined(__s390__) || defined(__s390x__) -#define HAS_TEST_AND_SET - -typedef unsigned int slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - int _res = 0; - - __asm__ __volatile__( - " cs %0,%3,0(%2) \n" -: "+d"(_res), "+m"(*lock) -: "a"(lock), "d"(1) -: "memory", "cc"); - return _res; -} - -#endif /* __s390__ || __s390x__ */ - - -#if defined(__sparc__) /* Sparc */ -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - register slock_t _res; - - /* - * See comment in /pg/backend/port/tas/solaris_sparc.s for why this - * uses "ldstub", and that file uses "cas". gcc currently generates - * sparcv7-targeted binaries, so "cas" use isn't possible. - */ - __asm__ __volatile__( - " ldstub [%2], %0 \n" -: "=r"(_res), "+m"(*lock) -: "r"(lock) -: "memory"); - return (int) _res; -} - -#endif /* __sparc__ */ - - -/* PowerPC */ -#if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__) -#define HAS_TEST_AND_SET - -#if defined(__ppc64__) || defined(__powerpc64__) -typedef unsigned long slock_t; -#else -typedef unsigned int slock_t; -#endif - -#define TAS(lock) tas(lock) -/* - * NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002, - * an isync is a sufficient synchronization barrier after a lwarx/stwcx loop. - */ -static __inline__ int -tas(volatile slock_t *lock) -{ - slock_t _t; - int _res; - - __asm__ __volatile__( -" lwarx %0,0,%3 \n" -" cmpwi %0,0 \n" -" bne 1f \n" -" addi %0,%0,1 \n" -" stwcx. %0,0,%3 \n" -" beq 2f \n" -"1: li %1,1 \n" -" b 3f \n" -"2: \n" -" isync \n" -" li %1,0 \n" -"3: \n" - -: "=&r"(_t), "=r"(_res), "+m"(*lock) -: "r"(lock) -: "memory", "cc"); - return _res; -} - -/* PowerPC S_UNLOCK is almost standard but requires a "sync" instruction */ -#define S_UNLOCK(lock) \ -do \ -{ \ - __asm__ __volatile__ (" sync \n"); \ - *((volatile slock_t *) (lock)) = 0; \ -} while (0) - -#endif /* powerpc */ - - -/* Linux Motorola 68k */ -#if (defined(__mc68000__) || defined(__m68k__)) && defined(__linux__) -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - register int rv; - - __asm__ __volatile__( - " clrl %0 \n" - " tas %1 \n" - " sne %0 \n" -: "=d"(rv), "+m"(*lock) -: -: "memory", "cc"); - return rv; -} - -#endif /* (__mc68000__ || __m68k__) && __linux__ */ - - -/* - * VAXen -- even multiprocessor ones - * (thanks to Tom Ivar Helbekkmo) - */ -#if defined(__vax__) -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - register int _res; - - __asm__ __volatile__( - " movl $1, %0 \n" - " bbssi $0, (%2), 1f \n" - " clrl %0 \n" - "1: \n" -: "=&r"(_res), "+m"(*lock) -: "r"(lock) -: "memory"); - return _res; -} - -#endif /* __vax__ */ - - -#if defined(__ns32k__) /* National Semiconductor 32K */ -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - register int _res; - - __asm__ __volatile__( - " sbitb 0, %1 \n" - " sfsd %0 \n" -: "=r"(_res), "+m"(*lock) -: -: "memory"); - return _res; -} - -#endif /* __ns32k__ */ - - -#if defined(__alpha) || defined(__alpha__) /* Alpha */ -/* - * Correct multi-processor locking methods are explained in section 5.5.3 - * of the Alpha AXP Architecture Handbook, which at this writing can be - * found at ftp://ftp.netbsd.org/pub/NetBSD/misc/dec-docs/index.html. - * For gcc we implement the handbook's code directly with inline assembler. - */ -#define HAS_TEST_AND_SET - -typedef unsigned long slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - register slock_t _res; - - __asm__ __volatile__( - " ldq $0, %1 \n" - " bne $0, 2f \n" - " ldq_l %0, %1 \n" - " bne %0, 2f \n" - " mov 1, $0 \n" - " stq_c $0, %1 \n" - " beq $0, 2f \n" - " mb \n" - " br 3f \n" - "2: mov 1, %0 \n" - "3: \n" -: "=&r"(_res), "+m"(*lock) -: -: "memory", "0"); - return (int) _res; -} - -#define S_UNLOCK(lock) \ -do \ -{\ - __asm__ __volatile__ (" mb \n"); \ - *((volatile slock_t *) (lock)) = 0; \ -} while (0) - -#endif /* __alpha || __alpha__ */ - - -#if defined(__mips__) && !defined(__sgi) /* non-SGI MIPS */ -/* Note: on SGI we use the OS' mutex ABI, see below */ -/* Note: R10000 processors require a separate SYNC */ -#define HAS_TEST_AND_SET - -typedef unsigned int slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - register volatile slock_t *_l = lock; - register int _res; - register int _tmp; - - __asm__ __volatile__( - " .set push \n" - " .set mips2 \n" - " .set noreorder \n" - " .set nomacro \n" - " ll %0, %2 \n" - " or %1, %0, 1 \n" - " sc %1, %2 \n" - " xori %1, 1 \n" - " or %0, %0, %1 \n" - " sync \n" - " .set pop " -: "=&r" (_res), "=&r" (_tmp), "+R" (*_l) -: -: "memory"); - return _res; -} - -/* MIPS S_UNLOCK is almost standard but requires a "sync" instruction */ -#define S_UNLOCK(lock) \ -do \ -{ \ - __asm__ __volatile__( \ - " .set push \n" \ - " .set mips2 \n" \ - " .set noreorder \n" \ - " .set nomacro \n" \ - " sync \n" \ - " .set pop "); \ - *((volatile slock_t *) (lock)) = 0; \ -} while (0) - -#endif /* __mips__ && !__sgi */ - - -/* These live in s_lock.c, but only for gcc */ - - -#if defined(__m68k__) && !defined(__linux__) /* non-Linux Motorola 68k */ -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; -#endif - - -#endif /* __GNUC__ */ - - - -/* - * --------------------------------------------------------------------- - * Platforms that use non-gcc inline assembly: - * --------------------------------------------------------------------- - */ - -#if !defined(HAS_TEST_AND_SET) /* We didn't trigger above, let's try here */ - - -#if defined(USE_UNIVEL_CC) /* Unixware compiler */ -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; - -#define TAS(lock) tas(lock) - -asm int -tas(volatile slock_t *s_lock) -{ -/* UNIVEL wants %mem in column 1, so we don't pg_indent this file */ -%mem s_lock - pushl %ebx - movl s_lock, %ebx - movl $255, %eax - lock - xchgb %al, (%ebx) - popl %ebx -} - -#endif /* defined(USE_UNIVEL_CC) */ - - -#if defined(__alpha) || defined(__alpha__) /* Tru64 Unix Alpha compiler */ -/* - * The Tru64 compiler doesn't support gcc-style inline asm, but it does - * have some builtin functions that accomplish much the same results. - * For simplicity, slock_t is defined as long (ie, quadword) on Alpha - * regardless of the compiler in use. LOCK_LONG and UNLOCK_LONG only - * operate on an int (ie, longword), but that's OK as long as we define - * S_INIT_LOCK to zero out the whole quadword. - */ -#define HAS_TEST_AND_SET - -typedef unsigned long slock_t; - -#include -#define S_INIT_LOCK(lock) (*(lock) = 0) -#define TAS(lock) (__LOCK_LONG_RETRY((lock), 1) == 0) -#define S_UNLOCK(lock) __UNLOCK_LONG(lock) - -#endif /* __alpha || __alpha__ */ - - -#if defined(__hppa) || defined(__hppa__) /* HP PA-RISC, GCC and HP compilers */ -/* - * HP's PA-RISC - * - * See src/backend/port/hpux/tas.c.template for details about LDCWX. Because - * LDCWX requires a 16-byte-aligned address, we declare slock_t as a 16-byte - * struct. The active word in the struct is whichever has the aligned address; - * the other three words just sit at -1. - * - * When using gcc, we can inline the required assembly code. - */ -#define HAS_TEST_AND_SET - -typedef struct -{ - int sema[4]; -} slock_t; - -#define TAS_ACTIVE_WORD(lock) ((volatile int *) (((long) (lock) + 15) & ~15)) - -#if defined(__GNUC__) - -static __inline__ int -tas(volatile slock_t *lock) -{ - volatile int *lockword = TAS_ACTIVE_WORD(lock); - register int lockval; - - __asm__ __volatile__( - " ldcwx 0(0,%2),%0 \n" -: "=r"(lockval), "+m"(*lockword) -: "r"(lockword) -: "memory"); - return (lockval == 0); -} - -#endif /* __GNUC__ */ - -#define S_UNLOCK(lock) (*TAS_ACTIVE_WORD(lock) = -1) - -#define S_INIT_LOCK(lock) \ - do { \ - volatile slock_t *lock_ = (lock); \ - lock_->sema[0] = -1; \ - lock_->sema[1] = -1; \ - lock_->sema[2] = -1; \ - lock_->sema[3] = -1; \ - } while (0) - -#define S_LOCK_FREE(lock) (*TAS_ACTIVE_WORD(lock) != 0) - -#endif /* __hppa || __hppa__ */ - - -#if defined(__hpux) && defined(__ia64) && !defined(__GNUC__) - -#define HAS_TEST_AND_SET - -typedef unsigned int slock_t; - -#include -#define TAS(lock) _Asm_xchg(_SZ_W, lock, 1, _LDHINT_NONE) - -#endif /* HPUX on IA64, non gcc */ - - -#if defined(__sgi) /* SGI compiler */ -/* - * SGI IRIX 5 - * slock_t is defined as a unsigned long. We use the standard SGI - * mutex API. - * - * The following comment is left for historical reasons, but is probably - * not a good idea since the mutex ABI is supported. - * - * This stuff may be supplemented in the future with Masato Kataoka's MIPS-II - * assembly from his NECEWS SVR4 port, but we probably ought to retain this - * for the R3000 chips out there. - */ -#define HAS_TEST_AND_SET - -typedef unsigned long slock_t; - -#include "mutex.h" -#define TAS(lock) (test_and_set(lock,1)) -#define S_UNLOCK(lock) (test_then_and(lock,0)) -#define S_INIT_LOCK(lock) (test_then_and(lock,0)) -#define S_LOCK_FREE(lock) (test_then_add(lock,0) == 0) -#endif /* __sgi */ - - -#if defined(sinix) /* Sinix */ -/* - * SINIX / Reliant UNIX - * slock_t is defined as a struct abilock_t, which has a single unsigned long - * member. (Basically same as SGI) - */ -#define HAS_TEST_AND_SET - -#include "abi_mutex.h" -typedef abilock_t slock_t; - -#define TAS(lock) (!acquire_lock(lock)) -#define S_UNLOCK(lock) release_lock(lock) -#define S_INIT_LOCK(lock) init_lock(lock) -#define S_LOCK_FREE(lock) (stat_lock(lock) == UNLOCKED) -#endif /* sinix */ - - -#if defined(_AIX) /* AIX */ -/* - * AIX (POWER) - */ -#define HAS_TEST_AND_SET - -typedef unsigned int slock_t; - -#define TAS(lock) _check_lock(lock, 0, 1) -#define S_UNLOCK(lock) _clear_lock(lock, 0) -#endif /* _AIX */ - - -#if defined (nextstep) /* Nextstep */ -#define HAS_TEST_AND_SET - -typedef struct mutex slock_t; - -#define APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE 0 /* -- APC: non-blocking lock not available in this case -- */ - -#define S_LOCK(lock) mutex_lock(lock) -#define S_UNLOCK(lock) mutex_unlock(lock) -#define S_INIT_LOCK(lock) mutex_init(lock) -/* For Mach, we have to delve inside the entrails of `struct mutex'. Ick! */ -#define S_LOCK_FREE(alock) ((alock)->lock == 0) -#endif /* nextstep */ - - -/* These are in s_lock.c */ - - -#if defined(sun3) /* Sun3 */ -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; -#endif - - -#if defined(__sun) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc)) -#define HAS_TEST_AND_SET - -#if defined(__i386) || defined(__x86_64__) || defined(__sparcv9) || defined(__sparcv8plus) -typedef unsigned int slock_t; -#else -typedef unsigned char slock_t; -#endif - -extern slock_t pg_atomic_cas(volatile slock_t *lock, slock_t with, - slock_t cmp); - -#define TAS(a) (pg_atomic_cas((a), 1, 0) != 0) -#endif - - -#ifdef WIN32_ONLY_COMPILER -typedef LONG slock_t; - -#define HAS_TEST_AND_SET -#define TAS(lock) (InterlockedCompareExchange(lock, 1, 0)) - -#define SPIN_DELAY() spin_delay() - -static __forceinline void -spin_delay(void) -{ - /* See comment for gcc code. Same code, MASM syntax */ - __asm rep nop; -} - -#endif - - -#endif /* !defined(HAS_TEST_AND_SET) */ - - -/* Blow up if we didn't have any way to do spinlocks */ -#ifndef HAS_TEST_AND_SET -/* -- APC: We have better options in APC than this, that should be specified explicitly so just fail out and notify the user -- */ -#error Spin locking is not available on your platform, please select another locking method (see ./configure --help). -/* #error PostgreSQL does not have native spinlock support on this platform. To continue the compilation, rerun configure using --disable-spinlocks. However, performance will be poor. Please report this to pgsql-bugs@postgresql.org. */ -#endif - - -#else /* !HAVE_SPINLOCKS */ - - -/* - * Fake spinlock implementation using semaphores --- slow and prone - * to fall foul of kernel limits on number of semaphores, so don't use this - * unless you must! The subroutines appear in spin.c. - */ - -/* -- Removed for APC -typedef PGSemaphoreData slock_t; - -extern bool s_lock_free_sema(volatile slock_t *lock); -extern void s_unlock_sema(volatile slock_t *lock); -extern void s_init_lock_sema(volatile slock_t *lock); -extern int tas_sema(volatile slock_t *lock); - -#define S_LOCK_FREE(lock) s_lock_free_sema(lock) -#define S_UNLOCK(lock) s_unlock_sema(lock) -#define S_INIT_LOCK(lock) s_init_lock_sema(lock) -#define TAS(lock) tas_sema(lock) -*/ - -#endif /* HAVE_SPINLOCKS */ - - -/* - * Default Definitions - override these above as needed. - */ - -#define APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE 1 /* -- APC: Non-blocking lock available for this case -- */ - -#if !defined(S_LOCK) -#define S_LOCK(lock) \ - do { \ - if (TAS(lock)) \ - s_lock((lock), __FILE__, __LINE__); \ - } while (0) -#endif /* S_LOCK */ - -#if !defined(S_LOCK_FREE) -#define S_LOCK_FREE(lock) (*(lock) == 0) -#endif /* S_LOCK_FREE */ - -#if !defined(S_UNLOCK) -#define S_UNLOCK(lock) (*((volatile slock_t *) (lock)) = 0) -#endif /* S_UNLOCK */ - -#if !defined(S_INIT_LOCK) -#define S_INIT_LOCK(lock) S_UNLOCK(lock) -#endif /* S_INIT_LOCK */ - -#if !defined(SPIN_DELAY) -#define SPIN_DELAY() ((void) 0) -#endif /* SPIN_DELAY */ - -#if !defined(TAS) -extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or - * s_lock.c */ - -#define TAS(lock) tas(lock) -#endif /* TAS */ - - -/* - * Platform-independent out-of-line support routines - */ -extern void s_lock(volatile slock_t *lock, const char *file, int line); - -/* Support for dynamic adjustment of spins_per_delay */ -#define DEFAULT_SPINS_PER_DELAY 100 - -#if 0 /* -- Removed from APC use -- */ -extern void set_spins_per_delay(int shared_spins_per_delay); -extern int update_spins_per_delay(int shared_spins_per_delay); -#endif - -#endif /* S_LOCK_H */ diff --git a/php5-apc/apc.ini b/php5-apc/apc.ini deleted file mode 100644 index 5f7bdde..0000000 --- a/php5-apc/apc.ini +++ /dev/null @@ -1,2 +0,0 @@ -# configuration for php APC module -extension=apc.so diff --git a/php_apc.c b/php_apc.c deleted file mode 100644 index 207016d..0000000 --- a/php_apc.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | Rasmus Lerdorf | - +----------------------------------------------------------------------+ - - 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.c,v 3.154.2.5 2008/05/11 18:57:00 rasmus Exp $ */ - -#include "apc_zend.h" -#include "apc_cache.h" -#include "apc_main.h" -#include "apc_sma.h" -#include "apc_lock.h" -#include "php_globals.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "SAPI.h" -#include "rfc1867.h" -#include "php_apc.h" -#if PHP_API_VERSION <= 20020918 -#if HAVE_APACHE -#ifdef APC_PHP4_STAT -#undef XtOffsetOf -#include "httpd.h" -#endif -#endif -#endif - -#if HAVE_SIGACTION -#include "apc_signal.h" -#endif - -/* {{{ PHP_FUNCTION declarations */ -PHP_FUNCTION(apc_cache_info); -PHP_FUNCTION(apc_clear_cache); -PHP_FUNCTION(apc_sma_info); -PHP_FUNCTION(apc_store); -PHP_FUNCTION(apc_fetch); -PHP_FUNCTION(apc_delete); -PHP_FUNCTION(apc_compile_file); -PHP_FUNCTION(apc_define_constants); -PHP_FUNCTION(apc_load_constants); -PHP_FUNCTION(apc_add); -/* }}} */ - -/* {{{ ZEND_DECLARE_MODULE_GLOBALS(apc) */ -ZEND_DECLARE_MODULE_GLOBALS(apc) - -/* True globals */ -apc_cache_t* apc_cache = NULL; -apc_cache_t* apc_user_cache = NULL; -void* apc_compiled_filters = NULL; - -static void php_apc_init_globals(zend_apc_globals* apc_globals TSRMLS_DC) -{ - apc_globals->filters = NULL; - apc_globals->initialized = 0; - apc_globals->cache_stack = apc_stack_create(0); - apc_globals->cache_by_default = 1; - apc_globals->slam_defense = 0; - apc_globals->mem_size_ptr = NULL; - apc_globals->fpstat = 1; - apc_globals->stat_ctime = 0; - apc_globals->write_lock = 1; - apc_globals->report_autofilter = 0; - apc_globals->apc_optimize_function = NULL; -#ifdef MULTIPART_EVENT_FORMDATA - apc_globals->rfc1867 = 0; -#endif - apc_globals->copied_zvals = NULL; -#ifdef ZEND_ENGINE_2 - apc_globals->reserved_offset = -1; -#endif - apc_globals->force_file_update = 0; - apc_globals->coredump_unmap = 0; -} - -static void php_apc_shutdown_globals(zend_apc_globals* apc_globals TSRMLS_DC) -{ - /* deallocate the ignore patterns */ - if (apc_globals->filters != NULL) { - int i; - for (i=0; apc_globals->filters[i] != NULL; i++) { - apc_efree(apc_globals->filters[i]); - } - apc_efree(apc_globals->filters); - } - - /* the stack should be empty */ - assert(apc_stack_size(apc_globals->cache_stack) == 0); - - /* apc cleanup */ - apc_stack_destroy(apc_globals->cache_stack); - - /* the rest of the globals are cleaned up in apc_module_shutdown() */ -} - -/* }}} */ - -/* {{{ PHP_INI */ - -static PHP_INI_MH(OnUpdate_filters) /* {{{ */ -{ - APCG(filters) = apc_tokenize(new_value, ','); - return SUCCESS; -} -/* }}} */ - -static PHP_INI_MH(OnUpdateShmSegments) /* {{{ */ -{ -#if APC_MMAP - if(atoi(new_value)!=1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "apc.shm_segments setting ignored in MMAP mode"); - } - APCG(shm_segments) = 1; -#else - APCG(shm_segments) = atoi(new_value); -#endif - return SUCCESS; -} -/* }}} */ - -#ifdef MULTIPART_EVENT_FORMDATA -static PHP_INI_MH(OnUpdateRfc1867Freq) /* {{{ */ -{ - int tmp; - tmp = zend_atoi(new_value, new_value_length); - if(tmp < 0) { - apc_eprint("rfc1867_freq must be greater than or equal to zero."); - return FAILURE; - } - if(new_value[new_value_length-1] == '%') { - if(tmp > 100) { - apc_eprint("rfc1867_freq cannot be over 100%%"); - return FAILURE; - } - APCG(rfc1867_freq) = tmp / 100.0; - } else { - APCG(rfc1867_freq) = tmp; - } - return SUCCESS; -} -/* }}} */ -#endif - -#ifdef ZEND_ENGINE_2 -#define OnUpdateInt OnUpdateLong -#endif - -PHP_INI_BEGIN() -STD_PHP_INI_BOOLEAN("apc.enabled", "1", PHP_INI_SYSTEM, OnUpdateBool, enabled, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.shm_segments", "1", PHP_INI_SYSTEM, OnUpdateShmSegments, shm_segments, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.shm_size", "30", PHP_INI_SYSTEM, OnUpdateInt, shm_size, zend_apc_globals, apc_globals) -STD_PHP_INI_BOOLEAN("apc.include_once_override", "0", PHP_INI_SYSTEM, OnUpdateBool, include_once, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.num_files_hint", "1000", PHP_INI_SYSTEM, OnUpdateInt, num_files_hint, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.user_entries_hint", "4096", PHP_INI_SYSTEM, OnUpdateInt, user_entries_hint, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.gc_ttl", "3600", PHP_INI_SYSTEM, OnUpdateInt, gc_ttl, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.ttl", "0", PHP_INI_SYSTEM, OnUpdateInt, ttl, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.user_ttl", "0", PHP_INI_SYSTEM, OnUpdateInt, user_ttl, zend_apc_globals, apc_globals) -#if APC_MMAP -STD_PHP_INI_ENTRY("apc.mmap_file_mask", NULL, PHP_INI_SYSTEM, OnUpdateString, mmap_file_mask, zend_apc_globals, apc_globals) -#endif -PHP_INI_ENTRY("apc.filters", NULL, PHP_INI_SYSTEM, OnUpdate_filters) -STD_PHP_INI_BOOLEAN("apc.cache_by_default", "1", PHP_INI_ALL, OnUpdateBool, cache_by_default, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.slam_defense", "0", PHP_INI_SYSTEM, OnUpdateInt, slam_defense, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.file_update_protection", "2", PHP_INI_SYSTEM, OnUpdateInt,file_update_protection, zend_apc_globals, apc_globals) -STD_PHP_INI_BOOLEAN("apc.enable_cli", "0", PHP_INI_SYSTEM, OnUpdateBool, enable_cli, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.max_file_size", "1M", PHP_INI_SYSTEM, OnUpdateInt, max_file_size, zend_apc_globals, apc_globals) -STD_PHP_INI_BOOLEAN("apc.stat", "1", PHP_INI_SYSTEM, OnUpdateBool, fpstat, zend_apc_globals, apc_globals) -STD_PHP_INI_BOOLEAN("apc.stat_ctime", "0", PHP_INI_SYSTEM, OnUpdateBool, stat_ctime, zend_apc_globals, apc_globals) -STD_PHP_INI_BOOLEAN("apc.write_lock", "1", PHP_INI_SYSTEM, OnUpdateBool, write_lock, zend_apc_globals, apc_globals) -STD_PHP_INI_BOOLEAN("apc.report_autofilter", "0", PHP_INI_SYSTEM, OnUpdateBool, report_autofilter,zend_apc_globals, apc_globals) -#ifdef MULTIPART_EVENT_FORMDATA -STD_PHP_INI_BOOLEAN("apc.rfc1867", "0", PHP_INI_SYSTEM, OnUpdateBool, rfc1867, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.rfc1867_prefix", "upload_", PHP_INI_SYSTEM, OnUpdateStringUnempty, rfc1867_prefix, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.rfc1867_name", "APC_UPLOAD_PROGRESS", PHP_INI_SYSTEM, OnUpdateStringUnempty, rfc1867_name, zend_apc_globals, apc_globals) -STD_PHP_INI_ENTRY("apc.rfc1867_freq", "0", PHP_INI_SYSTEM, OnUpdateRfc1867Freq, rfc1867_freq, zend_apc_globals, apc_globals) -#endif -STD_PHP_INI_BOOLEAN("apc.coredump_unmap", "0", PHP_INI_SYSTEM, OnUpdateBool, coredump_unmap, zend_apc_globals, apc_globals) -PHP_INI_END() - -/* }}} */ - -/* {{{ PHP_MINFO_FUNCTION(apc) */ -static PHP_MINFO_FUNCTION(apc) -{ - php_info_print_table_start(); - php_info_print_table_row(2, "APC Support", APCG(enabled) ? "enabled" : "disabled"); - php_info_print_table_row(2, "Version", APC_VERSION); -#if APC_MMAP - php_info_print_table_row(2, "MMAP Support", "Enabled"); - php_info_print_table_row(2, "MMAP File Mask", APCG(mmap_file_mask)); -#else - php_info_print_table_row(2, "MMAP Support", "Disabled"); -#endif -#if APC_SEM_LOCKS - php_info_print_table_row(2, "Locking type", "IPC Semaphore"); -#elif APC_FUTEX_LOCKS - php_info_print_table_row(2, "Locking type", "Linux Futex Locks"); -#elif APC_PTHREADMUTEX_LOCKS - php_info_print_table_row(2, "Locking type", "pthread mutex Locks"); -#elif APC_SPIN_LOCKS - php_info_print_table_row(2, "Locking type", "spin Locks"); -#else - php_info_print_table_row(2, "Locking type", "File Locks"); -#endif - php_info_print_table_row(2, "Revision", "$Revision: 3.154.2.5 $"); - php_info_print_table_row(2, "Build Date", __DATE__ " " __TIME__); - php_info_print_table_end(); - DISPLAY_INI_ENTRIES(); -} -/* }}} */ - -#ifdef MULTIPART_EVENT_FORMDATA -extern int apc_rfc1867_progress(unsigned int event, void *event_data, void **extra TSRMLS_DC); -#endif - -/* {{{ PHP_MINIT_FUNCTION(apc) */ -static PHP_MINIT_FUNCTION(apc) -{ - ZEND_INIT_MODULE_GLOBALS(apc, php_apc_init_globals, php_apc_shutdown_globals); - - REGISTER_INI_ENTRIES(); - - /* Disable APC in cli mode unless overridden by apc.enable_cli */ - if(!APCG(enable_cli) && !strcmp(sapi_module.name, "cli")) { - APCG(enabled) = 0; - } - - if (APCG(enabled)) { - if(APCG(initialized)) { - apc_process_init(module_number TSRMLS_CC); - } else { - apc_module_init(module_number TSRMLS_CC); - apc_zend_init(TSRMLS_C); - apc_process_init(module_number TSRMLS_CC); -#ifdef MULTIPART_EVENT_FORMDATA - /* File upload progress tracking */ - if(APCG(rfc1867)) { - php_rfc1867_callback = apc_rfc1867_progress; - } -#endif - } - } - - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_MSHUTDOWN_FUNCTION(apc) */ -static PHP_MSHUTDOWN_FUNCTION(apc) -{ - if(APCG(enabled)) { - apc_process_shutdown(TSRMLS_C); - apc_zend_shutdown(TSRMLS_C); - apc_module_shutdown(TSRMLS_C); -#ifndef ZTS - php_apc_shutdown_globals(&apc_globals); -#endif -#if HAVE_SIGACTION - apc_shutdown_signals(); -#endif - } -#ifdef ZTS - ts_free_id(apc_globals_id); -#endif - UNREGISTER_INI_ENTRIES(); - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_RINIT_FUNCTION(apc) */ -static PHP_RINIT_FUNCTION(apc) -{ - if(APCG(enabled)) { - apc_request_init(TSRMLS_C); - -#if HAVE_SIGACTION - apc_set_signals(TSRMLS_C); -#endif - } - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_RSHUTDOWN_FUNCTION(apc) */ -static PHP_RSHUTDOWN_FUNCTION(apc) -{ - if(APCG(enabled)) { - apc_request_shutdown(TSRMLS_C); - } - return SUCCESS; -} -/* }}} */ - -/* {{{ proto array apc_cache_info([string type] [, bool limited]) */ -PHP_FUNCTION(apc_cache_info) -{ - apc_cache_info_t* info; - apc_cache_link_t* p; - zval* list; - char *cache_type; - int ct_len; - zend_bool limited=0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sb", &cache_type, &ct_len, &limited) == FAILURE) { - return; - } - - if(ZEND_NUM_ARGS()) { - if(!strcasecmp(cache_type,"user")) { - info = apc_cache_info(apc_user_cache, limited); - } else if(!strcasecmp(cache_type,"filehits")) { -#ifdef APC_FILEHITS - RETVAL_ZVAL(APCG(filehits), 1, 0); - return; -#else - RETURN_FALSE; -#endif - } else { - info = apc_cache_info(apc_cache, limited); - } - } else info = apc_cache_info(apc_cache, limited); - - if(!info) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "No APC info available. Perhaps APC is not enabled? Check apc.enabled in your ini file"); - RETURN_FALSE; - } - - array_init(return_value); - add_assoc_long(return_value, "num_slots", info->num_slots); - add_assoc_long(return_value, "ttl", info->ttl); - add_assoc_long(return_value, "num_hits", info->num_hits); - add_assoc_long(return_value, "num_misses", info->num_misses); - add_assoc_long(return_value, "start_time", info->start_time); - add_assoc_long(return_value, "expunges", info->expunges); - add_assoc_long(return_value, "mem_size", info->mem_size); - add_assoc_long(return_value, "num_entries", info->num_entries); - add_assoc_long(return_value, "num_inserts", info->num_inserts); -#ifdef MULTIPART_EVENT_FORMDATA - add_assoc_long(return_value, "file_upload_progress", 1); -#else - add_assoc_long(return_value, "file_upload_progress", 0); -#endif -#if APC_MMAP - add_assoc_stringl(return_value, "memory_type", "mmap", sizeof("mmap")-1, 1); -#else - add_assoc_stringl(return_value, "memory_type", "IPC shared", sizeof("IPC shared")-1, 1); -#endif -#if APC_SEM_LOCKS - add_assoc_stringl(return_value, "locking_type", "IPC semaphore", sizeof("IPC semaphore")-1, 1); -#elif APC_FUTEX_LOCKS - add_assoc_stringl(return_value, "locking_type", "Linux Futex", sizeof("Linux Futex")-1, 1); -#elif APC_PTHREADMUTEX_LOCKS - add_assoc_stringl(return_value, "locking_type", "pthread mutex", sizeof("pthread mutex")-1, 1); -#elif APC_SPIN_LOCKS - add_assoc_stringl(return_value, "locking_type", "spin", sizeof("spin")-1, 1); -#else - add_assoc_stringl(return_value, "locking_type", "file", sizeof("file")-1, 1); -#endif - if(limited) { - apc_cache_free_info(info); - return; - } - - ALLOC_INIT_ZVAL(list); - array_init(list); - - for (p = info->list; p != NULL; p = p->next) { - zval* link; - - ALLOC_INIT_ZVAL(link); - array_init(link); - - if(p->type == APC_CACHE_ENTRY_FILE) { - add_assoc_string(link, "filename", p->data.file.filename, 1); - add_assoc_long(link, "device", p->data.file.device); - add_assoc_long(link, "inode", p->data.file.inode); - add_assoc_string(link, "type", "file", 1); - } else if(p->type == APC_CACHE_ENTRY_USER) { - add_assoc_string(link, "info", p->data.user.info, 1); - add_assoc_long(link, "ttl", (long)p->data.user.ttl); - add_assoc_string(link, "type", "user", 1); - } - add_assoc_long(link, "num_hits", p->num_hits); - add_assoc_long(link, "mtime", p->mtime); - add_assoc_long(link, "creation_time", p->creation_time); - add_assoc_long(link, "deletion_time", p->deletion_time); - add_assoc_long(link, "access_time", p->access_time); - add_assoc_long(link, "ref_count", p->ref_count); - add_assoc_long(link, "mem_size", p->mem_size); - add_next_index_zval(list, link); - } - add_assoc_zval(return_value, "cache_list", list); - - ALLOC_INIT_ZVAL(list); - array_init(list); - - for (p = info->deleted_list; p != NULL; p = p->next) { - zval* link; - - ALLOC_INIT_ZVAL(link); - array_init(link); - - if(p->type == APC_CACHE_ENTRY_FILE) { - add_assoc_string(link, "filename", p->data.file.filename, 1); - add_assoc_long(link, "device", p->data.file.device); - add_assoc_long(link, "inode", p->data.file.inode); - add_assoc_string(link, "type", "file", 1); - } else if(p->type == APC_CACHE_ENTRY_USER) { - add_assoc_string(link, "info", p->data.user.info, 1); - add_assoc_long(link, "ttl", (long)p->data.user.ttl); - add_assoc_string(link, "type", "user", 1); - } - add_assoc_long(link, "num_hits", p->num_hits); - add_assoc_long(link, "mtime", p->mtime); - add_assoc_long(link, "creation_time", p->creation_time); - add_assoc_long(link, "deletion_time", p->deletion_time); - add_assoc_long(link, "access_time", p->access_time); - add_assoc_long(link, "ref_count", p->ref_count); - add_assoc_long(link, "mem_size", p->mem_size); - add_next_index_zval(list, link); - } - add_assoc_zval(return_value, "deleted_list", list); - - apc_cache_free_info(info); -} -/* }}} */ - -/* {{{ proto void apc_clear_cache([string cache]) */ -PHP_FUNCTION(apc_clear_cache) -{ - char *cache_type; - int ct_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &cache_type, &ct_len) == FAILURE) { - return; - } - - if(ZEND_NUM_ARGS()) { - if(!strcasecmp(cache_type,"user")) { - apc_cache_clear(apc_user_cache); - RETURN_TRUE; - } - } - apc_cache_clear(apc_cache); -} -/* }}} */ - -/* {{{ proto array apc_sma_info([bool limited]) */ -PHP_FUNCTION(apc_sma_info) -{ - apc_sma_info_t* info; - zval* block_lists; - int i; - zend_bool limited = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &limited) == FAILURE) { - return; - } - - info = apc_sma_info(limited); - - if(!info) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "No APC SMA info available. Perhaps APC is disabled via apc.enabled?"); - RETURN_FALSE; - } - - array_init(return_value); - add_assoc_long(return_value, "num_seg", info->num_seg); - add_assoc_long(return_value, "seg_size", info->seg_size); - add_assoc_long(return_value, "avail_mem", apc_sma_get_avail_mem()); - - if(limited) { - apc_sma_free_info(info); - return; - } - -#if ALLOC_DISTRIBUTION - { - size_t *adist = apc_sma_get_alloc_distribution(); - zval* list; - ALLOC_INIT_ZVAL(list); - array_init(list); - for(i=0; i<30; i++) { - add_next_index_long(list, adist[i]); - } - add_assoc_zval(return_value, "adist", list); - } -#endif - ALLOC_INIT_ZVAL(block_lists); - array_init(block_lists); - - for (i = 0; i < info->num_seg; i++) { - apc_sma_link_t* p; - zval* list; - - ALLOC_INIT_ZVAL(list); - array_init(list); - - for (p = info->list[i]; p != NULL; p = p->next) { - zval* link; - - ALLOC_INIT_ZVAL(link); - array_init(link); - - add_assoc_long(link, "size", p->size); - add_assoc_long(link, "offset", p->offset); - add_next_index_zval(list, link); - } - add_next_index_zval(block_lists, list); - } - add_assoc_zval(return_value, "block_lists", block_lists); - apc_sma_free_info(info); -} -/* }}} */ - -/* {{{ _apc_store */ -int _apc_store(char *strkey, int strkey_len, const zval *val, const unsigned int ttl, const int exclusive TSRMLS_DC) { - apc_cache_entry_t *entry; - apc_cache_key_t key; - time_t t; - size_t mem_size = 0; - -#if PHP_API_VERSION < 20041225 -#if HAVE_APACHE && defined(APC_PHP4_STAT) - t = ((request_rec *)SG(server_context))->request_time; -#else - t = time(0); -#endif -#else - t = sapi_get_request_time(TSRMLS_C); -#endif - - if(!APCG(enabled)) return 0; - - HANDLE_BLOCK_INTERRUPTIONS(); - - APCG(mem_size_ptr) = &mem_size; - if (!(entry = apc_cache_make_user_entry(strkey, strkey_len + 1, val, ttl))) { - APCG(mem_size_ptr) = NULL; - apc_cache_expunge(apc_cache,t); - apc_cache_expunge(apc_user_cache,t); - HANDLE_UNBLOCK_INTERRUPTIONS(); - return 0; - } - - if (!apc_cache_make_user_key(&key, strkey, strkey_len + 1, t)) { - APCG(mem_size_ptr) = NULL; - apc_cache_free_entry(entry); - /* make_user_key doesn't allocate anything, so no expunge */ - HANDLE_UNBLOCK_INTERRUPTIONS(); - return 0; - } - - if (!apc_cache_user_insert(apc_user_cache, key, entry, t, exclusive TSRMLS_CC)) { - apc_cache_free_entry(entry); - APCG(mem_size_ptr) = NULL; - /* - No expunge here - user_insert can fail for non-memory related reasons - The alloc-based expunge hook in 3.1 will do a better job here - (removing the expunge here also fixes bug #13336) - */ - HANDLE_UNBLOCK_INTERRUPTIONS(); - return 0; - } - - APCG(mem_size_ptr) = NULL; - - HANDLE_UNBLOCK_INTERRUPTIONS(); - - return 1; -} -/* }}} */ - -/* {{{ proto int apc_store(string key, mixed var [, long ttl ]) - */ -PHP_FUNCTION(apc_store) { - zval *val; - char *strkey; - int strkey_len; - long ttl = 0L; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &strkey, &strkey_len, &val, &ttl) == FAILURE) { - return; - } - - if(!strkey_len) RETURN_FALSE; - - if(_apc_store(strkey, strkey_len, val, (unsigned int)ttl, 0 TSRMLS_CC)) RETURN_TRUE; - RETURN_FALSE; -} -/* }}} */ - -/* {{{ proto int apc_add(string key, mixed var [, long ttl ]) - */ -PHP_FUNCTION(apc_add) { - zval *val; - char *strkey; - int strkey_len; - long ttl = 0L; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &strkey, &strkey_len, &val, &ttl) == FAILURE) { - return; - } - - if(!strkey_len) RETURN_FALSE; - - if(_apc_store(strkey, strkey_len, val, (unsigned int)ttl, 1 TSRMLS_CC)) RETURN_TRUE; - RETURN_FALSE; -} -/* }}} */ - -void *apc_erealloc_wrapper(void *ptr, size_t size) { - return _erealloc(ptr, size, 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); -} -/* {{{ RETURN_ZVAL for php4 */ -#if !defined(ZEND_ENGINE_2) && !defined(RETURN_ZVAL) -#define RETURN_ZVAL(zv, copy, dtor) { RETVAL_ZVAL(zv, copy, dtor); return; } -#define RETVAL_ZVAL(zv, copy, dtor) ZVAL_ZVAL(return_value, zv, copy, dtor) -#define ZVAL_ZVAL(z, zv, copy, dtor) { \ - int is_ref, refcount; \ - is_ref = (z)->is_ref; \ - refcount = (z)->refcount; \ - *(z) = *(zv); \ - if (copy) { \ - zval_copy_ctor(z); \ - } \ - if (dtor) { \ - if (!copy) { \ - ZVAL_NULL(zv); \ - } \ - zval_ptr_dtor(&zv); \ - } \ - (z)->is_ref = is_ref; \ - (z)->refcount = refcount; \ - } -#endif -/* }}} */ - -/* {{{ proto mixed apc_fetch(mixed key[, bool &success]) - */ -PHP_FUNCTION(apc_fetch) { - zval *key; - zval *success = NULL; - HashTable *hash; - HashPosition hpos; - zval **hentry; - zval *result; - zval *result_entry; - char *strkey; - int strkey_len; - apc_cache_entry_t* entry; - time_t t; - - if(!APCG(enabled)) RETURN_FALSE; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &key, &success) == FAILURE) { - return; - } - -#if PHP_API_VERSION < 20041225 -#if HAVE_APACHE && defined(APC_PHP4_STAT) - t = ((request_rec *)SG(server_context))->request_time; -#else - t = time(0); -#endif -#else - t = sapi_get_request_time(TSRMLS_C); -#endif - - if (success) { - ZVAL_BOOL(success, 0); - } - - if(Z_TYPE_P(key) != IS_STRING && Z_TYPE_P(key) != IS_ARRAY) { - convert_to_string(key); - } - - if(Z_TYPE_P(key) == IS_STRING) { - strkey = Z_STRVAL_P(key); - strkey_len = Z_STRLEN_P(key); - if(!strkey_len) RETURN_FALSE; - entry = apc_cache_user_find(apc_user_cache, strkey, strkey_len + 1, t); - if(entry) { - /* deep-copy returned shm zval to emalloc'ed return_value */ - apc_cache_fetch_zval(return_value, entry->data.user.val, apc_php_malloc, apc_php_free); - apc_cache_release(apc_user_cache, entry); - } else { - RETURN_FALSE; - } - } else if(Z_TYPE_P(key) == IS_ARRAY) { - hash = Z_ARRVAL_P(key); - MAKE_STD_ZVAL(result); - array_init(result); - zend_hash_internal_pointer_reset_ex(hash, &hpos); - while(zend_hash_get_current_data_ex(hash, (void**)&hentry, &hpos) == SUCCESS) { - if(Z_TYPE_PP(hentry) != IS_STRING) { - apc_wprint("apc_fetch() expects a string or array of strings."); - RETURN_FALSE; - } - entry = apc_cache_user_find(apc_user_cache, Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) + 1, t); - if(entry) { - /* deep-copy returned shm zval to emalloc'ed return_value */ - MAKE_STD_ZVAL(result_entry); - apc_cache_fetch_zval(result_entry, entry->data.user.val, apc_php_malloc, apc_php_free); - apc_cache_release(apc_user_cache, entry); - zend_hash_add(Z_ARRVAL_P(result), Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) +1, &result_entry, sizeof(zval*), NULL); - } /* don't set values we didn't find */ - zend_hash_move_forward_ex(hash, &hpos); - } - RETVAL_ZVAL(result, 0, 1); - } else { - apc_wprint("apc_fetch() expects a string or array of strings."); - RETURN_FALSE; - } - - if (success) { - ZVAL_BOOL(success, 1); - } - - return; -} -/* }}} */ - -/* {{{ proto mixed apc_delete(string key) - */ -PHP_FUNCTION(apc_delete) { - char *strkey; - int strkey_len; - - if(!APCG(enabled)) RETURN_FALSE; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &strkey, &strkey_len) == FAILURE) { - return; - } - - if(!strkey_len) RETURN_FALSE; - - if(apc_cache_user_delete(apc_user_cache, strkey, strkey_len + 1)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } -} -/* }}} */ - -static void _apc_define_constants(zval *constants, zend_bool case_sensitive TSRMLS_DC) { - char *const_key; - unsigned int const_key_len; - zval **entry; - HashPosition pos; - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(constants), &pos); - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(constants), (void**)&entry, &pos) == SUCCESS) { - zend_constant c; - int key_type; - ulong num_key; - - key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(constants), &const_key, &const_key_len, &num_key, 0, &pos); - if(key_type != HASH_KEY_IS_STRING) { - zend_hash_move_forward_ex(Z_ARRVAL_P(constants), &pos); - continue; - } - switch(Z_TYPE_PP(entry)) { - case IS_LONG: - case IS_DOUBLE: - case IS_STRING: - case IS_BOOL: - case IS_RESOURCE: - case IS_NULL: - break; - default: - zend_hash_move_forward_ex(Z_ARRVAL_P(constants), &pos); - continue; - } - c.value = **entry; - zval_copy_ctor(&c.value); - c.flags = case_sensitive; - c.name = zend_strndup(const_key, const_key_len); - c.name_len = const_key_len; -#ifdef ZEND_ENGINE_2 - c.module_number = PHP_USER_CONSTANT; -#endif - zend_register_constant(&c TSRMLS_CC); - - zend_hash_move_forward_ex(Z_ARRVAL_P(constants), &pos); - } -} - -/* {{{ proto mixed apc_define_constants(string key, array constants [,bool case-sensitive]) - */ -PHP_FUNCTION(apc_define_constants) { - char *strkey; - int strkey_len; - zval *constants = NULL; - zend_bool case_sensitive = 1; - int argc = ZEND_NUM_ARGS(); - - if (zend_parse_parameters(argc TSRMLS_CC, "sa|b", &strkey, &strkey_len, &constants, &case_sensitive) == FAILURE) { - return; - } - - if(!strkey_len) RETURN_FALSE; - - _apc_define_constants(constants, case_sensitive TSRMLS_CC); - if(_apc_store(strkey, strkey_len, constants, 0, 0 TSRMLS_CC)) RETURN_TRUE; - RETURN_FALSE; -} /* }}} */ - -/* {{{ proto mixed apc_load_constants(string key [, bool case-sensitive]) - */ -PHP_FUNCTION(apc_load_constants) { - char *strkey; - int strkey_len; - apc_cache_entry_t* entry; - time_t t; - zend_bool case_sensitive = 1; - - if(!APCG(enabled)) RETURN_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &strkey, &strkey_len, &case_sensitive) == FAILURE) { - return; - } - - if(!strkey_len) RETURN_FALSE; - -#if PHP_API_VERSION < 20041225 -#if HAVE_APACHE && defined(APC_PHP4_STAT) - t = ((request_rec *)SG(server_context))->request_time; -#else - t = time(0); -#endif -#else - t = sapi_get_request_time(TSRMLS_C); -#endif - - entry = apc_cache_user_find(apc_user_cache, strkey, strkey_len + 1, t); - - if(entry) { - _apc_define_constants(entry->data.user.val, case_sensitive TSRMLS_CC); - apc_cache_release(apc_user_cache, entry); - RETURN_TRUE; - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ proto boolean apc_compile_file(string filename) - */ -PHP_FUNCTION(apc_compile_file) { - char *filename; - int filename_len; - zend_file_handle file_handle; - zend_op_array *op_array; - long slam_defense = 0; - char** filters = NULL; - zend_bool cache_by_default = 1; - HashTable cg_function_table, cg_class_table, eg_function_table, eg_class_table; - HashTable *cg_orig_function_table, *cg_orig_class_table, *eg_orig_function_table, *eg_orig_class_table; - - if(!APCG(enabled)) RETURN_FALSE; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { - return; - } - - if(!filename) RETURN_FALSE; - - /* reset slam defense, filters, and cache_by_default */ - slam_defense = APCG(slam_defense); - APCG(slam_defense) = 0; - - filters = APCG(filters); - APCG(filters) = NULL; - - cache_by_default = APCG(cache_by_default); - APCG(cache_by_default) = 1; - - /* Replace function/class tables to avoid namespace conflicts */ - zend_hash_init_ex(&cg_function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0); - cg_orig_function_table = CG(function_table); - CG(function_table) = &cg_function_table; - zend_hash_init_ex(&cg_class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0); - cg_orig_class_table = CG(class_table); - CG(class_table) = &cg_class_table; - eg_orig_function_table = EG(function_table); - EG(function_table) = CG(function_table); - eg_orig_class_table = EG(class_table); - EG(class_table) = CG(class_table); - APCG(force_file_update) = 1; - - /* Compile the file, loading it into the cache */ - file_handle.type = ZEND_HANDLE_FILENAME; - file_handle.filename = filename; - file_handle.free_filename = 0; - file_handle.opened_path = NULL; - zend_try { - op_array = zend_compile_file(&file_handle, ZEND_INCLUDE TSRMLS_CC); - } zend_catch { - apc_wprint("Error compiling %s in apc_compile_file.", filename); - op_array = NULL; - } zend_end_try(); - - /* Return class/function tables to previous states, destroy temp tables */ - APCG(force_file_update) = 0; - CG(function_table) = cg_orig_function_table; - zend_hash_destroy(&cg_function_table); - CG(class_table) = cg_orig_class_table; - zend_hash_destroy(&cg_class_table); - EG(function_table) = eg_orig_function_table; - EG(class_table) = eg_orig_class_table; - - /* Restore global settings */ - APCG(slam_defense) = slam_defense; - APCG(filters) = filters; - APCG(cache_by_default) = cache_by_default; - - if(op_array == NULL) { RETURN_FALSE; } - - /* Free up everything */ - zend_destroy_file_handle(&file_handle TSRMLS_CC); -#ifdef ZEND_ENGINE_2 - destroy_op_array(op_array TSRMLS_CC); -#else - destroy_op_array(op_array); -#endif - efree(op_array); - - RETURN_TRUE; -} -/* }}} */ - -#ifdef ZEND_ENGINE_2 -/* {{{ arginfo */ -static -ZEND_BEGIN_ARG_INFO(php_apc_fetch_arginfo, 0) - ZEND_ARG_INFO(0, "key") - ZEND_ARG_INFO(1, "success") -ZEND_END_ARG_INFO() -/* }}} */ -#else -#define php_apc_fetch_arginfo NULL -#endif - - -/* {{{ apc_functions[] */ -function_entry apc_functions[] = { - PHP_FE(apc_cache_info, NULL) - PHP_FE(apc_clear_cache, NULL) - PHP_FE(apc_sma_info, NULL) - PHP_FE(apc_store, NULL) - PHP_FE(apc_fetch, php_apc_fetch_arginfo) - PHP_FE(apc_delete, NULL) - PHP_FE(apc_define_constants, NULL) - PHP_FE(apc_load_constants, NULL) - PHP_FE(apc_compile_file, NULL) - PHP_FE(apc_add, NULL) - {NULL, NULL, NULL} -}; -/* }}} */ - -/* {{{ module definition structure */ - -zend_module_entry apc_module_entry = { - STANDARD_MODULE_HEADER, - "apc", - apc_functions, - PHP_MINIT(apc), - PHP_MSHUTDOWN(apc), - PHP_RINIT(apc), - PHP_RSHUTDOWN(apc), - PHP_MINFO(apc), - APC_VERSION, - STANDARD_MODULE_PROPERTIES -}; - -#ifdef COMPILE_DL_APC -ZEND_GET_MODULE(apc) -#endif -/* }}} */ - -/* - * 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 - */ diff --git a/php_apc.h b/php_apc.h deleted file mode 100644 index 8eb6861..0000000 --- a/php_apc.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | APC | - +----------------------------------------------------------------------+ - | Copyright (c) 2008 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 | - | George Schlossnagle | - | Rasmus Lerdorf | - +----------------------------------------------------------------------+ - - 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,v 3.14.2.1 2008/05/11 18:57:00 rasmus Exp $ */ - -#ifndef PHP_APC_H -#define PHP_APC_H - -#include "apc_php.h" -#include "apc_globals.h" - -extern zend_module_entry apc_module_entry; -#define apc_module_ptr &apc_module_entry - -#define phpext_apc_ptr apc_module_ptr - -#endif /* PHP_APC_H */ - -/* - * 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 - */ diff --git a/tests/apc_001.phpt b/tests/apc_001.phpt deleted file mode 100644 index c1592de..0000000 --- a/tests/apc_001.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -APC: apc_store/fetch with strings ---SKIPIF-- - ---INI-- -apc.enabled=1 -apc.enable_cli=1 -apc.file_update_protection=0 ---FILE-- - -===DONE=== - ---EXPECTF-- -string(11) "hello world" -string(11) "hello world" -string(4) "nice" -===DONE=== diff --git a/tests/apc_002.phpt b/tests/apc_002.phpt deleted file mode 100644 index 8f22162..0000000 --- a/tests/apc_002.phpt +++ /dev/null @@ -1,34 +0,0 @@ ---TEST-- -APC: apc_store/fetch with objects ---SKIPIF-- - ---INI-- -apc.enabled=1 -apc.enable_cli=1 -apc.file_update_protection=0 ---FILE-- -a = true; -var_dump($bar); - -?> -===DONE=== - ---EXPECTF-- -object(foo)#%d (0) { -} -object(foo)#%d (0) { -} -object(foo)#%d (1) { - ["a"]=> - bool(true) -} -===DONE=== diff --git a/tests/apc_003.phpt b/tests/apc_003.phpt deleted file mode 100644 index 8f4876e..0000000 --- a/tests/apc_003.phpt +++ /dev/null @@ -1,99 +0,0 @@ ---TEST-- -APC: apc_store/fetch with objects ---SKIPIF-- - ---INI-- -apc.enabled=1 -apc.enable_cli=1 -apc.file_update_protection=0 ---FILE-- -a = true; -print_r($bar); - -class bar extends foo -{ - public $pub = 'bar'; - protected $pro = 'bar'; - private $pri = 'bar'; // we don't see this, we'd need php 5.1 new serialization - - function __construct() - { - $this->bar = true; - } - - function change() - { - $this->pri = 'mod'; - } -} - -class baz extends bar -{ - private $pri = 'baz'; - - function __construct() - { - parent::__construct(); - $this->baz = true; - } -} - -$baz = new baz; -print_r($baz); -$baz->change(); -print_r($baz); -apc_store('baz', $baz); -unset($baz); -print_r(apc_fetch('baz')); - -?> -===DONE=== - ---EXPECTF-- -foo Object -( -) -foo Object -( -) -foo Object -( - [a] => 1 -) -baz Object -( - [pri%sprivate] => baz - [pub] => bar - [pro:protected] => bar - [pri%sprivate] => bar - [bar] => 1 - [baz] => 1 -) -baz Object -( - [pri%sprivate] => baz - [pub] => bar - [pro:protected] => bar - [pri%sprivate] => mod - [bar] => 1 - [baz] => 1 -) -baz Object -( - [pri%sprivate] => baz - [pub] => bar - [pro:protected] => bar - [pri%sprivate] => mod - [bar] => 1 - [baz] => 1 -) -===DONE=== diff --git a/tests/skipif.inc b/tests/skipif.inc deleted file mode 100644 index 18c75f2..0000000 --- a/tests/skipif.inc +++ /dev/null @@ -1,6 +0,0 @@ -