Skip to content
Closed
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
50 changes: 44 additions & 6 deletions frankenphp.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,11 @@ sapi_module_struct frankenphp_sapi_module = {

STANDARD_SAPI_MODULE_PROPERTIES};

struct thread_args {
int num_threads;
int num_non_worker_threads;
};

static void *manager_thread(void *arg) {
// SIGPIPE must be masked in non-Go threads:
// https://pkg.go.dev/os/signal#hdr-Go_programs_that_use_cgo_or_SWIG
Expand All @@ -738,7 +743,10 @@ static void *manager_thread(void *arg) {
exit(EXIT_FAILURE);
}

int num_threads = *((int *)arg);
struct thread_args args = *((struct thread_args*)arg);

int num_threads = args.num_threads;
int num_non_worker_threads = args.num_non_worker_threads;
free(arg);
arg = NULL;

Expand Down Expand Up @@ -770,6 +778,16 @@ static void *manager_thread(void *arg) {

threadpool thpool = thpool_init(num_threads);

// handle case where all threads are non-worker threads
if(num_threads == num_non_worker_threads) {
for(int i = 0; i < num_threads; i++) {
thpool_add_work(thpool, go_fetch_and_execute, NULL);
}

// todo: properly shutdown
return NULL;
}

uintptr_t rh;
while ((rh = go_fetch_request())) {
thpool_add_work(thpool, go_execute_script, (void *)rh);
Expand Down Expand Up @@ -798,14 +816,17 @@ static void *manager_thread(void *arg) {
return NULL;
}

int frankenphp_init(int num_threads) {
int frankenphp_init(int num_threads, int non_worker_threads) {
pthread_t thread;

int *num_threads_ptr = calloc(1, sizeof(int));
*num_threads_ptr = num_threads;
struct thread_args args;
args.num_threads = num_threads;
args.num_non_worker_threads = non_worker_threads;

struct thread_args* num_threads_ptr = calloc(1, sizeof(args));
*num_threads_ptr = args;

if (pthread_create(&thread, NULL, *manager_thread, (void *)num_threads_ptr) !=
0) {
if (pthread_create(&thread, NULL, *manager_thread, (void *)num_threads_ptr) != 0) {
go_shutdown();

return -1;
Expand All @@ -815,9 +836,12 @@ int frankenphp_init(int num_threads) {
}

int frankenphp_request_startup() {
//go_log_s("here we go!");
if (php_request_startup() == SUCCESS) {
//go_log_s("success!");
return SUCCESS;
}
//go_log_s("failure!");

frankenphp_server_context *ctx = SG(server_context);
SG(server_context) = NULL;
Expand All @@ -829,14 +853,23 @@ int frankenphp_request_startup() {
return FAILURE;
}

int req = 0;

int frankenphp_execute_script(char *file_name) {
char str[50];
int rn = req++;
sprintf(str, "starting %d", rn);
//go_log_s(str);
if (frankenphp_request_startup() == FAILURE) {
free(file_name);
file_name = NULL;

return FAILURE;
}

sprintf(str, "started %d", rn);
//go_log_s(str);

int status = SUCCESS;

zend_file_handle file_handle;
Expand All @@ -859,6 +892,9 @@ int frankenphp_execute_script(char *file_name) {
frankenphp_clean_server_context();
frankenphp_request_shutdown();

sprintf(str, "finished %d", rn);
//go_log_s(str);

return status;
}

Expand All @@ -875,6 +911,8 @@ static char **cli_argv;
// Bakken and Zeev Suraski
static void cli_register_file_handles(bool no_close) /* {{{ */
{
go_log_s("registering file handles");

php_stream *s_in, *s_out, *s_err;
php_stream_context *sc_in = NULL, *sc_out = NULL, *sc_err = NULL;
zend_constant ic, oc, ec;
Expand Down
65 changes: 63 additions & 2 deletions frankenphp.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import (
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
"unsafe"

"github.com/maypok86/otter"
Expand Down Expand Up @@ -317,7 +319,7 @@ func Init(options ...Option) error {
done = make(chan struct{})
requestChan = make(chan *http.Request)

if C.frankenphp_init(C.int(opt.numThreads)) != 0 {
if C.frankenphp_init(C.int(opt.numThreads), C.int(opt.numThreads-numWorkers)) != 0 {
return MainThreadCreationError
}

Expand Down Expand Up @@ -439,6 +441,8 @@ func updateServerContext(request *http.Request, create bool, mrh C.uintptr_t) er
return nil
}

var counter int

// ServeHTTP executes a PHP script according to the given context.
func ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) error {
shutdownWG.Add(1)
Expand Down Expand Up @@ -475,6 +479,10 @@ func go_fetch_request() C.uintptr_t {
return 0

case r := <-requestChan:
count := counter
counter += 1
logger.Warn("Fetched request", zap.Int("counter", count))
r = r.WithContext(context.WithValue(r.Context(), "counter__", count))
h := cgo.NewHandle(r)
r.Context().Value(handleKey).(*handleList).AddHandle(h)
return C.uintptr_t(h)
Expand All @@ -487,7 +495,58 @@ func maybeCloseContext(fc *FrankenPHPContext) {
})
}

// go_execute_script Note: only called in cgi-mode
//export go_log_s
func go_log_s(cstr *C.char) {
// Convert C string to Go string
str := C.GoString(cstr)

// Log (print) the string
logger.Warn(str)
}

var conReqs atomic.Int32

//export go_fetch_and_execute
func go_fetch_and_execute(rh unsafe.Pointer) {
//logger.Warn("Starting fetch and execute")

start := time.Now()

for {
select {
case <-done:
return
case r := <-requestChan:
conReqs.Add(1)
logger.Warn("Executing request", zap.Int("total", int(conReqs.Load())), zap.Duration("elapsed", time.Since(start)))
start = time.Now()
fc, ok := FromContext(r.Context())
handle := cgo.NewHandle(r)
r.Context().Value(handleKey).(*handleList).AddHandle(handle)
if !ok {
panic(InvalidRequestError)
}

if err := updateServerContext(r, true, 0); err != nil {
panic(err)
}

fc.exitStatus = C.frankenphp_execute_script(C.CString(fc.scriptFilename))
if fc.exitStatus < 0 {
panic(ScriptExecutionError)
}

maybeCloseContext(fc)
r.Context().Value(handleKey).(*handleList).FreeAll()
conReqs.Add(-1)

logger.Warn("finished execution", zap.Int("total", int(conReqs.Load())), zap.Duration("elapsed", time.Since(start)))
start = time.Now()
}
}
}

// go_execute_script Note: only called in cgi-mode and the main worker request
//
//export go_execute_script
func go_execute_script(rh unsafe.Pointer) {
Expand All @@ -512,6 +571,8 @@ func go_execute_script(rh unsafe.Pointer) {
if fc.exitStatus < 0 {
panic(ScriptExecutionError)
}

logger.Warn("Handled request", zap.Any("counter", request.Context().Value("counter__")))
}

//export go_ub_write
Expand Down
2 changes: 1 addition & 1 deletion frankenphp.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ typedef struct frankenphp_config {
} frankenphp_config;
frankenphp_config frankenphp_get_config();

int frankenphp_init(int num_threads);
int frankenphp_init(int num_threads, int non_worker_threads);

int frankenphp_update_server_context(
bool create, uintptr_t current_request, uintptr_t main_request,
Expand Down