Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
dktapps committed Nov 21, 2024
1 parent bc78680 commit 86e029b
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 74 deletions.
73 changes: 3 additions & 70 deletions src/prepare.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,61 +826,8 @@ static inline void pmmpthread_prepare_sapi(const pmmpthread_ident_t* source) {
}
} /* }}} */

/* {{{ Includes the autoloader provided, if any. This code is borrowed from krakjoe/parallel. */
static int pmmpthread_thread_bootstrap(zend_string* file) {
zend_file_handle fh;
zend_op_array* ops;
zval rv;
int result;

if (!file) {
return SUCCESS;
}

zend_stream_init_filename_ex(&fh, file);
result = php_stream_open_for_zend_ex(&fh, USE_PATH | REPORT_ERRORS | STREAM_OPEN_FOR_INCLUDE);

if (result != SUCCESS) {
zend_error(E_ERROR, "Unable to open thread autoload file %s", ZSTR_VAL(file));
return FAILURE;
}

zend_hash_add_empty_element(&EG(included_files),
fh.opened_path ?
fh.opened_path : file);

ops = zend_compile_file(&fh, ZEND_REQUIRE);

zend_destroy_file_handle(&fh);

if (ops) {
ZVAL_UNDEF(&rv);
zend_execute(ops, &rv);
destroy_op_array(ops);
efree(ops);

if (EG(exception)) {
zend_exception_error(EG(exception), E_ERROR);
zend_error(E_ERROR, "Uncaught exception thrown from thread autoload file %s", ZSTR_VAL(file));
return FAILURE;
}

zval_ptr_dtor(&rv);
return SUCCESS;
}

if (EG(exception)) {
zend_exception_error(EG(exception), E_ERROR);
zend_error(E_ERROR, "Error compiling thread autoload file %s", ZSTR_VAL(file));
}

return FAILURE;
} /* }}} */

