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
84 changes: 72 additions & 12 deletions frankenphp.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
ZEND_TSRMLS_CACHE_DEFINE()
#endif

static const char *MODULES_TO_RELOAD[] = {"filter", "session", NULL};
#define INITIAL_MODULES_CAPACITY 8

static const char *MODULES_TO_RELOAD[] = {"filter", "session"};
frankenphp_modules_to_reload modules_to_reload = {NULL, 0, 0};

frankenphp_version frankenphp_get_version() {
return (frankenphp_version){
Expand Down Expand Up @@ -115,18 +118,42 @@ static void frankenphp_release_temporary_streams() {
ZEND_HASH_FOREACH_END();
}

static void init_modules_to_reload(void) {
if (modules_to_reload.names != NULL) {
return;
}

size_t length = sizeof MODULES_TO_RELOAD / sizeof *MODULES_TO_RELOAD;

size_t capacity = length > 0 ? length * 2 : INITIAL_MODULES_CAPACITY;
modules_to_reload.names = malloc(capacity * sizeof(char *));
if (!modules_to_reload.names) {
return; // TODO: handle this as an error
}

for (size_t i = 0; i < length; i++) {
modules_to_reload.names[i] = strdup(MODULES_TO_RELOAD[i]);
}

modules_to_reload.length = length;
modules_to_reload.capacity = capacity;
}

/* Adapted from php_request_shutdown */
static void frankenphp_worker_request_shutdown() {
/* Flush all output buffers */
zend_try { php_output_end_all(); }
zend_end_try();

/* TODO: store the list of modules to reload in a global module variable */
const char **module_name;
init_modules_to_reload();

zend_module_entry *module;
for (module_name = MODULES_TO_RELOAD; *module_name; module_name++) {
if ((module = zend_hash_str_find_ptr(&module_registry, *module_name,
strlen(*module_name)))) {
for (size_t i = 0; i < modules_to_reload.length; i++) {
module =
zend_hash_str_find_ptr(&module_registry, modules_to_reload.names[i],
strlen(modules_to_reload.names[i]));

if (module && module->request_shutdown_func) {
module->request_shutdown_func(module->type, module->module_number);
}
}
Expand All @@ -144,6 +171,37 @@ static void frankenphp_worker_request_shutdown() {
zend_set_memory_limit(PG(memory_limit));
}

/* API for extensions to register their modules to reload */
bool frankenphp_register_module_to_reload(const char *module_name) {
if (module_name == NULL) {
return false;
}

init_modules_to_reload();

for (size_t i = 0; i < modules_to_reload.length; i++) {
if (strcmp(modules_to_reload.names[i], module_name) == 0) {
return true;
}
}

if (modules_to_reload.length >= modules_to_reload.capacity) {
size_t new_capacity = modules_to_reload.capacity * 2;
const char **new_names =
realloc(modules_to_reload.names, new_capacity * sizeof(char *));
if (!new_names) {
return false; // Out of memory
}
modules_to_reload.names = new_names;
modules_to_reload.capacity = new_capacity;
}

modules_to_reload.names[modules_to_reload.length] = strdup(module_name);
modules_to_reload.length++;

return true;
}

// shutdown the dummy request that starts the worker script
bool frankenphp_shutdown_dummy_request(void) {
if (SG(server_context) == NULL) {
Expand Down Expand Up @@ -223,13 +281,15 @@ static int frankenphp_worker_request_startup() {
}
}

/* TODO: store the list of modules to reload in a global module variable */
const char **module_name;
init_modules_to_reload();

/* Reload modules */
zend_module_entry *module;
for (module_name = MODULES_TO_RELOAD; *module_name; module_name++) {
if ((module = zend_hash_str_find_ptr(&module_registry, *module_name,
strlen(*module_name))) &&
module->request_startup_func) {
for (size_t i = 0; i < modules_to_reload.length; i++) {
module =
zend_hash_str_find_ptr(&module_registry, modules_to_reload.names[i],
strlen(modules_to_reload.names[i]));
if (module && module->request_startup_func) {
module->request_startup_func(module->type, module->module_number);
}
}
Expand Down
8 changes: 8 additions & 0 deletions frankenphp.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ typedef struct frankenphp_config {
} frankenphp_config;
frankenphp_config frankenphp_get_config();

typedef struct {
const char **names;
size_t length;
size_t capacity;
} frankenphp_modules_to_reload;

int frankenphp_new_main_thread(int num_threads);
bool frankenphp_new_php_thread(uintptr_t thread_index);

Expand Down Expand Up @@ -91,4 +97,6 @@ void frankenphp_register_bulk(
ht_key_value_pair auth_type, ht_key_value_pair remote_ident,
ht_key_value_pair request_uri);

bool frankenphp_register_module_to_reload(const char *module_name);

#endif
Loading