Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:21758 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 77806 invoked by uid 1010); 1 Feb 2006 22:53:51 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 77790 invoked from network); 1 Feb 2006 22:53:51 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Feb 2006 22:53:51 -0000 X-Host-Fingerprint: 204.11.219.139 lerdorf.com Linux 2.4/2.6 Received: from ([204.11.219.139:48670] helo=colo.lerdorf.com) by pb1.pair.com (ecelerity 2.0 beta r(6323M)) with SMTP id 0F/17-23224-EFB31E34 for ; Wed, 01 Feb 2006 17:53:51 -0500 Received: from [192.168.150.3] ([203.98.22.198]) (authenticated bits=0) by colo.lerdorf.com (8.13.5/8.13.5/Debian-3) with ESMTP id k11Mripv030669 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 1 Feb 2006 14:53:46 -0800 Message-ID: <43E13BF9.6030101@lerdorf.com> Date: Thu, 02 Feb 2006 11:53:45 +1300 User-Agent: Thunderbird 1.5 (Macintosh/20051201) MIME-Version: 1.0 To: Sascha Schumann CC: jluedke@concentric.com, internals@lists.php.net References: <200602011939.OAA10156@alexander.concentric.com> <43E1143C.7080407@lerdorf.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: ClamAV 0.88/1266/Wed Feb 1 14:21:42 2006 on colo X-Virus-Status: Clean Subject: Re: [PHP-DEV] reducing open calls in php From: rasmus@lerdorf.com (Rasmus Lerdorf) Sascha Schumann wrote: > Or simply use eAccelerator which does not cause those open > calls. Which doesn't support PHP 5.1 very well. > Rasmus, is that behaviour by design? I deinstalled APC > because of this 'characteristic' last week. It was killing a > high-traffic site. Look at the code for require_once/include_once. It has nothing to do with APC. The code is: zend_file_handle file_handle; if(SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle)) { if(!file_handle.opened_path) { file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); } if(zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) { op_array = zend_compile_file(&file_handle, ZEND_INCLUDE); zend_destroy_file_handle(&file_handle); } else { zend_file_handle_dtor(&file_handle); failure_retval=1; } } else { if(opline->op2.u.constant.value.lval==ZEND_INCLUDE_ONCE) { zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, inc_filename->value.str.val); } else { zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, inc_filename->value.str.val); } } In contrast, a straight include/require just does: op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename); Nothing else. An opcode cache doesn't kick in until the compiler hook is invoked either by zend_compile_filename or zend_compile_file. Anything that happens before is outside of its control, and since there is no hook here to override this require_once behaviour I really don't see how an opcode cache can be avoiding this zend_stream_open() call. The way the _once code is written makes a lot of sense for non-opcode cached requests where it would be silly to do an initial stat to check if the file has been included and then go back and open it. Doing it all in one call makes sense assuming multiple includes is not the common case and that an open isn't significantly more expensive than a stat. However, for an opcode cache this is of course far from ideal and it is an area I have on my TODO list for trying to figure out a nice way to work around it. If eaccel has somehow figured out a way around this I'd like to see it. I have never looked at that code and I don't particularly want to, so if someone could provide a rough summary of how they manage to override this _once logic I would appreciate it. -Rasmus