#include "study_coroutine.h" #include using Study::PHPCoroutine; using Study::Coroutine; static std::unordered_map user_yield_coros; ZEND_BEGIN_ARG_INFO_EX(arginfo_study_coroutine_void, 0, 0, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_study_coroutine_resume, 0, 0, 1) ZEND_ARG_INFO(0, cid) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_study_coroutine_isExist, 0, 0, 1) ZEND_ARG_INFO(0, cid) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_study_coroutine_create, 0, 0, 1) ZEND_ARG_CALLABLE_INFO(0, func, 0) ZEND_END_ARG_INFO() static PHP_METHOD(study_coroutine_util, create); PHP_METHOD(study_coroutine_util, create) { zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fcc = empty_fcall_info_cache; ZEND_PARSE_PARAMETERS_START(1, -1) Z_PARAM_FUNC(fci, fcc) Z_PARAM_VARIADIC('*', fci.params, fci.param_count) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); long cid = PHPCoroutine::create(&fcc, fci.param_count, fci.params); RETURN_LONG(cid); } PHP_METHOD(study_coroutine_util, yield) { Coroutine* co = Coroutine::get_current(); user_yield_coros[co->get_cid()] = co; co->yield(); RETURN_TRUE; } PHP_METHOD(study_coroutine_util, resume) { zend_long cid = 0; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_LONG(cid) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); auto coroutine_iterator = user_yield_coros.find(cid); if (coroutine_iterator == user_yield_coros.end()) { php_error_docref(NULL, E_WARNING, "resume error"); RETURN_FALSE; } Coroutine* co = coroutine_iterator->second; user_yield_coros.erase(cid); co->resume(); RETURN_TRUE; } PHP_METHOD(study_coroutine_util, getCid) { Coroutine* co = Coroutine::get_current(); if (co == nullptr) { RETURN_LONG(-1); } RETURN_LONG(co->get_cid()); } PHP_METHOD(study_coroutine_util, isExist) { zend_long cid = 0; bool is_exist; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_LONG(cid) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); auto coroutine_iterator = Coroutine::coroutines.find(cid); is_exist = (coroutine_iterator != Coroutine::coroutines.end()); RETURN_BOOL(is_exist); } static const zend_function_entry study_coroutine_util_methods[] = { PHP_ME(study_coroutine_util, create, arginfo_study_coroutine_create, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(study_coroutine_util, yield, arginfo_study_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(study_coroutine_util, resume, arginfo_study_coroutine_resume, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(study_coroutine_util, getCid, arginfo_study_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(study_coroutine_util, isExist, arginfo_study_coroutine_isExist, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END }; /** * Define zend class entry */ zend_class_entry study_coroutine_ce; zend_class_entry *study_coroutine_ce_ptr; void study_coroutine_util_init() { INIT_NS_CLASS_ENTRY(study_coroutine_ce, "Study", "Coroutine", study_coroutine_util_methods); study_coroutine_ce_ptr = zend_register_internal_class(&study_coroutine_ce TSRMLS_CC); // Registered in the Zend Engine }