From: Dmitry Stogov Date: Wed, 6 Mar 2013 05:41:59 +0000 (+0400) Subject: Allows exclusion of large files from being cached X-Git-Tag: php-5.5.0beta1~42^2~12 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=08bfdc75a4c6656192706cd153fc28ab89a821bc;p=php Allows exclusion of large files from being cached --- diff --git a/README b/README index b44386e87a..c0304a73ab 100644 --- a/README +++ b/README @@ -159,6 +159,10 @@ zend_optimizerplus.blacklist_filename compile time evaluation. 3) Code that triggers an Optimizer+ bug. +zend_optimizerplus.max_file_size (default "0") + Allows exclusion of large files from being cached. By default all files + are cached. + zend_optimizerplus.consistency_checks (default "0") Check the cache checksum each N requests. The default value of "0" means that the checks are disabled. diff --git a/ZendAccelerator.c b/ZendAccelerator.c index 06469f5c02..ed94226560 100644 --- a/ZendAccelerator.c +++ b/ZendAccelerator.c @@ -654,7 +654,7 @@ static int zend_get_stream_timestamp(const char *filename, struct stat *statbuf } #if ZEND_WIN32 -static accel_time_t zend_get_file_handle_timestamp_win(zend_file_handle *file_handle) +static accel_time_t zend_get_file_handle_timestamp_win(zend_file_handle *file_handle, size_t *size) { static unsigned __int64 utc_base = 0; static FILETIME utc_base_ft; @@ -689,13 +689,16 @@ static accel_time_t zend_get_file_handle_timestamp_win(zend_file_handle *file_ha ftime = (((unsigned __int64)fdata.ftLastWriteTime.dwHighDateTime) << 32) + fdata.ftLastWriteTime.dwLowDateTime - utc_base; ftime /= 10000000L; + if (size) { + *size = (size_t)(((unsigned __int64)fdata.nFileSizeHigh) << 32 + (unsigned __int64)fdata.nFileSizeLow); + } return (accel_time_t)ftime; } return 0; } #endif -static accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle TSRMLS_DC) +static accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_t *size TSRMLS_DC) { struct stat statbuf; #ifdef ZEND_WIN32 @@ -709,12 +712,15 @@ static accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle struct stat *tmpbuf = sapi_module.get_stat(TSRMLS_C); if (tmpbuf) { + if (size) { + *size = tmpbuf->st_size; + } return tmpbuf->st_mtime; } } #ifdef ZEND_WIN32 - res = zend_get_file_handle_timestamp_win(file_handle); + res = zend_get_file_handle_timestamp_win(file_handle, size); if (res) { return res; } @@ -788,6 +794,9 @@ static accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle return 0; } + if (size) { + *size = statbuf.st_size; + } return statbuf.st_mtime; } @@ -820,7 +829,7 @@ static inline int do_validate_timestamps(zend_persistent_script *persistent_scri return FAILURE; } - if (zend_get_file_handle_timestamp(file_handle TSRMLS_CC) == persistent_script->timestamp) { + if (zend_get_file_handle_timestamp(file_handle, NULL TSRMLS_CC) == persistent_script->timestamp) { if (full_path_ptr) { file_handle->opened_path = NULL; } @@ -834,7 +843,7 @@ static inline int do_validate_timestamps(zend_persistent_script *persistent_scri ps_handle.filename = persistent_script->full_path; ps_handle.opened_path = persistent_script->full_path; - if (zend_get_file_handle_timestamp(&ps_handle TSRMLS_CC) == persistent_script->timestamp) { + if (zend_get_file_handle_timestamp(&ps_handle, NULL TSRMLS_CC) == persistent_script->timestamp) { return SUCCESS; } @@ -1178,6 +1187,7 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han zval *orig_user_error_handler; zend_op_array *op_array; int do_bailout = 0; + accel_time_t timestamp = 0; #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO zend_uint orig_compiler_options = 0; #endif @@ -1211,7 +1221,7 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO if (file_handle->type == ZEND_HANDLE_STREAM) { char *buf; - size_t size, offset = 0; + size_t size; /* Stream callbacks needs to be called in context of original * function and class tables (see: https://bugs.php.net/bug.php?id=64353) @@ -1223,6 +1233,29 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han } #endif + if (ZCG(accel_directives).validate_timestamps || ZCG(accel_directives).max_file_size > 0) { + size_t size = 0; + + /* Obtain the file timestamps, *before* actually compiling them, + * otherwise we have a race-condition. + */ + timestamp = zend_get_file_handle_timestamp(file_handle, ZCG(accel_directives).max_file_size > 0 ? &size : NULL TSRMLS_CC); + + /* If we can't obtain a timestamp (that means file is possibly socket) + * we won't cache it + */ + if (timestamp == 0) { + *op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC); + return NULL; + } + + if (ZCG(accel_directives).max_file_size > 0 && size > (size_t)ZCG(accel_directives).max_file_size) { + ZCSG(blacklist_misses)++; + *op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC); + return NULL; + } + } + new_persistent_script = create_persistent_script(); /* Save the original values for the op_array, function table and class table */ @@ -1295,14 +1328,7 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han /* Obtain the file timestamps, *before* actually compiling them, * otherwise we have a race-condition. */ - new_persistent_script->timestamp = zend_get_file_handle_timestamp(file_handle TSRMLS_CC); - - /* If we can't obtain a timestamp (that means file is possibly socket) - * we return it but do not persist it - */ - if (new_persistent_script->timestamp == 0) { - return new_persistent_script; - } + new_persistent_script->timestamp = timestamp; new_persistent_script->dynamic_members.revalidate = ZCSG(revalidate_at); } diff --git a/ZendAccelerator.h b/ZendAccelerator.h index 268d86faaa..310605b878 100644 --- a/ZendAccelerator.h +++ b/ZendAccelerator.h @@ -219,6 +219,7 @@ typedef struct _zend_accel_directives { long log_verbosity_level; long optimization_level; + long max_file_size; #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO long interned_strings_buffer; #endif diff --git a/zend_accelerator_module.c b/zend_accelerator_module.c index 1bf16e5035..5f7c32b594 100644 --- a/zend_accelerator_module.c +++ b/zend_accelerator_module.c @@ -218,6 +218,7 @@ ZEND_INI_BEGIN() STD_PHP_INI_ENTRY("zend_optimizerplus.revalidate_freq" , "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.revalidate_freq, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("zend_optimizerplus.preferred_memory_model", "" , PHP_INI_SYSTEM, OnUpdateStringUnempty, accel_directives.memory_model, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("zend_optimizerplus.blacklist_filename" , "" , PHP_INI_SYSTEM, OnUpdateAccelBlacklist, accel_directives.user_blacklist_filename, zend_accel_globals, accel_globals) + STD_PHP_INI_ENTRY("zend_optimizerplus.max_file_size" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.max_file_size, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("zend_optimizerplus.protect_memory" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.protect_memory, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("zend_optimizerplus.save_comments" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.save_comments, zend_accel_globals, accel_globals) @@ -554,6 +555,7 @@ static ZEND_FUNCTION(accelerator_get_configuration) add_assoc_long(directives, "zend_optimizerplus.revalidate_freq", ZCG(accel_directives).revalidate_freq); add_assoc_string(directives, "zend_optimizerplus.preferred_memory_model", STRING_NOT_NULL(ZCG(accel_directives).memory_model), 1); add_assoc_string(directives, "zend_optimizerplus.blacklist_filename", STRING_NOT_NULL(ZCG(accel_directives).user_blacklist_filename), 1); + add_assoc_long(directives, "zend_optimizerplus.max_file_size", ZCG(accel_directives).max_file_size); add_assoc_string(directives, "zend_optimizerplus.error_log", STRING_NOT_NULL(ZCG(accel_directives).error_log), 1); add_assoc_bool(directives, "zend_optimizerplus.protect_memory", ZCG(accel_directives).protect_memory);