diff --git a/php_v8js_macros.h b/php_v8js_macros.h index 7f0d019e..c65403e3 100644 --- a/php_v8js_macros.h +++ b/php_v8js_macros.h @@ -159,6 +159,9 @@ struct _v8js_process_globals { /* Path to icudtl.dat file */ char *icudtl_dat_path; + /* Number of V8 platform background worker threads */ + int thread_pool_size; + std::unique_ptr v8_platform; }; diff --git a/tests/thread_pool_size.phpt b/tests/thread_pool_size.phpt new file mode 100644 index 00000000..f9cf1412 --- /dev/null +++ b/tests/thread_pool_size.phpt @@ -0,0 +1,76 @@ +--TEST-- +v8js.thread_pool_size INI directive validation and lifecycle +--SKIPIF-- + +--INI-- +v8js.thread_pool_size=0 +--FILE-- +executeString('1 + 2')); + +// 5. Attempts to change setting after initialization must fail +var_dump(ini_set('v8js.thread_pool_size', '2')); +var_dump(ini_set('v8js.thread_pool_size', '0')); +var_dump(ini_set('v8js.thread_pool_size', '64')); +var_dump(ini_get('v8js.thread_pool_size')); + +// 6. Attempts to change setting after destroying instance must still fail +unset($v8); +var_dump(ini_set('v8js.thread_pool_size', '8')); +var_dump(ini_set('v8js.thread_pool_size', '0')); +var_dump(ini_get('v8js.thread_pool_size')); +?> +===EOF=== +--EXPECT-- +string(1) "0" +string(1) "0" +string(1) "1" +string(1) "1" +string(2) "64" +string(2) "64" +string(1) "0" +string(1) "0" +string(1) "4" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(1) "4" +int(3) +bool(false) +bool(false) +bool(false) +string(1) "4" +bool(false) +bool(false) +string(1) "4" +===EOF=== diff --git a/v8js_main.cc b/v8js_main.cc index 627949a0..01574c18 100644 --- a/v8js_main.cc +++ b/v8js_main.cc @@ -112,11 +112,41 @@ static ZEND_INI_MH(v8js_OnUpdateUseArrayAccess) /* {{{ */ } /* }}} */ +static ZEND_INI_MH(v8js_OnUpdateThreadPoolSize) /* {{{ */ +{ +#if PHP_VERSION_ID < 80200 + zend_long tmp = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); +#else + zend_long tmp = zend_ini_parse_quantity_warn(new_value, entry->name); +#endif + /* V8 has hard limit of 16 threads for now, we allow up to 64 */ + if (tmp < 0 || tmp > 64) { + return FAILURE; + } + +#ifdef ZTS + std::lock_guard lock(v8js_process_globals.lock); + if (v8js_process_globals.v8_initialized) { + return FAILURE; + } +#else + /* V8 already has been initialized -> cannot be changed anymore */ + if (V8JSG(v8_initialized)) { + return FAILURE; + } +#endif + + v8js_process_globals.thread_pool_size = static_cast(tmp); + return SUCCESS; +} +/* }}} */ + ZEND_INI_BEGIN() /* {{{ */ ZEND_INI_ENTRY("v8js.flags", NULL, ZEND_INI_ALL, v8js_OnUpdateV8Flags) ZEND_INI_ENTRY("v8js.icudtl_dat_path", NULL, ZEND_INI_ALL, v8js_OnUpdateIcudatPath) ZEND_INI_ENTRY("v8js.use_date", "0", ZEND_INI_ALL, v8js_OnUpdateUseDate) ZEND_INI_ENTRY("v8js.use_array_access", "0", ZEND_INI_ALL, v8js_OnUpdateUseArrayAccess) + ZEND_INI_ENTRY("v8js.thread_pool_size", "0", ZEND_INI_ALL, v8js_OnUpdateThreadPoolSize) ZEND_INI_END() /* }}} */ diff --git a/v8js_v8.cc b/v8js_v8.cc index 467f201b..cba06e21 100644 --- a/v8js_v8.cc +++ b/v8js_v8.cc @@ -68,7 +68,11 @@ void v8js_v8_init() /* {{{ */ #endif #endif - v8js_process_globals.v8_platform = v8::platform::NewDefaultPlatform(); + if (v8js_process_globals.thread_pool_size > 0) { + v8js_process_globals.v8_platform = v8::platform::NewDefaultPlatform(v8js_process_globals.thread_pool_size); + } else { + v8js_process_globals.v8_platform = v8::platform::NewDefaultPlatform(); + } v8::V8::InitializePlatform(v8js_process_globals.v8_platform.get()); #ifdef V8_HAS_INITIALIZE_SANDBOX