mirror of
https://github.com/php/frankenphp.git
synced 2026-03-24 00:52:11 +01:00
Adds all thread states.
This commit is contained in:
@@ -2,9 +2,6 @@ package frankenphp
|
||||
|
||||
// #include "frankenphp.h"
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// EXPERIMENTAL: ThreadDebugState prints the state of a single PHP thread - debugging purposes only
|
||||
type ThreadDebugState struct {
|
||||
@@ -54,21 +51,33 @@ func threadDebugState(thread *phpThread) ThreadDebugState {
|
||||
// EXPERIMENTAL: Expose the current thread's information to PHP
|
||||
//
|
||||
//export go_frankenphp_info
|
||||
func go_frankenphp_info(threadIndex C.uintptr_t) unsafe.Pointer {
|
||||
thread := phpThreads[threadIndex]
|
||||
func go_frankenphp_info(threadIndex C.uintptr_t) *C.zval {
|
||||
currentThread := phpThreads[threadIndex]
|
||||
_, isWorker := currentThread.handler.(*workerThread)
|
||||
|
||||
_, isWorker := thread.handler.(*workerThread)
|
||||
threadInfos := make([]any, 0, len(phpThreads))
|
||||
for _, thread := range phpThreads {
|
||||
if thread.state.is(stateReserved) {
|
||||
continue
|
||||
}
|
||||
threadInfos = append(threadInfos, map[string]any{
|
||||
"index": thread.threadIndex,
|
||||
"name": thread.name(),
|
||||
"state": thread.state.name(),
|
||||
"is_waiting": thread.state.isInWaitingState(),
|
||||
"waiting_since_milliseconds": thread.state.waitTime(),
|
||||
})
|
||||
}
|
||||
|
||||
return PHPArray(&Array{
|
||||
keys: []PHPKey{
|
||||
PHPKey{Type: PHPStringKey, Str: "thread_name"},
|
||||
PHPKey{Type: PHPStringKey, Str: "thread_index"},
|
||||
PHPKey{Type: PHPStringKey, Str: "is_worker_thread"},
|
||||
},
|
||||
values: []interface{}{
|
||||
thread.name(),
|
||||
int(threadIndex),
|
||||
isWorker,
|
||||
},
|
||||
})
|
||||
zval := (*C.zval)(PHPMap(map[string]any{
|
||||
"frankenphp_version": C.GoString(C.frankenphp_get_version().frankenphp_version),
|
||||
"current_thread": int64(threadIndex),
|
||||
"is_worker_thread": isWorker,
|
||||
"threads": threadInfos,
|
||||
}))
|
||||
|
||||
// TODO: how to circumvent pinning?
|
||||
currentThread.Pin(zval)
|
||||
|
||||
return zval
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ frankenphp_version frankenphp_get_version() {
|
||||
return (frankenphp_version){
|
||||
PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION,
|
||||
PHP_EXTRA_VERSION, PHP_VERSION, PHP_VERSION_ID,
|
||||
TOSTRING(FRANKENPHP_VERSION)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1204,6 +1205,7 @@ PHP_FUNCTION(frankenphp_info) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
zend_array *result = go_frankenphp_info(thread_index);
|
||||
RETURN_ARR(result);
|
||||
zval *result = go_frankenphp_info(thread_index);
|
||||
|
||||
RETURN_ARR(Z_ARR_P(result));
|
||||
}
|
||||
@@ -36,6 +36,7 @@ typedef struct frankenphp_version {
|
||||
const char *extra_version;
|
||||
const char *version;
|
||||
unsigned long version_id;
|
||||
const char *frankenphp_version;
|
||||
} frankenphp_version;
|
||||
frankenphp_version frankenphp_get_version();
|
||||
|
||||
|
||||
@@ -970,14 +970,14 @@ func TestFileStreamInWorkerMode(t *testing.T) {
|
||||
|
||||
func TestFrankenPHPInfo_module(t *testing.T) {
|
||||
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
|
||||
body := fetchBody("GET", "http://example.com/frankenphp_info.php", handler)
|
||||
body, _ := testGet("http://example.com/frankenphp_info.php", handler, t)
|
||||
assert.Contains(t, body, "[is_worker_thread] => 1")
|
||||
}, &testOptions{workerScript: "frankenphp_info.php"})
|
||||
}
|
||||
|
||||
func TestFrankenPHPInfo_worker(t *testing.T) {
|
||||
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
|
||||
body := fetchBody("GET", "http://example.com/frankenphp_info.php", handler)
|
||||
body, _ := testGet("http://example.com/frankenphp_info.php", handler, t)
|
||||
assert.Contains(t, body, "[is_worker_thread] => \n")
|
||||
}, &testOptions{})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user