Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:88597 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 87068 invoked from network); 1 Oct 2015 08:54:15 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Oct 2015 08:54:15 -0000 Authentication-Results: pb1.pair.com header.from=themattficken@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=themattficken@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.217.177 as permitted sender) X-PHP-List-Original-Sender: themattficken@gmail.com X-Host-Fingerprint: 209.85.217.177 mail-lb0-f177.google.com Received: from [209.85.217.177] ([209.85.217.177:36206] helo=mail-lb0-f177.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 3E/A2-04700-5B4FC065 for ; Thu, 01 Oct 2015 04:54:14 -0400 Received: by lbcao8 with SMTP id ao8so5189274lbc.3 for ; Thu, 01 Oct 2015 01:54:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=945I5EUpIkeJf6PpFnmW+ZIzCMy5iH7S2jm9dRbfeCU=; b=Alha1eaiG0EKeNhveaGO6jY4cjmplNdFmtBWF8R4pXG4FsOtGSYyRnHYKCx2uh9l1K 6AJMjdlECJ2M2be2b0RUE/rxpTM2p5snIvyZh13xrVPhduzFjTHWeKPujF1lD9CMxA9r moLgdXmbPbe8dOEFg3KO4OWUMqJwVRXZc0oIGi+FlFGUSut1Rg0Ss0Hx8JCPfWgIF6Ls mzpbrb07c2JSryKKG2eU3mKcDXNfktzzFKT0Rz5ZIVFew5dRG7Y3ENrdl8N/5NLFaE0v uy7o82x5lvsE+P2o4wf+Ct3tKAQt6JCynCBPSaa4IH6AkEfBUMPcElQLdpitEVvMk6xj Sftw== MIME-Version: 1.0 X-Received: by 10.25.151.65 with SMTP id z62mr1623996lfd.21.1443689650052; Thu, 01 Oct 2015 01:54:10 -0700 (PDT) Received: by 10.112.46.38 with HTTP; Thu, 1 Oct 2015 01:54:09 -0700 (PDT) In-Reply-To: References: Date: Thu, 1 Oct 2015 01:54:09 -0700 Message-ID: To: Pierre Joye Cc: Dmitry Stogov , Anatoliy Belsky , Laruence , PHP Internals , "dmitry@php.net" Content-Type: multipart/alternative; boundary=001a11402942c1e713052107305b Subject: Re: [PHP-DEV] Re: Windows OpCache bug fix From: themattficken@gmail.com (Matt Ficken) --001a11402942c1e713052107305b Content-Type: text/plain; charset=UTF-8 > > > 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) { --001a11402942c1e713052107305b--