Skip to content

Commit 98f446d

Browse files
committed
feat: expose thread API for Go-based PHP extensions
Add APIs that enable Go-based PHP extensions to execute on existing FrankenPHP threads and access per-request state: - Thread(index) — retrieves a PHP thread by its index, returning its *http.Request which carries the request context - PHPThread.Pin() — pins a Go object to prevent GC collection - PHPThread.IsRequestDone() — checks if the request has been closed - frankenphp_thread_index() — C function returning the current thread index so C extension methods can call back into Go This makes it possible to build PHP extensions where PHP calls into C, C resolves the current thread index, and Go handles the logic with full access to the request context.
1 parent d26834c commit 98f446d

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

frankenphp.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,10 @@ bool frankenphp_new_php_thread(uintptr_t thread_index) {
12781278
return true;
12791279
}
12801280

1281+
uintptr_t frankenphp_thread_index(void) {
1282+
return thread_index;
1283+
}
1284+
12811285
/* Use global variables to store CLI arguments to prevent useless allocations */
12821286
static char *cli_script;
12831287
static int cli_argc;

frankenphp.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,38 @@ type PHPConfig struct {
128128
ZendMaxExecutionTimers bool
129129
}
130130

131+
// PHPThread exposes a PHP thread's request context.
132+
type PHPThread struct {
133+
Request *http.Request
134+
thread *phpThread
135+
}
136+
137+
// IsRequestDone determines whether the request associated with the PHPThread has been closed.
138+
func (p *PHPThread) IsRequestDone() bool {
139+
return p.thread.frankenPHPContext().isDone
140+
}
141+
142+
// Pin pins a Go object, preventing it from being moved or freed by the garbage
143+
// collector until the Pinner.Unpin method has been called.
144+
func (p *PHPThread) Pin(pointer any) {
145+
p.thread.Pin(pointer)
146+
}
147+
148+
// Thread retrieves a PHP thread by its index.
149+
// Returns nil and false if the system is not running or no thread exists at the given index.
150+
func Thread(index int) (*PHPThread, bool) {
151+
if !isRunning {
152+
return nil, false
153+
}
154+
155+
thread := phpThreads[index]
156+
if thread != nil {
157+
return &PHPThread{thread.frankenPHPContext().request, thread}, true
158+
}
159+
160+
return nil, false
161+
}
162+
131163
// Version returns infos about the PHP version.
132164
func Version() PHPVersion {
133165
cVersion := C.frankenphp_get_version()

frankenphp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ frankenphp_config frankenphp_get_config();
168168
int frankenphp_new_main_thread(int num_threads);
169169
bool frankenphp_new_php_thread(uintptr_t thread_index);
170170

171+
uintptr_t frankenphp_thread_index(void);
172+
171173
bool frankenphp_shutdown_dummy_request(void);
172174
void frankenphp_update_local_thread_context(bool is_worker);
173175

0 commit comments

Comments
 (0)