diff --git a/NEWS b/NEWS index 1485a9f3110..af78129214f 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,10 @@ PHP NEWS . Fix IntlDateFormatter::parseToCalendar() reference type system breaks. (nielsdos) +- Opcache: + . Fixed bug GH-18417 (Windows SHM reattachment fails when increasing + memory_consumption or jit_buffer_size). (nielsdos) + - SPL: . Fixed bug GH-18421 (Integer overflow with large numbers in LimitIterator). (nielsdos) diff --git a/ext/opcache/shared_alloc_win32.c b/ext/opcache/shared_alloc_win32.c index 331aff32c98..5e37cedcb4d 100644 --- a/ext/opcache/shared_alloc_win32.c +++ b/ext/opcache/shared_alloc_win32.c @@ -69,9 +69,9 @@ static void zend_win_error_message(int type, char *msg, int err) php_win32_error_msg_free(buf); } -static char *create_name_with_username(char *name) +static char *create_name_with_username(const char *name, size_t unique_id) { - static char newname[MAXPATHLEN + 1 + 32 + 1 + 20 + 1 + 32 + 1]; + static char newname[MAXPATHLEN + 1 + 32 + 1 + 20 + 1 + 32 + sizeof("ffffffffffffffff")-1 + 1]; char *p = newname; p += strlcpy(newname, name, MAXPATHLEN + 1); *(p++) = '@'; @@ -80,7 +80,11 @@ static char *create_name_with_username(char *name) p += strlcpy(p, sapi_module.name, 21); *(p++) = '@'; p = zend_mempcpy(p, zend_system_id, 32); - *(p++) = '\0'; + if (unique_id) { + p += snprintf(p, sizeof("ffffffffffffffff"), "%zx", unique_id) + 1; + } else { + *(p++) = '\0'; + } ZEND_ASSERT(p - newname <= sizeof(newname)); return newname; @@ -88,7 +92,7 @@ static char *create_name_with_username(char *name) void zend_shared_alloc_create_lock(void) { - memory_mutex = CreateMutex(NULL, FALSE, create_name_with_username(ACCEL_MUTEX_NAME)); + memory_mutex = CreateMutex(NULL, FALSE, create_name_with_username(ACCEL_MUTEX_NAME, 0)); if (!memory_mutex) { zend_accel_error(ACCEL_LOG_FATAL, "Cannot create mutex (error %u)", GetLastError()); return; @@ -222,7 +226,7 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ can be called before the child process is killed. In this case, the mapping will fail and we have to sleep some time (until the child releases the mapping object) and retry.*/ do { - memfile = OpenFileMapping(FILE_MAP_READ|FILE_MAP_WRITE|FILE_MAP_EXECUTE, 0, create_name_with_username(ACCEL_FILEMAP_NAME)); + memfile = OpenFileMapping(FILE_MAP_READ|FILE_MAP_WRITE|FILE_MAP_EXECUTE, 0, create_name_with_username(ACCEL_FILEMAP_NAME, requested_size)); if (memfile == NULL) { err = GetLastError(); break; @@ -267,7 +271,7 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ (*shared_segments_p)[0] = shared_segment; memfile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE | SEC_COMMIT, size_high, size_low, - create_name_with_username(ACCEL_FILEMAP_NAME)); + create_name_with_username(ACCEL_FILEMAP_NAME, requested_size)); if (memfile == NULL) { err = GetLastError(); zend_shared_alloc_unlock_win32(); diff --git a/ext/opcache/tests/gh18417.phpt b/ext/opcache/tests/gh18417.phpt new file mode 100644 index 00000000000..e7b9790b9e6 --- /dev/null +++ b/ext/opcache/tests/gh18417.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-18417 (Windows SHM reattachment fails when increasing memory_consumption or jit_buffer_size) +--SKIPIF-- + +--FILE-- + ["pipe", "r"], + 1 => ["pipe", "w"], + 2 => ["pipe", "w"], +]; + +$proc = proc_open([ + PHP_BINARY, + "-n", + "-d", "extension_dir=$extension_dir", + "-d", "zend_extension=opcache", + "-d", "opcache.memory_consumption=$new_memory_consumption", + "-d", "opcache.enable=1", + "-d", "opcache.enable_cli=1", + "-r", + "echo 1;" +], $descriptorspec, $pipes); + +echo stream_get_contents($pipes[1]); +echo stream_get_contents($pipes[2]); + +proc_close($proc); +?> +--EXPECT-- +1