From a34ea625346aecd2d2b227b8ca4f114eaa607213 Mon Sep 17 00:00:00 2001 From: Dragan Dosen Date: Sun, 19 Apr 2009 18:28:19 +0200 Subject: [PATCH] php5-apc retained as dummy package. debian/control: + depends on Debian package php-apc. --- CHANGELOG | 227 ---- INSTALL | 417 -------- LICENSE | 68 -- NOTICE | 43 - TECHNOTES.txt | 361 ------- TODO | 30 - apc.c | 562 ---------- apc.dsp | 207 ---- apc.h | 121 --- apc.php | 1341 ------------------------ apc_cache.c | 1114 -------------------- apc_cache.h | 341 ------ apc_compile.c | 2591 ---------------------------------------------- apc_compile.h | 134 --- apc_debug.c | 57 - apc_debug.h | 1 - apc_fcntl.c | 118 --- apc_fcntl.h | 50 - apc_fcntl_win32.c | 117 --- apc_futex.c | 116 --- apc_futex.h | 55 - apc_globals.h | 116 --- apc_lock.h | 105 -- apc_main.c | 688 ------------ apc_main.h | 57 - apc_mmap.c | 139 --- apc_php.h | 74 -- apc_pool.c | 344 ------ apc_pool.h | 58 -- apc_pthreadmutex.c | 111 -- apc_pthreadmutex.h | 48 - apc_rfc1867.c | 195 ---- apc_sem.c | 177 ---- apc_sem.h | 51 - apc_shm.c | 110 -- apc_shm.h | 54 - apc_signal.c | 192 ---- apc_signal.h | 51 - apc_sma.c | 635 ------------ apc_sma.h | 88 -- apc_spin.c | 65 -- apc_spin.h | 48 - apc_stack.c | 105 -- apc_stack.h | 58 -- apc_zend.c | 277 ----- apc_zend.h | 53 - arch/atomic.h | 38 - arch/i386/atomic.h | 79 -- arch/x86_64/atomic.h | 80 -- config.m4 | 254 ----- debian/changelog | 8 + debian/control | 18 +- debian/copyright | 128 --- debian/install | 1 - debian/php5-apc.postinst | 20 - debian/rules | 83 +- pgsql_s_lock.c | 481 --------- pgsql_s_lock.h | 928 ----------------- php5-apc/apc.ini | 2 - php_apc.c | 1012 ------------------ php_apc.h | 52 - tests/apc_001.phpt | 27 - tests/apc_002.phpt | 34 - tests/apc_003.phpt | 99 -- tests/skipif.inc | 6 - 65 files changed, 38 insertions(+), 15282 deletions(-) delete mode 100644 CHANGELOG delete mode 100644 INSTALL delete mode 100644 LICENSE delete mode 100644 NOTICE delete mode 100644 TECHNOTES.txt delete mode 100644 TODO delete mode 100644 apc.c delete mode 100644 apc.dsp delete mode 100644 apc.h delete mode 100644 apc.php delete mode 100644 apc_cache.c delete mode 100644 apc_cache.h delete mode 100644 apc_compile.c delete mode 100644 apc_compile.h delete mode 100644 apc_debug.c delete mode 100644 apc_debug.h delete mode 100644 apc_fcntl.c delete mode 100644 apc_fcntl.h delete mode 100644 apc_fcntl_win32.c delete mode 100644 apc_futex.c delete mode 100644 apc_futex.h delete mode 100644 apc_globals.h delete mode 100644 apc_lock.h delete mode 100644 apc_main.c delete mode 100644 apc_main.h delete mode 100644 apc_mmap.c delete mode 100644 apc_php.h delete mode 100644 apc_pool.c delete mode 100644 apc_pool.h delete mode 100644 apc_pthreadmutex.c delete mode 100644 apc_pthreadmutex.h delete mode 100644 apc_rfc1867.c delete mode 100644 apc_sem.c delete mode 100644 apc_sem.h delete mode 100644 apc_shm.c delete mode 100644 apc_shm.h delete mode 100644 apc_signal.c delete mode 100644 apc_signal.h delete mode 100644 apc_sma.c delete mode 100644 apc_sma.h delete mode 100644 apc_spin.c delete mode 100644 apc_spin.h delete mode 100644 apc_stack.c delete mode 100644 apc_stack.h delete mode 100644 apc_zend.c delete mode 100644 apc_zend.h delete mode 100644 arch/atomic.h delete mode 100644 arch/i386/atomic.h delete mode 100644 arch/x86_64/atomic.h delete mode 100644 config.m4 delete mode 100644 debian/copyright delete mode 100644 debian/install delete mode 100644 debian/php5-apc.postinst delete mode 100644 pgsql_s_lock.c delete mode 100644 pgsql_s_lock.h delete mode 100644 php5-apc/apc.ini delete mode 100644 php_apc.c delete mode 100644 php_apc.h delete mode 100644 tests/apc_001.phpt delete mode 100644 tests/apc_002.phpt delete mode 100644 tests/apc_003.phpt delete mode 100644 tests/skipif.inc 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 @@ - -- 1.7.10.4