diff options
Diffstat (limited to 'ext/opcache/shared_alloc_win32.c')
-rw-r--r-- | ext/opcache/shared_alloc_win32.c | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/ext/opcache/shared_alloc_win32.c b/ext/opcache/shared_alloc_win32.c index 92cf086ab1..c71f253b0a 100644 --- a/ext/opcache/shared_alloc_win32.c +++ b/ext/opcache/shared_alloc_win32.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) 1998-2015 The PHP Group | + | Copyright (c) 1998-2016 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 | @@ -76,18 +76,18 @@ static void zend_win_error_message(int type, char *msg, int err) static char *create_name_with_username(char *name) { - static char newname[MAXPATHLEN + UNLEN + 4]; + static char newname[MAXPATHLEN + UNLEN + 4 + 1 + 32]; char uname[UNLEN + 1]; DWORD unsize = UNLEN; GetUserName(uname, &unsize); - snprintf(newname, sizeof(newname) - 1, "%s@%s", name, uname); + snprintf(newname, sizeof(newname) - 1, "%s@%s@%.32s", name, uname, ZCG(system_id)); return newname; } static char *get_mmap_base_file(void) { - static char windir[MAXPATHLEN+UNLEN + 3 + sizeof("\\\\@")]; + static char windir[MAXPATHLEN+UNLEN + 3 + sizeof("\\\\@") + 1 + 32]; char uname[UNLEN + 1]; DWORD unsize = UNLEN; int l; @@ -95,7 +95,7 @@ static char *get_mmap_base_file(void) GetTempPath(MAXPATHLEN, windir); GetUserName(uname, &unsize); l = strlen(windir); - snprintf(windir + l, sizeof(windir) - l - 1, "\\%s@%s", ACCEL_FILEMAP_BASE, uname); + snprintf(windir + l, sizeof(windir) - l - 1, "\\%s@%s@%.32s", ACCEL_FILEMAP_BASE, uname, ZCG(system_id)); return windir; } @@ -146,13 +146,37 @@ 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, "Unable to reattach to base address", err); + zend_win_error_message(ACCEL_LOG_FATAL, "Base address marks unusable memory region. Please setup opcache.file_cache and opcache.file_cache_callback directives for more convenient Opcache usage", err); return ALLOC_FAILURE; } @@ -204,14 +228,19 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ err = GetLastError(); if (ret == ALLOC_FAIL_MAPPING) { /* Mapping failed, wait for mapping object to get freed and retry */ - CloseHandle(memfile); + CloseHandle(memfile); memfile = NULL; + if (++map_retries >= MAX_MAP_RETRIES) { + break; + } + zend_shared_alloc_unlock_win32(); Sleep(1000 * (map_retries + 1)); + zend_shared_alloc_lock_win32(); } else { zend_shared_alloc_unlock_win32(); return ret; } - } while (++map_retries < MAX_MAP_RETRIES); + } while (1); if (map_retries == MAX_MAP_RETRIES) { zend_shared_alloc_unlock_win32(); @@ -246,29 +275,7 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ be taken (fail to map). So under Vista, we try to map into a hard coded predefined addresses in high memory. */ if (!ZCG(accel_directives).mmap_base || !*ZCG(accel_directives).mmap_base) { - do { - OSVERSIONINFOEX osvi; - SYSTEM_INFO si; - - ZeroMemory(&si, sizeof(SYSTEM_INFO)); - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); - - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - - if (! GetVersionEx ((OSVERSIONINFO *) &osvi)) { - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (!GetVersionEx((OSVERSIONINFO *)&osvi)) { - break; - } - } - - GetSystemInfo(&si); - - /* Are we running Vista ? */ - if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion == 6) { - wanted_mapping_base = vista_mapping_base_set; - } - } while (0); + wanted_mapping_base = vista_mapping_base_set; } else { char *s = ZCG(accel_directives).mmap_base; @@ -324,10 +331,13 @@ static int detach_segment(zend_shared_segment *shared_segment) zend_shared_alloc_lock_win32(); if (mapping_base) { UnmapViewOfFile(mapping_base); + mapping_base = NULL; } CloseHandle(memfile); + memfile = NULL; zend_shared_alloc_unlock_win32(); CloseHandle(memory_mutex); + memory_mutex = NULL; return 0; } |