@@ -934,6 +934,31 @@ PHP_FUNCTION(frankenphp_log) {
934934 }
935935}
936936
937+ static void frankenphp_opcache_restart_hook (int reason ) {
938+ (void )reason ;
939+ go_schedule_opcache_reset (frankenphp_thread_index ());
940+ }
941+
942+ /* {{{ thread-safe opcache reset */
943+ PHP_FUNCTION (frankenphp_opcache_reset ) {
944+ frankenphp_opcache_restart_hook (0 );
945+
946+ RETVAL_TRUE ;
947+ } /* }}} */
948+
949+ /* Try to override opcache_reset if opcache is loaded.
950+ * instead of resetting opcache, reboot all threads */
951+ static void frankenphp_override_opcache_reset (void ) {
952+ zend_function * func = zend_hash_str_find_ptr (
953+ CG (function_table ), "opcache_reset" , sizeof ("opcache_reset" ) - 1 );
954+ if (func != NULL && func -> type == ZEND_INTERNAL_FUNCTION &&
955+ ((zend_internal_function * )func )-> handler !=
956+ ZEND_FN (frankenphp_opcache_reset )) {
957+ ((zend_internal_function * )func )-> handler =
958+ ZEND_FN (frankenphp_opcache_reset );
959+ }
960+ }
961+
937962#ifdef FRANKENPHP_TEST
938963/* Test-only entry point that exercises zval.h end-to-end:
939964 * validate -> persist (request -> persistent memory) ->
@@ -1005,6 +1030,10 @@ PHP_MINIT_FUNCTION(frankenphp) {
10051030 php_error (E_WARNING , "Failed to find built-in getenv function" );
10061031 }
10071032
1033+ // Override opcache_reset (may not be available yet if opcache loads as a
1034+ // shared extension in PHP 8.4 and below)
1035+ frankenphp_override_opcache_reset ();
1036+
10081037 return SUCCESS ;
10091038}
10101039
@@ -1023,7 +1052,16 @@ static zend_module_entry frankenphp_module = {
10231052static int frankenphp_startup (sapi_module_struct * sapi_module ) {
10241053 php_import_environment_variables = get_full_env ;
10251054
1026- return php_module_startup (sapi_module , & frankenphp_module );
1055+ int result = php_module_startup (sapi_module , & frankenphp_module );
1056+ #if PHP_VERSION_ID < 80500
1057+ if (result == SUCCESS ) {
1058+ /* Override opcache here again if loaded as a shared extension
1059+ * (php 8.4 and under) */
1060+ frankenphp_override_opcache_reset ();
1061+ }
1062+ #endif
1063+
1064+ return result ;
10271065}
10281066
10291067static int frankenphp_deactivate (void ) { return SUCCESS ; }
@@ -1392,6 +1430,12 @@ static void *php_thread(void *arg) {
13921430 zend_bailout ();
13931431 }
13941432
1433+ #if PHP_VERSION_ID < 80500
1434+ /* Override opcache here again if loaded as a shared extension
1435+ * (php 8.4 and under) */
1436+ frankenphp_override_opcache_reset ();
1437+ #endif
1438+
13951439 zend_file_handle file_handle ;
13961440 zend_stream_init_filename (& file_handle , scriptName );
13971441
@@ -1571,6 +1615,13 @@ static void *php_main(void *arg) {
15711615
15721616 frankenphp_sapi_module .startup (& frankenphp_sapi_module );
15731617
1618+ #if defined(ZTS ) && PHP_VERSION_ID >= 80400
1619+ /* Also restart everything on opcache memory overflow or similar events, the
1620+ * hook is triggered right before an opcache reset is scheduled
1621+ */
1622+ zend_accel_schedule_restart_hook = frankenphp_opcache_restart_hook ;
1623+ #endif
1624+
15741625 /* check if a default filter is set in php.ini and only filter if
15751626 * it is, this is deprecated and will be removed in PHP 9 */
15761627 char * default_filter ;
@@ -1784,16 +1835,6 @@ int frankenphp_execute_script_cli(char *script, int argc, char **argv,
17841835 return (intptr_t )exit_status ;
17851836}
17861837
1787- int frankenphp_reset_opcache (void ) {
1788- zend_function * opcache_reset =
1789- zend_hash_str_find_ptr (CG (function_table ), ZEND_STRL ("opcache_reset" ));
1790- if (opcache_reset ) {
1791- zend_call_known_function (opcache_reset , NULL , NULL , NULL , 0 , NULL , NULL );
1792- }
1793-
1794- return 0 ;
1795- }
1796-
17971838int frankenphp_get_current_memory_limit () { return PG (memory_limit ); }
17981839
17991840void frankenphp_init_thread_metrics (int max_threads ) {
0 commit comments