APC 3.0.15
リリースされてました。
積極的にメンテナンスされているのは嬉しいんだけど、またパラメータが(3つ)追加されてますね。
どういう局面で嬉しいのか(まだ)理解できていないけど、そろそろパラメータの量についていけなさそうな気配。
以下、変更内容(全部)。
diff -urN APC-3.0.14/CHANGELOG APC-3.0.15/CHANGELOG --- APC-3.0.14/CHANGELOG 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/CHANGELOG 2007-10-19 05:39:06.000000000 +0900 @@ -1,3 +1,14 @@ +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) diff -urN APC-3.0.14/INSTALL APC-3.0.15/INSTALL --- APC-3.0.14/INSTALL 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/INSTALL 2007-10-19 05:39:06.000000000 +0900 @@ -391,6 +391,23 @@ 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 This enables a lock-free local process shadow-cache which reduces lock contention when the cache is being written to. (Default: 0) diff -urN APC-3.0.14/TECHNOTES.txt APC-3.0.15/TECHNOTES.txt --- APC-3.0.14/TECHNOTES.txt 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/TECHNOTES.txt 2007-10-19 05:39:06.000000000 +0900 @@ -83,8 +83,12 @@ typedef struct block_t block_t; struct block_t { - int size; /* size of this block */ - int next; /* offset in segment of next free block */ + 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: diff -urN APC-3.0.14/apc.php APC-3.0.15/apc.php --- APC-3.0.14/apc.php 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc.php 2007-10-19 05:39:06.000000000 +0900 @@ -22,7 +22,7 @@ */ -$VERSION='$Id: apc.php,v 3.65 2006/10/27 18:32:52 shire Exp $'; +$VERSION='$Id: apc.php,v 3.68 2007/07/22 00:25:48 gopalv Exp $'; ////////// READ OPTIONAL CONFIGURATION FILE //////////// if (file_exists("apc.conf.php")) include("apc.conf.php"); @@ -59,7 +59,7 @@ // rewrite $PHP_SELF to block XSS attacks // -$PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],'')) : ''; +$PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],''), ENT_QUOTES) : ''; $time = time(); $host = getenv('HOSTNAME'); if($host) { $host = '('.$host.')'; } @@ -75,6 +75,7 @@ $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 @@ -85,7 +86,7 @@ 'SORT1' => '/^[AHSMCDTZ]$/', // first sort key 'SORT2' => '/^[DA]$/', // second sort key 'AGGR' => '/^\d+$/', // aggregation by dir level - 'SEARCH' => '/^.*$/' // aggregation by dir level + 'SEARCH' => '~^[a-zA-Z0-1/_.-]*$~' // aggregation by dir level ); // default cache mode @@ -114,7 +115,7 @@ foreach($vardom as $var => $dom) { if (!isset($_REQUEST[$var])) { $MYREQUEST[$var]=NULL; - } else if (!is_array($_REQUEST[$var]) && preg_match($dom,$_REQUEST[$var])) { + } else if (!is_array($_REQUEST[$var]) && preg_match($dom.'D',$_REQUEST[$var])) { $MYREQUEST[$var]=$_REQUEST[$var]; } else { $MYREQUEST[$var]=$_REQUEST[$var]=NULL; @@ -179,6 +180,10 @@ 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; @@ -929,7 +934,6 @@ $fieldheading='User Entry Label'; $fieldkey='info'; - // ----------------------------------------------- // System Cache Entries // ----------------------------------------------- @@ -1093,9 +1097,18 @@ else echo '<td class="td-n center">None</td>'; } - echo - '<td class="td-last center">',$entry['deletion_time'] ? date(DATE_FORMAT,$entry['deletion_time']) : '-','</td>', - '</tr>'; + if ($entry['deletion_time']) { + + echo '<td class="td-last center">', date(DATE_FORMAT,$entry['deletion_time']), '</td>'; + } else if ($MYREQUEST['OB'] == OB_USER_CACHE) { + + echo '<td class="td-last center">'; + echo '[<a href="', $MY_SELF, '&OB=', $MYREQUEST['OB'], '&DU=', urlencode($entry[$fieldkey]), '">Delete Now</a>]'; + echo '</td>'; + } else { + echo '<td class="td-last center"> </td>'; + } + echo '</tr>'; $i++; if ($i == $MYREQUEST['COUNT']) break; diff -urN APC-3.0.14/apc_cache.c APC-3.0.15/apc_cache.c --- APC-3.0.14/apc_cache.c 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_cache.c 2007-10-19 05:39:06.000000000 +0900 @@ -28,7 +28,7 @@ */ -/* $Id: apc_cache.c,v 3.140 2007/04/02 22:57:10 rasmus Exp $ */ +/* $Id: apc_cache.c,v 3.145 2007/10/05 23:06:56 gopalv Exp $ */ #include "apc_cache.h" #include "apc_lock.h" @@ -97,6 +97,7 @@ struct local_slot_t { slot_t *original; /* the original slot in shm */ int num_hits; /* number of hits */ + time_t creation_time; /* creation time */ apc_cache_entry_t *value; /* shallow copy of slot->value */ local_slot_t *next; /* only for dead list */ }; @@ -306,6 +307,9 @@ cache_size = sizeof(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 = (header_t*) cache->shmaddr; @@ -712,11 +716,10 @@ time_t t TSRMLS_DC) { - static char canon_path[MAXPATHLEN]; struct stat *tmp_buf=NULL; struct apc_fileinfo_t fileinfo = { {0}, }; int len; - + assert(key != NULL); if (!filename || !SG(request_info).path_translated) { @@ -734,12 +737,18 @@ key->mtime = t; key->type = APC_CACHE_KEY_FPFILE; } else { - if(!realpath(filename, canon_path)) { - fprintf(stderr, "realpath failed to canonicalize %s - bailing\n", filename); + 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 = canon_path; - key->data.fpfile.fullpath_len = strlen(canon_path); + + 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; } @@ -853,7 +862,6 @@ entry->type = APC_CACHE_ENTRY_FILE; entry->ref_count = 0; entry->mem_size = 0; - entry->autofiltered = 0; entry->local = 0; return entry; } @@ -995,7 +1003,6 @@ entry->type = APC_CACHE_ENTRY_USER; entry->ref_count = 0; entry->mem_size = 0; - entry->autofiltered = 0; entry->local = 0; return entry; } @@ -1171,7 +1178,7 @@ #endif /* {{{ make_local_slot */ -static local_slot_t* make_local_slot(apc_local_cache_t* cache, local_slot_t* lslot, slot_t* slot) +static local_slot_t* make_local_slot(apc_local_cache_t* cache, local_slot_t* lslot, slot_t* slot, time_t t) { apc_cache_entry_t* value; @@ -1181,7 +1188,8 @@ lslot->original = slot; lslot->value = value; - lslot->num_hits++; + lslot->num_hits = 0; + lslot->creation_time = t; return lslot; /* for what joy ? ... consistency */ } @@ -1233,10 +1241,11 @@ int i; for(i = 0; i < cache->num_slots; i++) { - slot_t * slot = cache->slots[i].original; - if((slot && slot->access_time < (t - cache->ttl)) || + lslot = &cache->slots[i]; + /* every slot lives for exactly TTL seconds */ + if((lslot->original && lslot->creation_time < (t - cache->ttl)) || cache->generation != cache->shmcache->header->expunges) { - free_local_slot(cache, &cache->slots[i]); + free_local_slot(cache, lslot); } } @@ -1292,9 +1301,15 @@ free_local_slot(cache, lslot); goto not_found; } + cache->num_hits++; + lslot->num_hits++; + lslot->original->access_time = t; /* unlocked write, but last write wins */ return lslot->value; } else if(key.type == APC_CACHE_KEY_FPFILE) { if(!memcmp(slot->key.data.fpfile.fullpath, key.data.fpfile.fullpath, key.data.fpfile.fullpath_len+1)) { + cache->num_hits++; + lslot->num_hits++; + lslot->original->access_time = t; /* unlocked write, but last write wins */ return lslot->value; } } @@ -1311,7 +1326,7 @@ /* i.e maintain a sort of top list */ if(lslot->original == NULL || (lslot->original->num_hits + lslot->num_hits) < slot->num_hits) { free_local_slot(cache, lslot); - make_local_slot(cache, lslot, slot); + make_local_slot(cache, lslot, slot, t); return lslot->value; } return slot->value; diff -urN APC-3.0.14/apc_cache.h APC-3.0.15/apc_cache.h --- APC-3.0.14/apc_cache.h 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_cache.h 2007-10-19 05:39:06.000000000 +0900 @@ -26,7 +26,7 @@ */ -/* $Id: apc_cache.h,v 3.45 2007/03/22 16:03:59 gopalv Exp $ */ +/* $Id: apc_cache.h,v 3.46 2007/10/05 23:06:56 gopalv Exp $ */ #ifndef APC_CACHE_H #define APC_CACHE_H @@ -93,7 +93,6 @@ struct apc_cache_entry_t { apc_cache_entry_value_t data; unsigned char type; - unsigned char autofiltered; unsigned char local; int ref_count; size_t mem_size; diff -urN APC-3.0.14/apc_compile.c APC-3.0.15/apc_compile.c --- APC-3.0.14/apc_compile.c 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_compile.c 2007-10-19 05:39:06.000000000 +0900 @@ -28,7 +28,7 @@ */ -/* $Id: apc_compile.c,v 3.85 2007/03/28 07:35:55 gopalv Exp $ */ +/* $Id: apc_compile.c,v 3.87 2007/08/25 13:09:13 gopalv Exp $ */ #include "apc_compile.h" #include "apc_globals.h" @@ -1266,11 +1266,10 @@ 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),len)) { + 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((IS_ABSOLUTE_PATH(fileinfo.fullpath, strlen(fileinfo.fullpath)) && (fullpath = fileinfo.fullpath)) - || (fullpath = realpath(fileinfo.fullpath, canon_path))) { - /* is either an absolute path or it goes through a realpath() */ + 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); diff -urN APC-3.0.14/apc_globals.h APC-3.0.15/apc_globals.h --- APC-3.0.14/apc_globals.h 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_globals.h 2007-10-19 05:39:06.000000000 +0900 @@ -29,12 +29,12 @@ */ -/* $Id: apc_globals.h,v 3.59 2007/03/21 21:07:28 rasmus Exp $ */ +/* $Id: apc_globals.h,v 3.66 2007/10/18 20:35:10 rasmus Exp $ */ #ifndef APC_GLOBALS_H #define APC_GLOBALS_H -#define APC_VERSION "3.0.14" +#define APC_VERSION "3.0.15" #include "apc_cache.h" #include "apc_stack.h" @@ -74,6 +74,9 @@ 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 @@ -82,6 +85,8 @@ zend_bool localcache; /* enable local cache */ long localcache_size; /* size of fast cache */ apc_local_cache_t* lcache; /* unlocked local cache */ + zend_bool force_file_update; /* force files to be updated during apc_compile_file */ + char canon_path[MAXPATHLEN]; /* canonical path for key data */ ZEND_END_MODULE_GLOBALS(apc) /* (the following declaration is defined in php_apc.c) */ diff -urN APC-3.0.14/apc_main.c APC-3.0.15/apc_main.c --- APC-3.0.14/apc_main.c 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_main.c 2007-10-19 05:39:06.000000000 +0900 @@ -28,7 +28,7 @@ */ -/* $Id: apc_main.c,v 3.97 2007/03/22 16:03:59 gopalv Exp $ */ +/* $Id: apc_main.c,v 3.102 2007/10/05 23:06:56 gopalv Exp $ */ #include "apc_php.h" #include "apc_main.h" @@ -258,7 +258,6 @@ default_compile: - cache_entry->autofiltered = 1; if(APCG(report_autofilter)) { apc_wprint("Autofiltering %s", h->opened_path); } @@ -270,14 +269,16 @@ } 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); /* XXX: kludge */ h->type = ZEND_HANDLE_FILENAME; - - return old_compile_file(h, type TSRMLS_CC); + + return NULL; } /* }}} */ @@ -311,7 +312,7 @@ return old_compile_file(h, type TSRMLS_CC); } -#if PHP_API_VERSION <= 20041225 +#if PHP_API_VERSION < 20041225 #if HAVE_APACHE && defined(APC_PHP4_STAT) t = ((request_rec *)SG(server_context))->request_time; #else @@ -330,15 +331,20 @@ return old_compile_file(h, type TSRMLS_CC); } - if(APCG(localcache)) { - /* search for the file in the local cache */ - cache_entry = apc_local_cache_find(APCG(lcache), key, t); + + if(!APCG(force_file_update)) { + if(APCG(localcache)) { + /* search for the file in the local cache */ + cache_entry = apc_local_cache_find(APCG(lcache), key, t); + } else { + /* search for the file in the cache */ + cache_entry = apc_cache_find(apc_cache, key, t); + } } else { - /* search for the file in the cache */ - cache_entry = apc_cache_find(apc_cache, key, t); + cache_entry = NULL; } - if (cache_entry != NULL && !cache_entry->autofiltered) { + if (cache_entry != NULL) { int dummy = 1; if (h->opened_path == NULL) { h->opened_path = estrdup(cache_entry->data.file.filename); @@ -346,27 +352,14 @@ 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); /* XXX kludge */ apc_stack_push(APCG(cache_stack), cache_entry); - return cached_compile(h, type TSRMLS_CC); - } - else if(cache_entry != NULL && cache_entry->autofiltered) { - /* nobody else is using this cache_entry */ - if(cache_entry->ref_count == 1) { - if(cache_entry->data.file.op_array) { - apc_free_op_array(cache_entry->data.file.op_array, apc_sma_free); - cache_entry->data.file.op_array = NULL; - } - if(cache_entry->data.file.functions) { - apc_free_functions(cache_entry->data.file.functions, apc_sma_free); - cache_entry->data.file.functions = NULL; - } - if(cache_entry->data.file.classes) { - apc_free_classes(cache_entry->data.file.classes, apc_sma_free); - cache_entry->data.file.classes = NULL; - } + op_array = cached_compile(h, type TSRMLS_CC); + if(op_array) { + return op_array; } - /* We never push this into the cache_stack, so we have to do a release */ - apc_cache_release(apc_cache, cache_entry); - return old_compile_file(h, type TSRMLS_CC); + if(APCG(report_autofilter)) { + apc_wprint("Recompiling %s", h->opened_path); + } + /* TODO: check what happens with EG(included_files) */ } if(apc_cache_busy(apc_cache) && APCG(localcache)) { @@ -402,6 +395,26 @@ } } + /* 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 = *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.st_mtime; + } + HANDLE_BLOCK_INTERRUPTIONS(); #if NONBLOCKING_LOCK_AVAILABLE @@ -629,14 +642,6 @@ 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++) { #ifdef ZEND_ENGINE_2 diff -urN APC-3.0.14/apc_mmap.c APC-3.0.15/apc_mmap.c --- APC-3.0.14/apc_mmap.c 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_mmap.c 2007-10-19 05:39:06.000000000 +0900 @@ -25,7 +25,7 @@ */ -/* $Id: apc_mmap.c,v 3.5 2006/03/12 00:31:45 rasmus Exp $ */ +/* $Id: apc_mmap.c,v 3.6 2007/05/09 22:15:33 shire Exp $ */ #include "apc.h" @@ -46,7 +46,7 @@ #define MAP_NOSYNC 0 #endif -void *apc_mmap(char *file_mask, int size) +void *apc_mmap(char *file_mask, size_t size) { void* shmaddr; /* the shared memory address */ @@ -120,7 +120,7 @@ return shmaddr; } -void apc_unmap(void* shmaddr, int size) +void apc_unmap(void* shmaddr, size_t size) { munmap(shmaddr, size); } diff -urN APC-3.0.14/apc_rfc1867.c APC-3.0.15/apc_rfc1867.c --- APC-3.0.14/apc_rfc1867.c 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_rfc1867.c 2007-10-19 05:39:06.000000000 +0900 @@ -25,11 +25,16 @@ */ -/* $Id: apc_rfc1867.c,v 3.4 2007/02/24 11:45:29 rasmus Exp $*/ +/* $Id: apc_rfc1867.c,v 3.12 2007/10/18 20:37:20 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); @@ -37,7 +42,7 @@ struct timeval a; double t; gettimeofday(&a, NULL); - t = a.tv_sec + (a.tv_usec/1000000); + t = a.tv_sec + (a.tv_usec/1000000.00); return t; } @@ -51,6 +56,8 @@ 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; @@ -68,17 +75,21 @@ 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,"apc_upload_progress",19) && data->value && data->length && data->length < 58) { - strlcat(tracking_key, "upload_", 63); + 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+7; + key_length = data->length + prefix_len; bytes_processed = data->post_bytes_processed; } } @@ -99,6 +110,7 @@ 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); } @@ -115,7 +127,11 @@ add_assoc_string(track, "filename", filename, 1); add_assoc_string(track, "name", name, 1); add_assoc_long(track, "done", 0); - _apc_store(tracking_key, key_length, track, 3600, 0 TSRMLS_CC); + 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; @@ -135,6 +151,7 @@ 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); } @@ -154,9 +171,12 @@ add_assoc_double(track, "rate", rate); add_assoc_string(track, "filename", filename, 1); add_assoc_string(track, "name", name, 1); - add_assoc_string(track, "temp_filename", temp_filename, 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); } diff -urN APC-3.0.14/apc_shm.c APC-3.0.15/apc_shm.c --- APC-3.0.14/apc_shm.c 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_shm.c 2007-10-19 05:39:06.000000000 +0900 @@ -26,11 +26,10 @@ */ -/* $Id: apc_shm.c,v 3.10 2006/05/31 22:24:48 rasmus Exp $ */ +/* $Id: apc_shm.c,v 3.11 2007/05/09 22:15:33 shire Exp $ */ #include "apc_shm.h" #include "apc.h" -#include <sys/types.h> #ifdef PHP_WIN32 /* shm functions are available in TSRM */ #include <tsrm/tsrm_win32.h> @@ -48,7 +47,7 @@ # define SHM_A 0222 /* write permission */ #endif -int apc_shm_create(const char* pathname, int proj, int size) +int apc_shm_create(const char* pathname, int proj, size_t size) { int shmid; /* shared memory id */ int oflag; /* permissions on shm */ diff -urN APC-3.0.14/apc_shm.h APC-3.0.15/apc_shm.h --- APC-3.0.14/apc_shm.h 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_shm.h 2007-10-19 05:39:06.000000000 +0900 @@ -25,14 +25,19 @@ */ -/* $Id: apc_shm.h,v 3.6 2006/03/12 00:31:45 rasmus Exp $ */ +/* $Id: apc_shm.h,v 3.8 2007/05/23 01:23:21 auroraeosrose Exp $ */ #ifndef APC_SHM_H #define APC_SHM_H +#include <sys/types.h> +#ifdef PHP_WIN32 +#include <time.h> +#endif + /* Wrapper functions for unix shared memory */ -extern int apc_shm_create(const char* name, int proj, int size); +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); diff -urN APC-3.0.14/apc_sma.c APC-3.0.15/apc_sma.c --- APC-3.0.14/apc_sma.c 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_sma.c 2007-10-19 05:39:06.000000000 +0900 @@ -26,7 +26,7 @@ */ -/* $Id: apc_sma.c,v 1.63 2007/04/02 09:02:57 gopalv Exp $ */ +/* $Id: apc_sma.c,v 1.67 2007/08/03 20:53:57 gopalv Exp $ */ #include "apc_sma.h" #include "apc.h" @@ -35,8 +35,8 @@ #include "apc_shm.h" #include <limits.h> #if APC_MMAP -void *apc_mmap(char *file_mask, int size); -void apc_unmap(void* shmaddr, int size); +void *apc_mmap(char *file_mask, size_t size); +void apc_unmap(void* shmaddr, size_t size); #endif /* {{{ locking macros */ @@ -151,7 +151,7 @@ if(header->nfoffset) { prv = BLOCKAT(header->nfoffset); } else { - prv = BLOCKAT(sizeof(header_t)); + prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); } CHECK_CANARY(prv); @@ -172,7 +172,7 @@ /* Check to see if we need to wrap around and search from the top */ if(header->nfoffset && prv->next == 0) { - prv = BLOCKAT(sizeof(header_t)); + prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); #ifdef __APC_SMA_DEBUG__ CHECK_CANARY(prv); #endif @@ -247,7 +247,7 @@ /* find position of new block in free list */ cur = BLOCKAT(offset); - prv = BLOCKAT(sizeof(header_t)); + prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); CHECK_CANARY(cur); @@ -306,7 +306,7 @@ /* {{{ apc_sma_init */ -void apc_sma_init(int numseg, int segsize, char *mmap_file_mask) +void apc_sma_init(int numseg, size_t segsize, char *mmap_file_mask) { int i; @@ -354,8 +354,7 @@ header = (header_t*) shmaddr; apc_lck_create(NULL, 0, 1, header->sma_lock); header->segsize = sma_segsize; - header->avail = sma_segsize - sizeof(header_t) - sizeof(block_t) - - ALIGNWORD(sizeof(int)); + header->avail = sma_segsize - ALIGNWORD(sizeof(header_t)) - ALIGNWORD(sizeof(block_t)); header->nfoffset = 0; #if ALLOC_DISTRIBUTION { @@ -363,9 +362,9 @@ for(j=0; j<30; j++) header->adist[j] = 0; } #endif - block = BLOCKAT(sizeof(header_t)); + block = BLOCKAT(ALIGNWORD(sizeof(header_t))); block->size = 0; - block->next = sizeof(header_t) + sizeof(block_t); + block->next = ALIGNWORD(sizeof(header_t)) + ALIGNWORD(sizeof(block_t)); SET_CANARY(block); #ifdef __APC_SMA_DEBUG__ block->id = -1; @@ -422,10 +421,10 @@ UNLOCK(((header_t*)sma_shmaddrs[sma_lastseg])->sma_lock); for (i = 0; i < sma_numseg; i++) { - LOCK(((header_t*)sma_shmaddrs[i])->sma_lock); 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); @@ -510,7 +509,7 @@ info = (apc_sma_info_t*) apc_emalloc(sizeof(apc_sma_info_t)); info->num_seg = sma_numseg; - info->seg_size = sma_segsize - sizeof(header_t) - sizeof(block_t) - ALIGNWORD(sizeof(int)); + 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++) { @@ -523,7 +522,7 @@ for (i = 0; i < sma_numseg; i++) { RDLOCK(((header_t*)sma_shmaddrs[i])->sma_lock); shmaddr = sma_shmaddrs[i]; - prv = BLOCKAT(sizeof(header_t)); + prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); link = &info->list[i]; @@ -568,9 +567,9 @@ /* }}} */ /* {{{ apc_sma_get_avail_mem */ -int apc_sma_get_avail_mem() +size_t apc_sma_get_avail_mem() { - int avail_mem = 0; + size_t avail_mem = 0; int i; for (i = 0; i < sma_numseg; i++) { @@ -598,7 +597,7 @@ for (i = 0; i < sma_numseg; i++) { char* shmaddr = sma_shmaddrs[i]; header_t* header = (header_t*) shmaddr; - block_t* prv = BLOCKAT(sizeof(header_t)); + block_t* prv = BLOCKAT(ALIGNWORD(sizeof(header_t))); int avail = 0; /* For each block in this segment */ diff -urN APC-3.0.14/apc_sma.h APC-3.0.15/apc_sma.h --- APC-3.0.14/apc_sma.h 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/apc_sma.h 2007-10-19 05:39:06.000000000 +0900 @@ -25,7 +25,7 @@ */ -/* $Id: apc_sma.h,v 1.16 2007/02/24 11:59:40 rasmus Exp $ */ +/* $Id: apc_sma.h,v 1.18 2007/05/11 01:46:31 shire Exp $ */ #ifndef APC_SMA_H #define APC_SMA_H @@ -36,7 +36,7 @@ /* Simple shared memory allocator */ -extern void apc_sma_init(int numseg, int segsize, char *mmap_file_mask); +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); @@ -49,8 +49,8 @@ /* {{{ struct definition: apc_sma_link_t */ typedef struct apc_sma_link_t apc_sma_link_t; struct apc_sma_link_t { - int size; /* size of this free block */ - int offset; /* offset in segment of this block */ + 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 */ }; /* }}} */ @@ -59,7 +59,7 @@ typedef struct apc_sma_info_t apc_sma_info_t; struct apc_sma_info_t { int num_seg; /* number of shared memory segments */ - int seg_size; /* size of each shared memory segment */ + long seg_size; /* size of each shared memory segment */ apc_sma_link_t** list; /* there is one list per segment */ }; /* }}} */ @@ -67,7 +67,7 @@ extern apc_sma_info_t* apc_sma_info(zend_bool limited); extern void apc_sma_free_info(apc_sma_info_t* info); -extern int apc_sma_get_avail_mem(); +extern size_t apc_sma_get_avail_mem(); extern void apc_sma_check_integrity(); #endif diff -urN APC-3.0.14/arch/atomic.h APC-3.0.15/arch/atomic.h --- APC-3.0.14/arch/atomic.h 1970-01-01 09:00:00.000000000 +0900 +++ APC-3.0.15/arch/atomic.h 2007-10-19 05:39:06.000000000 +0900 @@ -0,0 +1,38 @@ +/* + +----------------------------------------------------------------------+ + | 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 <shire@php.net> | + +----------------------------------------------------------------------+ + + */ + +/* $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 -urN APC-3.0.14/arch/i386/atomic.h APC-3.0.15/arch/i386/atomic.h --- APC-3.0.14/arch/i386/atomic.h 1970-01-01 09:00:00.000000000 +0900 +++ APC-3.0.15/arch/i386/atomic.h 2007-10-19 05:39:06.000000000 +0900 @@ -0,0 +1,79 @@ +/* + +----------------------------------------------------------------------+ + | 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 <shire@php.net> | + +----------------------------------------------------------------------+ + + */ + +/* $Id: atomic.h,v 1.1 2006/09/29 07:13:01 shire Exp $ */ + + +#include <sys/syscall.h> +#include <sys/time.h> +#include <linux/futex.h> + +/* 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 -urN APC-3.0.14/arch/x86_64/atomic.h APC-3.0.15/arch/x86_64/atomic.h --- APC-3.0.14/arch/x86_64/atomic.h 1970-01-01 09:00:00.000000000 +0900 +++ APC-3.0.15/arch/x86_64/atomic.h 2007-10-19 05:39:06.000000000 +0900 @@ -0,0 +1,80 @@ +/* + +----------------------------------------------------------------------+ + | 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 <shire@php.net> | + +----------------------------------------------------------------------+ + + */ + +/* $Id: atomic.h,v 1.1 2006/09/29 07:13:01 shire Exp $ */ + + +#include <sys/syscall.h> +#include <sys/time.h> +#include <linux/futex.h> + +/* 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 -urN APC-3.0.14/php_apc.c APC-3.0.15/php_apc.c --- APC-3.0.14/php_apc.c 2007-04-03 08:05:30.000000000 +0900 +++ APC-3.0.15/php_apc.c 2007-10-19 05:39:06.000000000 +0900 @@ -26,7 +26,7 @@ */ -/* $Id: php_apc.c,v 3.140 2007/03/28 07:14:54 gopalv Exp $ */ +/* $Id: php_apc.c,v 3.151 2007/09/18 21:35:46 shire Exp $ */ #include "apc_zend.h" #include "apc_cache.h" @@ -92,6 +92,7 @@ apc_globals->localcache = 0; apc_globals->localcache_size = 0; apc_globals->lcache = NULL; + apc_globals->force_file_update = 0; } static void php_apc_shutdown_globals(zend_apc_globals* apc_globals TSRMLS_DC) @@ -139,6 +140,28 @@ } /* }}} */ +#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 @@ -169,6 +192,9 @@ 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.localcache", "0", PHP_INI_SYSTEM, OnUpdateBool, localcache, zend_apc_globals, apc_globals) STD_PHP_INI_ENTRY("apc.localcache.size", "512", PHP_INI_SYSTEM, OnUpdateInt, localcache_size, zend_apc_globals, apc_globals) @@ -199,7 +225,7 @@ #else php_info_print_table_row(2, "Locking type", "File Locks"); #endif - php_info_print_table_row(2, "Revision", "$Revision: 3.140 $"); + php_info_print_table_row(2, "Revision", "$Revision: 3.151 $"); php_info_print_table_row(2, "Build Date", __DATE__ " " __TIME__); php_info_print_table_end(); DISPLAY_INI_ENTRIES(); @@ -503,7 +529,7 @@ time_t t; size_t mem_size = 0; -#if PHP_API_VERSION <= 20041225 +#if PHP_API_VERSION < 20041225 #if HAVE_APACHE && defined(APC_PHP4_STAT) t = ((request_rec *)SG(server_context))->request_time; #else @@ -638,7 +664,7 @@ return; } -#if PHP_API_VERSION <= 20041225 +#if PHP_API_VERSION < 20041225 #if HAVE_APACHE && defined(APC_PHP4_STAT) t = ((request_rec *)SG(server_context))->request_time; #else @@ -795,7 +821,7 @@ if(!strkey_len) RETURN_FALSE; -#if PHP_API_VERSION <= 20041225 +#if PHP_API_VERSION < 20041225 #if HAVE_APACHE && defined(APC_PHP4_STAT) t = ((request_rec *)SG(server_context))->request_time; #else @@ -863,12 +889,11 @@ 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; - zend_hash_init_ex(&eg_function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0); eg_orig_function_table = EG(function_table); - EG(function_table) = &eg_function_table; - zend_hash_init_ex(&eg_class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0); + EG(function_table) = CG(function_table); eg_orig_class_table = EG(class_table); - EG(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; @@ -878,19 +903,18 @@ zend_try { op_array = zend_compile_file(&file_handle, ZEND_INCLUDE TSRMLS_CC); } zend_catch { - apc_eprint("Error compiling %s in apc_compile_file.", filename); + 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; - zend_hash_destroy(&eg_function_table); EG(class_table) = eg_orig_class_table; - zend_hash_destroy(&eg_class_table); /* Restore global settings */ APCG(slam_defense) = slam_defense; @@ -923,6 +947,7 @@ 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} }; /* }}} */