-
Notifications
You must be signed in to change notification settings - Fork 7.9k
opcache_is_script_cached_in_file_cache(string $filename) #16979
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 4 commits
200193b
798a07d
824e638
30641d6
283844e
8cc7293
fd93557
7e23285
906b92d
1cdf3fa
f620d9c
6df1562
e282578
17edbe6
cd0177f
7cff70a
59a4ecc
b3b9501
d1b74e9
1b8311b
3e573f3
9346db9
f9c05a1
d750ae0
fbb4194
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
--TEST-- | ||
GH-16979: opcache_is_script_cached support file_cache argument | ||
--INI-- | ||
opcache.enable=1 | ||
opcache.enable_cli=1 | ||
opcache.jit=disable | ||
opcache.jit_buffer_size=0 | ||
opcache.file_cache={TMP} | ||
--EXTENSIONS-- | ||
opcache | ||
--FILE-- | ||
<?php | ||
|
||
opcache_compile_file(__FILE__); | ||
|
||
var_dump( | ||
opcache_is_script_cached(__FILE__, false) | ||
); | ||
|
||
var_dump( | ||
opcache_is_script_cached(__FILE__, true) | ||
); | ||
|
||
?> | ||
--EXPECT-- | ||
bool(true) | ||
bool(true) |
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -22,11 +22,13 @@ | |||||||||||||||||
#include <time.h> | ||||||||||||||||||
|
||||||||||||||||||
#include "php.h" | ||||||||||||||||||
#include "zend.h" | ||||||||||||||||||
#include "ZendAccelerator.h" | ||||||||||||||||||
#include "zend_API.h" | ||||||||||||||||||
#include "zend_closures.h" | ||||||||||||||||||
#include "zend_shared_alloc.h" | ||||||||||||||||||
#include "zend_accelerator_blacklist.h" | ||||||||||||||||||
#include "zend_file_cache.h" | ||||||||||||||||||
#include "php_ini.h" | ||||||||||||||||||
#include "SAPI.h" | ||||||||||||||||||
#include "zend_virtual_cwd.h" | ||||||||||||||||||
|
@@ -363,6 +365,37 @@ static int filename_is_in_cache(zend_string *filename) | |||||||||||||||||
return 0; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
static int filename_is_in_file_cache(zend_string *filename) | ||||||||||||||||||
{ | ||||||||||||||||||
if (!ZCG(accel_directives).file_cache) { | ||||||||||||||||||
return 0; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
zend_string *realpath; | ||||||||||||||||||
|
||||||||||||||||||
realpath = zend_resolve_path(filename); | ||||||||||||||||||
|
||||||||||||||||||
if (!realpath) { | ||||||||||||||||||
return 0; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
zend_file_handle handle; | ||||||||||||||||||
|
||||||||||||||||||
zend_stream_init_filename_ex(&handle, filename); | ||||||||||||||||||
handle.opened_path = realpath; | ||||||||||||||||||
|
||||||||||||||||||
zend_persistent_script *persistent_script = zend_file_cache_script_load(&handle, true); | ||||||||||||||||||
|
||||||||||||||||||
zend_destroy_file_handle(&handle); | ||||||||||||||||||
|
||||||||||||||||||
if (persistent_script) { | ||||||||||||||||||
return 1; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
return 0; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
static int accel_file_in_cache(INTERNAL_FUNCTION_PARAMETERS) | ||||||||||||||||||
{ | ||||||||||||||||||
if (ZEND_NUM_ARGS() == 1) { | ||||||||||||||||||
|
@@ -983,10 +1016,11 @@ ZEND_FUNCTION(opcache_compile_file) | |||||||||||||||||
ZEND_FUNCTION(opcache_is_script_cached) | ||||||||||||||||||
{ | ||||||||||||||||||
zend_string *script_name; | ||||||||||||||||||
bool file_cache = 0; | ||||||||||||||||||
|
||||||||||||||||||
ZEND_PARSE_PARAMETERS_START(1, 1) | ||||||||||||||||||
Z_PARAM_STR(script_name) | ||||||||||||||||||
ZEND_PARSE_PARAMETERS_END(); | ||||||||||||||||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &script_name, &file_cache) == FAILURE) { | ||||||||||||||||||
RETURN_THROWS(); | ||||||||||||||||||
} | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose the change away from fast-ZPP to regular ZPP is due to not knowing how this works instead of a deliberate change? (see https://wiki.php.net/rfc/fast_zpp)
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the help with this! |
||||||||||||||||||
|
||||||||||||||||||
if (!validate_api_restriction()) { | ||||||||||||||||||
RETURN_FALSE; | ||||||||||||||||||
|
@@ -996,5 +1030,9 @@ ZEND_FUNCTION(opcache_is_script_cached) | |||||||||||||||||
RETURN_FALSE; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
RETURN_BOOL(filename_is_in_cache(script_name)); | ||||||||||||||||||
if (file_cache) { | ||||||||||||||||||
RETURN_BOOL(filename_is_in_file_cache(script_name)); | ||||||||||||||||||
} else { | ||||||||||||||||||
RETURN_BOOL(filename_is_in_cache(script_name)); | ||||||||||||||||||
} | ||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this lead to loading from the file cache?
This look weird.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of, the
, true
parameter was to skip loading into SHM, so it'll effectively fully load the file & unserialize it, just not load it into SHM.I'll agree this probably wasn't ideal.
How about this latest commit, swapping to
zend_file_cache_script_validate(...)
?I was unhappy with the code re-use, as ideally I'd want to replace the validation code within
zend_file_cache_script_load(...)
with a call tozend_file_cache_script_validate(...)
:However, this had the side effect that I'd either be opening, reading & locking the cache file twice, or, we'd have to return a struct from
zend_file_cache_script_validate(...)
- something like this:and that felt even more complicated.... So I'm at a loss really.
How would you handle it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a parameter to
zend_file_cache_script_load()
would be the simplest solution, but a separate function as you did is a better API (IMHO).I like your suggestion of making the validate function return a struct, but I suggest to pass the struct as parameter so that the caller can allocate it on the stack:
Maybe rename
zend_file_cache_script_validate()
tozend_file_cache_open()
, andzend_file_cache_validation_result
tozend_file_cache_handle
, and add a small wrapper ofzend_file_cache_open()
that doesn't take this parameter:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @arnaud-lb ,
I've just pushed my first try at implementing the way you've suggested.
I actually really like that approach and it makes a lot more logical sense.
In the end, rather than passing around a file descriptor, since we were already reading the whole file to potentially checksum it, I've opted to pass around the
zend_arena_checkpoint
andzend_arena_alloc
values:I won't pretend I understand this very well, so if I've done something wrong, please speak up!
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I overlooked the arena usage before my previous comment. Unfortunately, passing around the arena checkpoint would result in fragile code.
Alternatives would be to allocate the buffer in some other way, or to mmap the file, but this is too much changes and this may negatively impact the performance of
zend_file_cache_script_load()
.At this point I think that adding a
validate_only
parameter tozend_file_cache_script_load()
is a better solution, after all.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries, getting your originally suggested method to build & work has been a great learning experience 😃
Thanks for your time reviewing and helping to move this along, it's really appreciated.
This is pretty much what I'd done in my first attempt that @dstogov didn't seem to like, so before I switch back:
@dstogov are you happy with that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there still any interest in us being able to implement this please?
And if so, @dstogov , are you able to weigh in on the above about what your preferred implementation is please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There were some questions about consistency. I haven't gotten to them yet.