summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/opcache/ZendAccelerator.c15
-rw-r--r--ext/opcache/ZendAccelerator.h9
-rw-r--r--ext/opcache/shared_alloc_win32.c26
-rw-r--r--ext/opcache/zend_accelerator_module.c9
-rw-r--r--ext/opcache/zend_shared_alloc.c10
-rw-r--r--ext/opcache/zend_shared_alloc.h1
6 files changed, 68 insertions, 2 deletions
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 862a85389f..e6d7005a8b 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -108,6 +108,9 @@ zend_accel_shared_globals *accel_shared_globals = NULL;
zend_bool accel_startup_ok = 0;
static char *zps_failure_reason = NULL;
char *zps_api_failure_reason = NULL;
+#if ENABLE_FILE_CACHE_FALLBACK
+zend_bool fallback_process = 0; /* process uses file cache fallback */
+#endif
static zend_op_array *(*accelerator_orig_compile_file)(zend_file_handle *file_handle, int type);
static int (*accelerator_orig_zend_stream_open_function)(const char *filename, zend_file_handle *handle );
@@ -2655,6 +2658,15 @@ static int accel_startup(zend_extension *extension)
zend_accel_error(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - can not reattach to exiting shared memory.");
return SUCCESS;
break;
+#if ENABLE_FILE_CACHE_FALLBACK
+ case ALLOC_FALLBACK:
+ zend_shared_alloc_lock();
+ fallback_process = 1;
+ zend_accel_init_auto_globals();
+ zend_shared_alloc_unlock();
+ goto file_cache_fallback;
+ break;
+#endif
}
/* from this point further, shared memory is supposed to be OK */
@@ -2682,6 +2694,9 @@ static int accel_startup(zend_extension *extension)
zend_accel_init_auto_globals();
#endif
}
+#if ENABLE_FILE_CACHE_FALLBACK
+file_cache_fallback:
+#endif
/* Override compiler */
accelerator_orig_compile_file = zend_compile_file;
diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h
index 93344ec0f5..798b2d7365 100644
--- a/ext/opcache/ZendAccelerator.h
+++ b/ext/opcache/ZendAccelerator.h
@@ -139,6 +139,9 @@ extern int lock_file;
#define DO_ALLOCA(x) do_alloca(x, use_heap)
#define FREE_ALLOCA(x) free_alloca(x, use_heap)
+#if defined(HAVE_OPCACHE_FILE_CACHE) && defined(ZEND_WIN32)
+# define ENABLE_FILE_CACHE_FALLBACK 1
+#endif
#if ZEND_WIN32
typedef unsigned __int64 accel_time_t;
@@ -219,6 +222,9 @@ typedef struct _zend_accel_directives {
zend_bool file_cache_only;
zend_bool file_cache_consistency_checks;
#endif
+#if ENABLE_FILE_CACHE_FALLBACK
+ zend_bool file_cache_fallback;
+#endif
#ifdef HAVE_HUGE_CODE_PAGES
zend_bool huge_code_pages;
#endif
@@ -293,6 +299,9 @@ typedef struct _zend_accel_shared_globals {
} zend_accel_shared_globals;
extern zend_bool accel_startup_ok;
+#if ENABLE_FILE_CACHE_FALLBACK
+extern zend_bool fallback_process;
+#endif
extern zend_accel_shared_globals *accel_shared_globals;
#define ZCSG(element) (accel_shared_globals->element)
diff --git a/ext/opcache/shared_alloc_win32.c b/ext/opcache/shared_alloc_win32.c
index 2a86e6b814..ce4bacf348 100644
--- a/ext/opcache/shared_alloc_win32.c
+++ b/ext/opcache/shared_alloc_win32.c
@@ -146,11 +146,35 @@ static int zend_shared_alloc_reattach(size_t requested_size, char **error_in)
return ALLOC_FAILURE;
}
fclose(fp);
-
/* Check if the requested address space is free */
if (VirtualQuery(wanted_mapping_base, &info, sizeof(info)) == 0 ||
info.State != MEM_FREE ||
info.RegionSize < requested_size) {
+#if ENABLE_FILE_CACHE_FALLBACK
+ if (ZCG(accel_directives).file_cache && ZCG(accel_directives).file_cache_fallback) {
+ size_t pre_size, wanted_mb_save;
+
+ wanted_mb_save = (size_t)wanted_mapping_base;
+
+ err = ERROR_INVALID_ADDRESS;
+ zend_win_error_message(ACCEL_LOG_WARNING, "Base address marks unusable memory region (fall-back to file cache)", err);
+
+ pre_size = ZEND_ALIGNED_SIZE(sizeof(zend_smm_shared_globals)) + ZEND_ALIGNED_SIZE(sizeof(zend_shared_segment)) + ZEND_ALIGNED_SIZE(sizeof(void *)) + ZEND_ALIGNED_SIZE(sizeof(int));
+ /* Map only part of SHM to have access opcache shared globals */
+ mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, pre_size + ZEND_ALIGNED_SIZE(sizeof(zend_accel_shared_globals)), NULL);
+ if (mapping_base == NULL) {
+ err = GetLastError();
+ zend_win_error_message(ACCEL_LOG_FATAL, "Unable to reattach to opcache shared globals", err);
+ return ALLOC_FAILURE;
+ }
+ accel_shared_globals = (zend_accel_shared_globals *)((char *)((zend_smm_shared_globals *)mapping_base)->app_shared_globals + ((char *)mapping_base - (char *)wanted_mb_save));
+
+ /* Make this process to use file-cache only */
+ ZCG(accel_directives).file_cache_only = 1;
+
+ return ALLOC_FALLBACK;
+ }
+#endif
err = ERROR_INVALID_ADDRESS;
zend_win_error_message(ACCEL_LOG_FATAL, "Base address marks unusable memory region", err);
return ALLOC_FAILURE;
diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c
index 11d631c538..bd53f6e373 100644
--- a/ext/opcache/zend_accelerator_module.c
+++ b/ext/opcache/zend_accelerator_module.c
@@ -309,6 +309,9 @@ ZEND_INI_BEGIN()
STD_PHP_INI_ENTRY("opcache.file_cache_only" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_only, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.file_cache_consistency_checks" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_consistency_checks, zend_accel_globals, accel_globals)
#endif
+#if ENABLE_FILE_CACHE_FALLBACK
+ STD_PHP_INI_ENTRY("opcache.file_cache_fallback" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_fallback, zend_accel_globals, accel_globals)
+#endif
#ifdef HAVE_HUGE_CODE_PAGES
STD_PHP_INI_BOOLEAN("opcache.huge_code_pages" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.huge_code_pages, zend_accel_globals, accel_globals)
#endif
@@ -733,7 +736,11 @@ static ZEND_FUNCTION(opcache_reset)
RETURN_FALSE;
}
- if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled)) {
+ if ((!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled))
+#if ENABLE_FILE_CACHE_FALLBACK
+ && !fallback_process
+#endif
+ ) {
RETURN_FALSE;
}
diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c
index 09da83a6a6..1ad3fd2e28 100644
--- a/ext/opcache/zend_shared_alloc.c
+++ b/ext/opcache/zend_shared_alloc.c
@@ -187,6 +187,11 @@ int zend_shared_alloc_startup(size_t requested_size)
smm_shared_globals = NULL;
return res;
}
+#if ENABLE_FILE_CACHE_FALLBACK
+ if (ALLOC_FALLBACK == res) {
+ return ALLOC_FALLBACK;
+ }
+#endif
if (!g_shared_alloc_handler) {
/* try memory handlers in order */
@@ -207,6 +212,11 @@ int zend_shared_alloc_startup(size_t requested_size)
if (res == SUCCESSFULLY_REATTACHED) {
return res;
}
+#if ENABLE_FILE_CACHE_FALLBACK
+ if (ALLOC_FALLBACK == res) {
+ return ALLOC_FALLBACK;
+ }
+#endif
shared_segments_array_size = ZSMMG(shared_segments_count) * S_H(segment_type_size)();
diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h
index 398b64f432..ec67343e89 100644
--- a/ext/opcache/zend_shared_alloc.h
+++ b/ext/opcache/zend_shared_alloc.h
@@ -68,6 +68,7 @@
#define FAILED_REATTACHED 2
#define SUCCESSFULLY_REATTACHED 4
#define ALLOC_FAIL_MAPPING 8
+#define ALLOC_FALLBACK 9
typedef struct _zend_shared_segment {
size_t size;