>
>
> And what wincache does. It is slower but the request is served.
>
>
> WinCache (file cache) if it can't reattach, creates a new shared mem file
for just that process: see
http://svn.php.net/viewvc/pecl/wincache/trunk/wincache_filemap.c?revision=336846&view=markup
Line 1122.

Yes, ideally it would be position independent, maybe using based pointers
for the structs in zend_smm_shared_globals, zend_accel_shared_globals,
etc....

I agree my bugfix is suboptimal but its the least complex option to get it
fixed for users in 7, so their requests get served.


My bugfix would increase memory usage, but so does a 2nd WinCache(or 3rd).
But at least if the 2nd OpCache is shared (the same procedure as if no
OpCache existed) its less likely to create a 3rd OpCache. For me at least,
often several processes in a row have this issue, so could have a 3rd or
4th OpCache or WinCache(even more memory), possibly very quickly.

Creating a 2nd OpCache, if its shared or per-process (like WinCache) seems
to be the simpler workaround. The trade-off is memory(especially if
per-process), time to recompile scripts, and sometimes breaking
opcache_reset(), opcache_invalidate() and stat cache pages(shared or
per-process OpCache).

Using the file cache should be better(won't slow down to recompile
scripts). But would still either require changing
zend_shared_alloc_startup() and other places because create_segments()
would still be returning ALLOC_FAILURE, OR creating a 2nd shared or
per-process OpCache anyway. Is this likely to be done? That would be great,
but it seems less likely because of the complexity.

Up to 6 OpCaches(5 backups) may be way too many (based off map_retries, 25
may be too many). My testing only ever gets a 2nd OpCache(never got a 3rd,
etc...).

There should be a workaround/suboptimal fix at least until someday when the
optimal solution is done, so requests get served.


@@ -74,18 +74,18 @@ static void zend_win_error_message(int type, char *msg,
int err)
zend_accel_error(type, msg);
}
-static char *create_name_with_username(char *name)
+static char *create_name_with_username(char *name, int num)
{
static char newname[MAXPATHLEN + UNLEN + 4];
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%d", name, uname, num);
return newname;
}
-static char *get_mmap_base_file(void)
+static char *get_mmap_base_file(int num)
{
static char windir[MAXPATHLEN+UNLEN + 3 + sizeof("\\\\@")];
char uname[UNLEN + 1];
@@ -95,13 +95,13 @@ 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",
ACCEL_FILEMAP_BASE, uname, num);
return windir;
}
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");
return;
@@ -123,11 +123,11 @@ void zend_shared_alloc_unlock_win32(void)
ReleaseMutex(memory_mutex);
}
-static int zend_shared_alloc_reattach(size_t requested_size, char
**error_in)
+static int zend_shared_alloc_reattach(size_t requested_size, int num, char
**error_in)
{
int err;
void *wanted_mapping_base;
- char *mmap_base_file = get_mmap_base_file();
+ char *mmap_base_file = get_mmap_base_file(num);
FILE *fp = fopen(mmap_base_file, "r");
MEMORY_BASIC_INFORMATION info;
@@ -194,24 +194,18 @@ 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 map
will fail
and we have to sleep some time (until the child releases the mapping
object) and retry.*/
do {
- memfile = OpenFileMapping(FILE_MAP_WRITE, 0,
create_name_with_username(ACCEL_FILEMAP_NAME));
+ memfile = OpenFileMapping(FILE_MAP_WRITE, 0,
create_name_with_username(ACCEL_FILEMAP_NAME, map_retries>>2));
err = GetLastError();
if (memfile == NULL) {
break;
}
- ret = zend_shared_alloc_reattach(requested_size, error_in);
+ ret = zend_shared_alloc_reattach(requested_size, map_retries>>2,
error_in);
err = GetLastError();
if (ret == ALLOC_FAIL_MAPPING) {
/* Mapping failed, wait for mapping object to get freed and retry */
@@ -241,7 +235,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_READWRITE, 0,
requested_size,
- create_name_with_username(ACCEL_FILEMAP_NAME));
+ create_name_with_username(ACCEL_FILEMAP_NAME, map_retries>>2));
err = GetLastError();
if (memfile == NULL) {
zend_shared_alloc_unlock_win32();
@@ -306,7 +300,7 @@ static int create_segments(size_t requested_size,
zend_shared_segment ***shared_
*error_in = "MapViewOfFile";
return ALLOC_FAILURE;
} else {
- char *mmap_base_file = get_mmap_base_file();
+ char *mmap_base_file = get_mmap_base_file(map_retries>>2);
FILE *fp = fopen(mmap_base_file, "w");
err = GetLastError();
if (!fp) {

Reply via email to