/* {{{ */
int pmmpthread_prepared_startup(pmmpthread_object_t* thread, pmmpthread_monitor_t *ready, zend_class_entry *thread_ce, zend_ulong thread_options) {
zend_string *autoload_file = NULL;

int pmmpthread_prepared_startup(pmmpthread_object_t* thread, pmmpthread_monitor_t *ready, zend_class_entry *thread_ce, zend_ulong thread_options, zend_string **autoload_file) {
PMMPTHREAD_PREPARATION_BEGIN_CRITICAL() {
thread->local.id = pmmpthread_self();
thread->local.ls = ts_resource(0);
Expand Down Expand Up @@ -936,28 +883,14 @@ int pmmpthread_prepared_startup(pmmpthread_object_t* thread, pmmpthread_monitor_
pmmpthread_prepare_includes(&thread->creator);

if (PMMPTHREAD_G(autoload_file)) {
autoload_file = zend_string_init(ZSTR_VAL(PMMPTHREAD_G(autoload_file)), ZSTR_LEN(PMMPTHREAD_G(autoload_file)), 1);
*autoload_file = zend_string_init(ZSTR_VAL(PMMPTHREAD_G(autoload_file)), ZSTR_LEN(PMMPTHREAD_G(autoload_file)), 1);
}
pmmpthread_monitor_add(ready, PMMPTHREAD_MONITOR_READY);

PMMPTHREAD_G(thread_count)++;
} PMMPTHREAD_PREPARATION_END_CRITICAL();

int result = SUCCESS;

//TODO: we probably should put this code inside routine instead of prepare
if (autoload_file != NULL) {
zend_first_try{
if (pmmpthread_thread_bootstrap(autoload_file) == FAILURE) {
//by this point the ready monitor has probably already been destroyed
//the main thread doesn't wait for user code to start running
pmmpthread_monitor_add(&thread->monitor, PMMPTHREAD_MONITOR_ERROR);
result = FAILURE;
}
} zend_end_try();
zend_string_release(autoload_file);
}
return result;
return SUCCESS;
} /* }}} */

/* {{{ Calls user shutdown functions before entering into the AWAIT_JOIN state.
Expand Down
2 changes: 1 addition & 1 deletion src/prepare.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void pmmpthread_prepared_entry_late_bindings(const pmmpthread_ident_t* source, z
void pmmpthread_context_late_bindings(const pmmpthread_ident_t* source); /* }}} */

/* {{{ */
int pmmpthread_prepared_startup(pmmpthread_object_t* thread, pmmpthread_monitor_t *ready, zend_class_entry *thread_ce, zend_ulong thread_options); /* }}} */
int pmmpthread_prepared_startup(pmmpthread_object_t* thread, pmmpthread_monitor_t *ready, zend_class_entry *thread_ce, zend_ulong thread_options, zend_string **autoload_file); /* }}} */

/* {{{ */
void pmmpthread_call_shutdown_functions(void); /* }}} */
Expand Down
67 changes: 66 additions & 1 deletion src/routine.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,57 @@ static void pmmpthread_routine_free(pmmpthread_routine_arg_t* r) {
pmmpthread_monitor_destroy(&r->ready);
} /* }}} */

/* {{{ Includes the autoloader provided, if any. This code is borrowed from krakjoe/parallel. */
static int pmmpthread_routine_run_bootstrap(zend_string* file) {
zend_file_handle fh;
zend_op_array* ops;
zval rv;
int result;

if (!file) {
return SUCCESS;
}

zend_stream_init_filename_ex(&fh, file);
result = php_stream_open_for_zend_ex(&fh, USE_PATH | REPORT_ERRORS | STREAM_OPEN_FOR_INCLUDE);

if (result != SUCCESS) {
zend_error(E_ERROR, "Unable to open thread autoload file %s", ZSTR_VAL(file));
return FAILURE;
}

zend_hash_add_empty_element(&EG(included_files),
fh.opened_path ?
fh.opened_path : file);

ops = zend_compile_file(&fh, ZEND_REQUIRE);

zend_destroy_file_handle(&fh);

if (ops) {
ZVAL_UNDEF(&rv);
zend_execute(ops, &rv);
destroy_op_array(ops);
efree(ops);

if (EG(exception)) {
zend_exception_error(EG(exception), E_ERROR);
zend_error(E_ERROR, "Uncaught exception thrown from thread autoload file %s", ZSTR_VAL(file));
return FAILURE;
}

zval_ptr_dtor(&rv);
return SUCCESS;
}

if (EG(exception)) {
zend_exception_error(EG(exception), E_ERROR);
zend_error(E_ERROR, "Error compiling thread autoload file %s", ZSTR_VAL(file));
}

return FAILURE;
} /* }}} */

/* {{{ */
static inline zend_result pmmpthread_routine_run_function(pmmpthread_zend_object_t* connection) {
zend_function* run;
Expand Down Expand Up @@ -106,12 +157,24 @@ static void* pmmpthread_routine(pmmpthread_routine_arg_t* routine) {
zend_ulong thread_options = routine->options;
pmmpthread_object_t* ts_obj = thread->ts_obj;
pmmpthread_monitor_t* ready = &routine->ready;
zend_string* autoload_file = NULL;

if (pmmpthread_prepared_startup(ts_obj, ready, thread->std.ce, thread_options) == SUCCESS) {
if (pmmpthread_prepared_startup(ts_obj, ready, thread->std.ce, thread_options, &autoload_file) == SUCCESS) {
pmmpthread_queue done_tasks_cache;
memset(&done_tasks_cache, 0, sizeof(pmmpthread_queue));

zend_first_try{
if (autoload_file != NULL) {
zend_try {
if (pmmpthread_routine_run_bootstrap(autoload_file) == FAILURE) {
zend_bailout();
}
} zend_catch {
zend_string_release(autoload_file);
zend_bailout();
} zend_end_try();
}

ZVAL_UNDEF(&PMMPTHREAD_ZG(this));
pmmpthread_object_connect(thread, &PMMPTHREAD_ZG(this));
if (pmmpthread_routine_run_function(PMMPTHREAD_FETCH_FROM(Z_OBJ_P(&PMMPTHREAD_ZG(this)))) == FAILURE) {
Expand Down Expand Up @@ -140,6 +203,8 @@ static void* pmmpthread_routine(pmmpthread_routine_arg_t* routine) {
}
}
}
} zend_catch {
pmmpthread_monitor_add(&ts_obj->monitor, PMMPTHREAD_MONITOR_ERROR);
} zend_end_try();

pmmpthread_call_shutdown_functions();
Expand Down
2 changes: 1 addition & 1 deletion tests/autoload-file-invalid-path.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Thread::setAutoloadFile(__DIR__ . '/assets/i-dont-exist.php');

$thread = new class extends Thread{
public function run() : void{

echo "unreachable\n";
}
};

Expand Down
2 changes: 1 addition & 1 deletion tests/autoload-file-throws-exception.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Thread::setAutoloadFile(__DIR__ . '/assets/autoload-file-uncaught-exception.php'

$thread = new class extends Thread{
public function run() : void{

echo "unreachable\n";
}
};

Expand Down

0 comments on commit 86e029b

Please sign in to comment.