Skip to content
This repository has been archived by the owner on Dec 16, 2019. It is now read-only.

WIP: New Concurrent class #906

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
75 changes: 75 additions & 0 deletions php_pthreads.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,15 @@ zend_module_entry pthreads_module_entry = {
zend_class_entry *pthreads_threaded_entry;
zend_class_entry *pthreads_volatile_entry;
zend_class_entry *pthreads_thread_entry;
zend_class_entry *pthreads_concurrent_entry;
zend_class_entry *pthreads_worker_entry;
zend_class_entry *pthreads_collectable_entry;
zend_class_entry *pthreads_pool_entry;
zend_class_entry *pthreads_socket_entry;

zend_object_handlers pthreads_handlers;
zend_object_handlers pthreads_socket_handlers;
zend_object_handlers pthreads_concurrent_handlers;
zend_object_handlers *zend_handlers;
void ***pthreads_instance = NULL;

Expand Down Expand Up @@ -119,8 +121,12 @@ static inline zend_bool pthreads_is_supported_sapi(char *name) {
}

typedef void (*zend_execute_ex_function)(zend_execute_data *);
typedef zend_op_array *(*zend_compile_file_function)(zend_file_handle *file_handle, int type);
typedef zend_op_array *(*zend_compile_string_function)(zval *source_string, char *filename);

zend_execute_ex_function zend_execute_ex_hook = NULL;
zend_compile_file_function zend_compile_file_hook = NULL;
zend_compile_string_function zend_compile_string_hook = NULL;

static inline void pthreads_globals_ctor(zend_pthreads_globals *pg) {
ZVAL_UNDEF(&pg->this);
Expand All @@ -131,6 +137,7 @@ static inline void pthreads_globals_ctor(zend_pthreads_globals *pg) {

/* {{{ */
static inline void pthreads_execute_ex(zend_execute_data *data) {

if (zend_execute_ex_hook) {
zend_execute_ex_hook(data);
} else execute_ex(data);
Expand All @@ -142,6 +149,50 @@ static inline void pthreads_execute_ex(zend_execute_data *data) {
}
} /* }}} */

/* {{{ */
static inline zend_op_array *pthreads_loop_postcompile_classtable() {
zend_class_entry *entry;
zend_string *name, *dup;

if (pthreads_compile_hook_lock()) {
ZEND_HASH_FOREACH_STR_KEY_PTR(CG(class_table), name, entry) {
if (entry->type == ZEND_USER_CLASS && !zend_hash_exists(&PTHREADS_G(postcompile), name) && ZSTR_VAL(name)[0] != '\0') {
dup = zend_new_interned_string(zend_string_init(ZSTR_VAL(name), ZSTR_LEN(name), GC_FLAGS(name) & IS_STR_PERSISTENT));
zend_hash_update_ptr(&PTHREADS_G(postcompile), dup, dup);
prepare_class_postcompile(entry);
}
} ZEND_HASH_FOREACH_END();

pthreads_compile_hook_unlock();
}
} /* }}} */

/* {{{ */
static inline zend_op_array *pthreads_compile_file(zend_file_handle *file_handle, int type) {
zend_op_array *op_array;

if (zend_compile_file_hook) {
op_array = zend_compile_file_hook(file_handle, type);
} else op_array = compile_file(file_handle, type);

pthreads_loop_postcompile_classtable();

return op_array;
} /* }}} */

/* {{{ */
static inline zend_op_array *pthreads_compile_string(zval *source_string, char *filename) {
zend_op_array *op_array;

if (zend_compile_string_hook) {
op_array = zend_compile_string_hook(source_string, filename);
} else op_array = compile_string(source_string, filename);

pthreads_loop_postcompile_classtable();

return op_array;
} /* }}} */

/* {{{ */
static inline zend_bool pthreads_verify_type(zend_execute_data *execute_data, zval *var, zend_arg_info *info) {
if (!ZEND_TYPE_IS_SET(info->type)) {
Expand Down Expand Up @@ -263,6 +314,12 @@ PHP_MINIT_FUNCTION(pthreads)
zend_execute_ex_hook = zend_execute_ex;
zend_execute_ex = pthreads_execute_ex;

zend_compile_file_hook = zend_compile_file;
zend_compile_file = pthreads_compile_file;

zend_compile_string_hook = zend_compile_string;
zend_compile_string = pthreads_compile_string;

REGISTER_LONG_CONSTANT("PTHREADS_INHERIT_ALL", PTHREADS_INHERIT_ALL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PTHREADS_INHERIT_NONE", PTHREADS_INHERIT_NONE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PTHREADS_INHERIT_INI", PTHREADS_INHERIT_INI, CONST_CS | CONST_PERSISTENT);
Expand All @@ -288,6 +345,10 @@ PHP_MINIT_FUNCTION(pthreads)
INIT_CLASS_ENTRY(ce, "Volatile", NULL);
pthreads_volatile_entry = zend_register_internal_class_ex(&ce, pthreads_threaded_entry);

INIT_CLASS_ENTRY(ce, "Concurrent", NULL);
pthreads_concurrent_entry = zend_register_internal_class_ex(&ce, pthreads_threaded_entry);
pthreads_concurrent_entry->create_object = pthreads_concurrent_ctor;

INIT_CLASS_ENTRY(ce, "Thread", pthreads_thread_methods);
pthreads_thread_entry=zend_register_internal_class_ex(&ce, pthreads_threaded_entry);
pthreads_thread_entry->create_object = pthreads_thread_ctor;
Expand Down Expand Up @@ -793,6 +854,20 @@ PHP_MINIT_FUNCTION(pthreads)
pthreads_socket_handlers.has_dimension = pthreads_has_dimension_disallow;
pthreads_socket_handlers.unset_dimension = pthreads_unset_dimension_disallow;

memcpy(&pthreads_concurrent_handlers, &pthreads_handlers, sizeof(zend_object_handlers));

pthreads_concurrent_handlers.get_debug_info = pthreads_concurrent_get_debug_info;

pthreads_concurrent_handlers.read_property = pthreads_concurrent_read_property;
pthreads_concurrent_handlers.write_property = pthreads_concurrent_write_property;
pthreads_concurrent_handlers.has_property = pthreads_concurrent_has_property;
pthreads_concurrent_handlers.unset_property = pthreads_concurrent_unset_property;

pthreads_concurrent_handlers.read_dimension = zend_handlers->read_dimension;
pthreads_concurrent_handlers.write_dimension = zend_handlers->write_dimension;
pthreads_concurrent_handlers.has_dimension = zend_handlers->has_dimension;
pthreads_concurrent_handlers.unset_dimension = zend_handlers->unset_dimension;

ZEND_INIT_MODULE_GLOBALS(pthreads, pthreads_globals_ctor, NULL);

if (pthreads_globals_init()) {
Expand Down
19 changes: 16 additions & 3 deletions src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ extern int pthreads_connect(pthreads_object_t* source, pthreads_object_t* destin
zend_bool pthreads_globals_init(){
if (!PTHREADS_G(init)&&!PTHREADS_G(failed)) {
PTHREADS_G(init)=1;
if (!(PTHREADS_G(monitor)=pthreads_monitor_alloc()))
if (!(PTHREADS_G(monitor)=pthreads_monitor_alloc())
|| !(PTHREADS_G(compile_hook_monitor)=pthreads_monitor_alloc()))
PTHREADS_G(failed)=1;
if (PTHREADS_G(failed)) {
PTHREADS_G(init)=0;
} else {
zend_hash_init(
&PTHREADS_G(objects), 64, NULL, (dtor_func_t) NULL, 1);
zend_hash_init(&PTHREADS_G(objects), 64, NULL, (dtor_func_t) NULL, 1);
zend_hash_init(&PTHREADS_G(postcompile), 15, NULL, (dtor_func_t) NULL, 1);
zend_hash_init(&PTHREADS_G(default_static_props), 15, NULL, (dtor_func_t) NULL, 1);
}

#if PHP_VERSION_ID >= 70300
Expand Down Expand Up @@ -83,6 +85,16 @@ void pthreads_globals_unlock() {
pthreads_monitor_unlock(PTHREADS_G(monitor));
} /* }}} */

/* {{{ */
zend_bool pthreads_compile_hook_lock(){
return pthreads_monitor_lock(PTHREADS_G(compile_hook_monitor));
} /* }}} */

/* {{{ */
void pthreads_compile_hook_unlock() {
pthreads_monitor_unlock(PTHREADS_G(compile_hook_monitor));
} /* }}} */

/* {{{ */
void* pthreads_globals_object_alloc(size_t length) {
void *bucket = (void*) ecalloc(1, length);
Expand Down Expand Up @@ -174,6 +186,7 @@ void pthreads_globals_shutdown() {
PTHREADS_G(failed)=0;
/* we allow proc shutdown to destroy tables, and global strings */
pthreads_monitor_free(PTHREADS_G(monitor));
pthreads_monitor_free(PTHREADS_G(compile_hook_monitor));
}
} /* }}} */
#endif
21 changes: 21 additions & 0 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,22 @@ struct _pthreads_globals {
* Objects Cache
*/
HashTable objects;

/**
* Global class table
*/
HashTable postcompile;

/*
* Global compile hook Monitor
*/
pthreads_monitor_t *compile_hook_monitor;

/*
* Default static props cache
*/
HashTable default_static_props;

/*
* High Frequency Strings
*/
Expand Down Expand Up @@ -88,6 +103,12 @@ zend_bool pthreads_globals_lock(); /* }}} */
/* {{{ release global lock */
void pthreads_globals_unlock(); /* }}} */

/* {{{ acquire compile hook lock */
zend_bool pthreads_compile_hook_lock(); /* }}} */

/* {{{ release compile hook lock */
void pthreads_compile_hook_unlock(); /* }}} */

/* {{{ copy string to globals */
char *pthreads_global_string(char *strkey, int32_t keylen, zend_bool lower); /* }}} */

Expand Down
Loading