Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions php_v8js_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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> v8_platform;
};

Expand Down
76 changes: 76 additions & 0 deletions tests/thread_pool_size.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
--TEST--
v8js.thread_pool_size INI directive validation and lifecycle
--SKIPIF--
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
--INI--
v8js.thread_pool_size=0
--FILE--
<?php
// 1. Initial value
var_dump(ini_get('v8js.thread_pool_size'));

// 2. Valid values before initialization (including boundaries 0 and 64)
var_dump(ini_set('v8js.thread_pool_size', '1'));
var_dump(ini_get('v8js.thread_pool_size'));

var_dump(ini_set('v8js.thread_pool_size', '64'));
var_dump(ini_get('v8js.thread_pool_size'));

var_dump(ini_set('v8js.thread_pool_size', '0'));
var_dump(ini_get('v8js.thread_pool_size'));

var_dump(ini_set('v8js.thread_pool_size', '4'));
var_dump(ini_get('v8js.thread_pool_size'));

// 3. Out-of-range and malformed values (must return false, value remains unchanged)
var_dump(ini_set('v8js.thread_pool_size', '-1'));
var_dump(ini_set('v8js.thread_pool_size', '-42'));
var_dump(ini_set('v8js.thread_pool_size', '65'));
var_dump(ini_set('v8js.thread_pool_size', '100'));
var_dump(@ini_set('v8js.thread_pool_size', '-1foo'));
var_dump(@ini_set('v8js.thread_pool_size', '100M'));
var_dump(ini_get('v8js.thread_pool_size'));

// 4. Initialize V8 platform by creating an instance
$v8 = new V8Js();
var_dump($v8->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===
30 changes: 30 additions & 0 deletions v8js_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Comment thread
Appla marked this conversation as resolved.
Resolved
#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<std::mutex> 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<int>(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)
Comment thread
Appla marked this conversation as resolved.
Resolved
ZEND_INI_END()
/* }}} */

Expand Down
6 changes: 5 additions & 1 deletion v8js_v8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down