int swoole_websocket_onMessage(swEventData *req) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif int fd = req->info.fd; zval *zdata; SW_MAKE_STD_ZVAL(zdata); zdata = php_swoole_get_recv_data(zdata, req TSRMLS_CC); char *buf = Z_STRVAL_P(zdata); long finish = buf[0] ? 1 : 0; long opcode = buf[1] ? 1 : 0; zval *zframe; SW_MAKE_STD_ZVAL(zframe); object_init_ex(zframe, swoole_websocket_frame_class_entry_ptr); zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("fd"), fd TSRMLS_CC); zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("finish"), finish TSRMLS_CC); zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("opcode"), opcode TSRMLS_CC); zend_update_property_stringl(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("data"), buf + 2, (Z_STRLEN_P(zdata) - 2) TSRMLS_CC); swServer *serv = SwooleG.serv; zval *zserv = (zval *) serv->ptr2; zval **args[2]; args[0] = &zserv; args[1] = &zframe; zval *retval = NULL; if (sw_call_user_function_ex(EG(function_table), NULL, websocket_callbacks[WEBSOCKET_CALLBACK_onMessage], &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "onMessage handler error"); } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&zdata); sw_zval_ptr_dtor(&zframe); return SW_OK; }
static void php_swoole_onTimerInterval(swTimer *timer, swTimer_node *event) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *retval = NULL; zval **args[2]; int argc = 1; zval *ztimer_id; swTimer_callback *cb = event->data; //server->addtimer if (cb == NULL && SwooleG.serv) { SwooleG.serv->onTimer(SwooleG.serv, event->interval); return; } if (cb->type == SW_TIMER_TICK) { SW_MAKE_STD_ZVAL(ztimer_id); ZVAL_LONG(ztimer_id, event->id); if (cb->data) { argc = 2; sw_zval_add_ref(&cb->data); args[1] = &cb->data; } } else { SW_MAKE_STD_ZVAL(ztimer_id); ZVAL_LONG(ztimer_id, event->interval); } args[0] = &ztimer_id; if (sw_call_user_function_ex(EG(function_table), NULL, cb->callback, &retval, argc, args, 0, NULL TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_timer: onTimerCallback handler error"); return; } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&ztimer_id); }
int swoole_websocket_onMessage(swEventData *req) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif int fd = req->info.fd; zval *zdata; SW_MAKE_STD_ZVAL(zdata); char frame_header[2]; php_swoole_get_recv_data(zdata, req, frame_header, 2); long finish = frame_header[0] ? 1 : 0; long opcode = frame_header[1]; zval *zframe; SW_MAKE_STD_ZVAL(zframe); object_init_ex(zframe, swoole_websocket_frame_class_entry_ptr); zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("fd"), fd TSRMLS_CC); zend_update_property_bool(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("finish"), finish TSRMLS_CC); zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("opcode"), opcode TSRMLS_CC); zend_update_property(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("data"), zdata TSRMLS_CC); swServer *serv = SwooleG.serv; zval *zserv = (zval *) serv->ptr2; zval **args[2]; args[0] = &zserv; args[1] = &zframe; zval *retval = NULL; zval *zcallback = php_swoole_server_get_callback(serv, req->info.from_fd, SW_SERVER_CB_onMessage); if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "onMessage handler error"); } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&zdata); sw_zval_ptr_dtor(&zframe); return SW_OK; }
static void aio_onReadFileCompleted(swAio_event *event) { zval *retval = NULL; zval *result = NULL; SW_MAKE_STD_ZVAL(result); if (event->ret < 0) { ZVAL_BOOL(result, 0); } else { ZVAL_STRINGL(result, event->buf, event->ret); sw_free(event->buf); } php_context *context = (php_context *) event->object; int ret = coro_resume(context, result, &retval); if (ret == CORO_END && retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); efree(event->req); efree(context); }
static void php_swoole_dns_timeout_coro(swTimer *timer, swTimer_node *tnode) { zval *retval = NULL; zval *zaddress; php_context *cxt = (php_context *) tnode->data; dns_request *req = (dns_request *) cxt->coro_params.value.ptr; SW_MAKE_STD_ZVAL(zaddress); dns_cache *cache = swHashMap_find(request_cache_map, Z_STRVAL_P(req->domain), Z_STRLEN_P(req->domain)); if (cache != NULL && cache->update_time > (int64_t) swTimer_get_now_msec) { SW_ZVAL_STRINGL(zaddress, (*cache->zaddress).str, (*cache->zaddress).length, 1); } else { SW_ZVAL_STRING(zaddress, "", 1); } int ret = coro_resume(req->context, zaddress, &retval); if (ret > 0) { goto free_zdata; } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } free_zdata: sw_zval_ptr_dtor(&zaddress); efree(req->context); req->useless = 1; }
static sw_inline void redis_execute_connect_callback(swRedisClient *redis, int success TSRMLS_DC) { zval *result, *retval; SW_MAKE_STD_ZVAL(result); ZVAL_BOOL(result, success); zval **args[2]; zval *zcallback = sw_zend_read_property(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("onConnect"), 0 TSRMLS_CC); args[0] = &redis->object; args[1] = &result; redis->connecting = 1; if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) != SUCCESS) { swoole_php_fatal_error(E_WARNING, "swoole_async_redis connect_callback handler error."); } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); redis->connecting = 0; }
/** * safe signal */ static void php_swoole_onSignal(int signo) { zval *retval; zval **args[1]; zval *callback = signal_callback[signo]; #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *zsigno; SW_MAKE_STD_ZVAL(zsigno); ZVAL_LONG(zsigno, signo); args[0] = &zsigno; if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "user_signal handler error"); } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&zsigno); }
static PHP_METHOD(swoole_coroutine_util, resume) { long id; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) { return; } swLinkedList *coros_list = swHashMap_find_int(defer_coros, id); if (coros_list == NULL) { swoole_php_fatal_error(E_WARNING, "Nothing can coroResume."); RETURN_FALSE; } php_context *context = swLinkedList_shift(coros_list); if (context == NULL) { swoole_php_fatal_error(E_WARNING, "Nothing can coroResume."); RETURN_FALSE; } zval *retval = NULL; zval *result; SW_MAKE_STD_ZVAL(result); ZVAL_BOOL(result, 1); int ret = coro_resume(context, result, &retval); if (ret == CORO_END && retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); efree(context); RETURN_TRUE; }
static void coro_dns_onResolveCompleted(swAio_event *event) { php_context *context = event->object; zval *retval = NULL; zval *result = NULL; SW_MAKE_STD_ZVAL(result); if (event->error == 0) { SW_ZVAL_STRING(result, event->buf, 1); } else { SwooleG.error = event->error; ZVAL_BOOL(result, 0); } int ret = coro_resume(context, result, &retval); if (ret == CORO_END && retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); efree(event->buf); efree(context); }
static void coro_dns_onGetaddrinfoCompleted(swAio_event *event) { php_context *context = event->object; zval *retval = NULL; zval *result = NULL; SW_MAKE_STD_ZVAL(result); struct sockaddr_in *addr_v4; struct sockaddr_in6 *addr_v6; swRequest_getaddrinfo *req = event->req; if (req->error == 0) { array_init(result); int i; char tmp[INET6_ADDRSTRLEN]; const char *r ; for (i = 0; i < req->count; i++) { if (req->family == AF_INET) { addr_v4 = req->result + (i * sizeof(struct sockaddr_in)); r = inet_ntop(AF_INET, (const void*) &addr_v4->sin_addr, tmp, sizeof(tmp)); } else { addr_v6 = req->result + (i * sizeof(struct sockaddr_in6)); r = inet_ntop(AF_INET6, (const void*) &addr_v6->sin6_addr, tmp, sizeof(tmp)); } if (r) { add_next_index_string(result, tmp); } } } else { ZVAL_BOOL(result, 0); SwooleG.error = req->error; } int ret = coro_resume(context, result, &retval); if (ret == CORO_END && retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); efree(req->hostname); efree(req->result); if (req->service) { efree(req->service); } efree(req); efree(context); }
static void aio_onStreamGetLineCompleted(swAio_event *event) { zval *retval = NULL; zval *result = NULL; SW_MAKE_STD_ZVAL(result); if (event->error == 0) { SW_ZVAL_STRINGL(result, event->buf, event->ret, 1); } else { SwooleG.error = event->error; ZVAL_BOOL(result, 0); } php_context *context = (php_context *) event->object; php_stream *stream; php_stream_from_zval_no_verify(stream, &context->coro_params); stream->readpos = event->offset; stream->writepos = (long) event->req; if (event->flags & SW_AIO_EOF) { stream->eof = 1; } int ret = coro_resume(context, result, &retval); if (ret == CORO_END && retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); efree(context); }
static void aio_onWriteFileCompleted(swAio_event *event) { zval *retval = NULL; zval *result = NULL; SW_MAKE_STD_ZVAL(result); if (event->ret < 0) { SwooleG.error = event->error; ZVAL_BOOL(result, 0); } else { ZVAL_LONG(result, event->ret); } php_context *context = (php_context *) event->object; int ret = coro_resume(context, result, &retval); if (ret == CORO_END && retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); efree(event->req); efree(context); }
static PHP_METHOD(swoole_buffer, __construct) { long size = SW_STRING_BUFFER_DEFAULT; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &size) == FAILURE) { RETURN_FALSE; } if (size < 1) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "buffer size cannot be less than 0"); RETURN_FALSE; } else if (size > SW_STRING_BUFFER_MAXLEN) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "buffer size must not exceed %d", SW_STRING_BUFFER_MAXLEN); RETURN_FALSE; } zval *zres; SW_MAKE_STD_ZVAL(zres,0); swString *buffer = swString_new(size); if (buffer == NULL) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "malloc(%ld) failed.", size); RETURN_FALSE; } swoole_set_object(getThis(), buffer); zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("capacity"), size TSRMLS_CC); }
static PHP_METHOD(swoole_http2_client, __construct) { char *host; zend_size_t host_len; long port = 80; zend_bool ssl = SW_FALSE; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &host, &host_len, &port, &ssl) == FAILURE) { return; } if (host_len <= 0) { zend_throw_exception(swoole_exception_class_entry_ptr, "host is empty.", SW_ERROR_INVALID_PARAMS TSRMLS_CC); RETURN_FALSE; } http2_client_property *hcc; hcc = (http2_client_property*) emalloc(sizeof(http2_client_property)); bzero(hcc, sizeof(http2_client_property)); swoole_set_property(getThis(), HTTP2_CLIENT_PROPERTY_INDEX, hcc); hcc->requests = swLinkedList_new(0, http2_client_request_free); hcc->stream_requests = swLinkedList_new(0, http2_client_request_free); hcc->streams = swHashMap_new(8, http2_client_stream_free); hcc->stream_id = 1; zval *ztype; SW_MAKE_STD_ZVAL(ztype); long type = SW_FLAG_ASYNC | SW_SOCK_TCP; if (ssl) { type |= SW_SOCK_SSL; hcc->ssl = 1; } ZVAL_LONG(ztype, type); zval *zobject = getThis(); zval *retval = NULL; sw_zend_call_method_with_1_params(&zobject, swoole_client_class_entry_ptr, NULL, "__construct", &retval, ztype); if (retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&ztype); hcc->host = estrndup(host, host_len); hcc->host_len = host_len; hcc->port = port; }
static void php_swoole_dns_callback(char *domain, swDNSResolver_result *result, void *data) { SWOOLE_GET_TSRMLS; dns_request *req = data; zval *retval = NULL; zval *zaddress; zval **args[2]; char *address; SW_MAKE_STD_ZVAL(zaddress); if (result->num > 0) { if (SwooleG.dns_lookup_random) { address = result->hosts[rand() % result->num].address; } else { address = result->hosts[0].address; } SW_ZVAL_STRING(zaddress, address, 1); } else { SW_ZVAL_STRING(zaddress, "", 1); } args[0] = &req->domain; args[1] = &zaddress; zval *zcallback = req->callback; if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { swoole_php_fatal_error(E_WARNING, "swoole_asyns_dns_lookup handler error."); return; } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } sw_zval_ptr_dtor(&req->callback); sw_zval_ptr_dtor(&req->domain); efree(req); if (retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&zaddress); }
static void swoole_coroutine_util_resume(void *data) { php_context *context = (php_context *)data; zval *retval = NULL; zval *result; SW_MAKE_STD_ZVAL(result); ZVAL_BOOL(result, 1); int ret = coro_resume(context, result, &retval); if (ret == CORO_END && retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); efree(context); }
static void php_coroutine_sleep_timeout(swTimer *timer, swTimer_node *tnode) { zval *retval = NULL; zval *result = NULL; SW_MAKE_STD_ZVAL(result); ZVAL_BOOL(result, 1); php_context *context = (php_context *) tnode->data; int ret = coro_resume(context, result, &retval); if (ret == CORO_END && retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); efree(context); }
/** * @zobject: swoole_http_client object */ static void http_client_coro_onError(swClient *cli) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *zdata; zval *retval = NULL; SW_MAKE_STD_ZVAL(zdata); //return false ZVAL_BOOL(zdata, 0); zval *zobject = cli->object; php_context *sw_current_context = swoole_get_property(zobject, 1); zend_update_property_long(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("errCode"), SwooleG.error TSRMLS_CC); if (cli->timeout_id > 0) { php_swoole_clear_timer_coro(cli->timeout_id TSRMLS_CC); cli->timeout_id=0; } if (!cli->released) { http_client_free(zobject TSRMLS_CC); } swoole_set_object(zobject, NULL); http_client_property *hcc = swoole_get_property(zobject, 0); if(hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT){ hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; hcc->defer_result = 0; goto free_zdata; } hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; int ret = coro_resume(sw_current_context, zdata, &retval); if (ret > 0) { goto free_zdata; } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } free_zdata: sw_zval_ptr_dtor(&zdata); }
static void http_client_coro_onTimeout(php_context *ctx) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *zdata; zval *retval = NULL; SW_MAKE_STD_ZVAL(zdata); ZVAL_BOOL(zdata, 0); //return false #if PHP_MAJOR_VERSION < 7 zval *zobject = (zval *)ctx->coro_params; #else zval _zobject = ctx->coro_params; zval *zobject = & _zobject; #endif //define time out RETURN ERROR 110 zend_update_property_long(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("errCode"), 110 TSRMLS_CC); http_client *http = swoole_get_object(zobject); http->cli->released = 1; http_client_free(zobject TSRMLS_CC); swoole_set_object(zobject, NULL); http_client_property *hcc = swoole_get_property(zobject, 0); if(hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT){ hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; hcc->defer_result = 0; goto free_zdata; } hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; int ret = coro_resume(ctx, zdata, &retval); if (ret > 0) { goto free_zdata; } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } free_zdata: sw_zval_ptr_dtor(&zdata); }
static void swoole_redis_onResult(redisAsyncContext *c, void *r, void *privdata) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif redisReply *reply = r; if (reply == NULL) { return; } swRedisClient *redis = c->ev.data; zval *result, *retval; SW_MAKE_STD_ZVAL(result); if (reply->str == NULL) { ZVAL_BOOL(result, 0); zend_update_property_long(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errCode"), c->err TSRMLS_CC); zend_update_property_string(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), c->errstr TSRMLS_CC); } else { SW_ZVAL_STRINGL(result, reply->str, reply->len, 1); } redis->state = SWOOLE_REDIS_STATE_READY; zval **args[2]; args[0] = &redis->object; args[1] = &result; if (sw_call_user_function_ex(EG(function_table), NULL, redis->result_callback, &retval, 2, args, 0, NULL TSRMLS_CC) != SUCCESS) { swoole_php_fatal_error(E_WARNING, "swoole_async_mysql callback handler error."); } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); }
static void client_onReceive(swClient *cli, char *data, uint32_t length) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *zobject = cli->object; zval *zcallback = NULL; zval **args[2]; zval *retval; zval *zdata; SW_MAKE_STD_ZVAL(zdata); SW_ZVAL_STRINGL(zdata, data, length, 1); args[0] = &zobject; args[1] = &zdata; client_callback *cb = swoole_get_property(zobject, 0); zcallback = cb->onReceive; if (zcallback == NULL || ZVAL_IS_NULL(zcallback)) { swoole_php_fatal_error(E_WARNING, "swoole_client object have not receive callback."); goto free_zdata; } if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { swoole_php_fatal_error(E_WARNING, "onReactorCallback handler error"); goto free_zdata; } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } free_zdata: sw_zval_ptr_dtor(&zdata); }
void swoole_redis_onConnect(const redisAsyncContext *c, int status) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif swRedisClient *redis = c->ev.data; zval *result, *retval; SW_MAKE_STD_ZVAL(result); if (status != REDIS_OK) { ZVAL_BOOL(result, 0); zend_update_property_long(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errCode"), c->err TSRMLS_CC); zend_update_property_string(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), c->errstr TSRMLS_CC); redis->state = SWOOLE_REDIS_STATE_CLOSED; } else { ZVAL_BOOL(result, 1); redis->state = SWOOLE_REDIS_STATE_READY; } zval **args[2]; args[0] = &redis->object; args[1] = &result; if (sw_call_user_function_ex(EG(function_table), NULL, redis->connect_callback, &retval, 2, args, 0, NULL TSRMLS_CC) != SUCCESS) { swoole_php_fatal_error(E_WARNING, "swoole_async_mysql callback handler error."); } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&result); }
static swVal* swoole_call_php_func(const char *name, int length) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif int i; zval **args[SW_PHP_FUNCTION_MAX_ARG]; zval *zval_array[SW_PHP_FUNCTION_MAX_ARG]; #if PHP_MAJOR_VERSION >= 7 zval _zval_array[SW_PHP_FUNCTION_MAX_ARG]; #endif zval *arg; uint32_t offset = 0; swVal *val; void *params = SwooleG.call_php_func_args->str; for (i = 0; i < SwooleG.call_php_func_argc; i++) { #if PHP_MAJOR_VERSION >= 7 zval_array[i] = &_zval_array[i]; #else SW_ALLOC_INIT_ZVAL(zval_array[i]); #endif arg = zval_array[i]; val = params + offset; if (swVal_to_zval(val, arg) < 0) { return NULL; } args[i] = &zval_array[i]; offset += sizeof(swVal) + val->length; } zval *func_name; zval *retval = NULL; SW_MAKE_STD_ZVAL(func_name); SW_ZVAL_STRING(func_name, name, 1); if (sw_call_user_function_ex(EG(function_table), NULL, func_name, &retval, SwooleG.call_php_func_argc, args, 0, NULL TSRMLS_CC) == FAILURE) { swoole_php_fatal_error(E_WARNING, "swoole_server: onPipeMessage handler error"); return NULL; } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } //clear input buffer swArgs_clear(); for (i = 0; i < SwooleG.call_php_func_argc; i++) { sw_zval_ptr_dtor(&zval_array[i]); } //return value if (!retval) { return NULL; } swVal *val_c = NULL; switch(Z_TYPE_P(retval)) { #if PHP_MAJOR_VERSION < 7 case IS_BOOL: val_c = sw_malloc(sizeof(swVal) + 1); swVal_bool(val_c, Z_BVAL_P(retval)); break; #else case IS_TRUE: val_c = sw_malloc(sizeof(swVal) + 1); swVal_bool(val_c, 1); break; case IS_FALSE: val_c = sw_malloc(sizeof(swVal) + 1); swVal_bool(val_c, 0); break; #endif case IS_STRING: val_c = sw_malloc(sizeof(swVal) + Z_STRLEN_P(retval) + 1); swVal_string(val_c, Z_STRVAL_P(retval) , Z_STRLEN_P(retval)); break; case IS_LONG: val_c = sw_malloc(sizeof(swVal) + sizeof(long)); swVal_long(val_c, Z_LVAL_P(retval)); break; case IS_DOUBLE: val_c = sw_malloc(sizeof(swVal) + sizeof(double)); swVal_double(val_c, Z_DVAL_P(retval)); break; case IS_NULL: return NULL; default: swWarn("unknown type."); break; } sw_zval_ptr_dtor(&retval); return val_c; }
int swoole_websocket_onMessage(swEventData *req) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif int fd = req->info.fd; zval *zdata; SW_MAKE_STD_ZVAL(zdata); char frame_header[2]; php_swoole_get_recv_data(zdata, req, frame_header, 2); long finish = frame_header[0] ? 1 : 0; long opcode = frame_header[1]; zval *zframe; SW_MAKE_STD_ZVAL(zframe); object_init_ex(zframe, swoole_websocket_frame_class_entry_ptr); zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("fd"), fd TSRMLS_CC); zend_update_property_bool(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("finish"), finish TSRMLS_CC); zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("opcode"), opcode TSRMLS_CC); zend_update_property(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("data"), zdata TSRMLS_CC); swServer *serv = SwooleG.serv; zval *zserv = (zval *) serv->ptr2; #ifndef SW_COROUTINE zval **args[2]; args[0] = &zserv; args[1] = &zframe; #else zval *args[2]; args[0] = zserv; args[1] = zframe; #endif zval *retval = NULL; #ifndef SW_COROUTINE zend_fcall_info_cache *fci_cache = php_swoole_server_get_cache(serv, req->info.from_fd, SW_SERVER_CB_onMessage); zval *zcallback = php_swoole_server_get_callback(SwooleG.serv, req->info.from_fd, SW_SERVER_CB_onMessage); if (sw_call_user_function_fast(zcallback, fci_cache, &retval, 2, args TSRMLS_CC) == FAILURE) { swoole_php_error(E_WARNING, "onMessage handler error"); } #else zend_fcall_info_cache *cache = php_swoole_server_get_cache(serv, req->info.from_fd, SW_SERVER_CB_onMessage); int ret = coro_create(cache, args, 2, &retval, NULL, NULL); if (ret != 0) { sw_zval_ptr_dtor(&zdata); sw_zval_ptr_dtor(&zframe); if (ret == CORO_LIMIT) { SwooleG.serv->factory.end(&SwooleG.serv->factory, fd); } return SW_OK; } #endif if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&zdata); sw_zval_ptr_dtor(&zframe); return SW_OK; }
static void php_swoole_aio_onComplete(swAio_event *event) { int isEOF = SW_FALSE; int64_t ret; zval *retval = NULL, *zcallback = NULL, *zwriten = NULL; zval *zcontent = NULL; zval **args[2]; file_request *file_req = NULL; dns_request *dns_req = NULL; #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif if (event->type == SW_AIO_DNS_LOOKUP) { dns_req = (dns_request *) event->req; if (dns_req->callback == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[2]"); return; } zcallback = dns_req->callback; } else { if (sw_zend_hash_find(&php_sw_aio_callback, (char *)&(event->fd), sizeof(event->fd), (void**) &file_req) != SUCCESS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[1]"); return; } if (file_req->callback == NULL && file_req->type == SW_AIO_READ) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[2]"); return; } zcallback = file_req->callback; } ret = event->ret; if (ret < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: Aio Error: %s[%d]", strerror(event->error), event->error); } else if (file_req != NULL) { if (ret == 0) { bzero(event->buf, event->nbytes); isEOF = SW_TRUE; } else if (file_req->once == 1 && ret < file_req->content_length) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: ret_length[%d] < req->length[%d].", (int) ret, file_req->content_length); } else if (event->type == SW_AIO_READ) { file_req->offset += event->ret; } } if (event->type == SW_AIO_READ) { SW_MAKE_STD_ZVAL(zcontent,0); args[0] = &file_req->filename; args[1] = &zcontent; SW_ZVAL_STRINGL(zcontent, event->buf, ret, 0); } else if (event->type == SW_AIO_WRITE) { SW_MAKE_STD_ZVAL(zwriten,0); args[0] = &file_req->filename; args[1] = &zwriten; ZVAL_LONG(zwriten, ret); if (file_req->once != 1) { if (SwooleAIO.mode == SW_AIO_LINUX) { free(event->buf); } else { efree(event->buf); } } } else if(event->type == SW_AIO_DNS_LOOKUP) { SW_MAKE_STD_ZVAL(zcontent,0); args[0] = &dns_req->domain; if (ret < 0) { SW_ZVAL_STRING(zcontent, "", 0); } else { SW_ZVAL_STRING(zcontent, event->buf, 0); } args[1] = &zcontent; } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete unknow event type"); return; } if (zcallback) { if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete handler error"); return; } } //readfile/writefile if (file_req != NULL) { //只操作一次,完成后释放缓存区并关闭文件 if (file_req->once == 1) { close_file: sw_zval_ptr_dtor(&file_req->callback); sw_zval_ptr_dtor(&file_req->filename); if (SwooleAIO.mode == SW_AIO_LINUX) { free(event->buf); } else { efree(event->buf); } close(event->fd); //remove from hashtable sw_zend_hash_del(&php_sw_aio_callback, (char *)&(event->fd), sizeof(event->fd)); } else if(file_req->type == SW_AIO_WRITE) { if (retval != NULL && !Z_BVAL_P(retval)) { swHashMap_del(php_swoole_open_files, Z_STRVAL_P(file_req->filename), Z_STRLEN_P(file_req->filename)); goto close_file; } } else { if (!Z_BVAL_P(retval) || isEOF) { goto close_file; } else if (SwooleAIO.read(event->fd, event->buf, event->nbytes, file_req->offset) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: continue to read failed. Error: %s[%d]", strerror(event->error), event->error); } } } else if (dns_req != NULL) { sw_zval_ptr_dtor(&dns_req->callback); sw_zval_ptr_dtor(&dns_req->domain); efree(dns_req); efree(event->buf); } if (zcontent != NULL) { efree(zcontent); } if (zwriten != NULL) { sw_zval_ptr_dtor(&zwriten); } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } if (SwooleWG.in_client && SwooleG.main_reactor->event_num == 1 && SwooleAIO.task_num == 1) { SwooleG.main_reactor->running = 0; } }
static void php_swoole_aio_onComplete(swAio_event *event) { int isEOF = SW_FALSE; int64_t ret; zval *retval = NULL, *zcallback = NULL, *zwriten = NULL; zval *zcontent = NULL; zval **args[2]; file_request *file_req = NULL; dns_request *dns_req = NULL; #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #else zval _zcontent; zval _zwriten; bzero(&_zcontent, sizeof(zval)); bzero(&_zwriten, sizeof(zval)); #endif if (event->type == SW_AIO_GETHOSTBYNAME) { dns_req = (dns_request *) event->req; if (dns_req->callback == NULL) { swoole_php_error(E_WARNING, "swoole_async: onAsyncComplete callback not found[0]"); return; } zcallback = dns_req->callback; } else { file_req = swHashMap_find_int(php_swoole_aio_request, event->task_id); if (!file_req) { swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete callback not found[1]"); return; } if (file_req->callback == NULL && file_req->type == SW_AIO_READ) { swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete callback not found[2]"); return; } zcallback = file_req->callback; } ret = event->ret; if (ret < 0) { SwooleG.error = event->error; swoole_php_error(E_WARNING, "Aio Error: %s[%d]", strerror(event->error), event->error); } else if (file_req != NULL) { if (ret == 0) { bzero(event->buf, event->nbytes); isEOF = SW_TRUE; } else if (file_req->once == 1 && ret < file_req->length) { swoole_php_fatal_error(E_WARNING, "ret_length[%d] < req->length[%d].", (int ) ret, file_req->length); } else if (event->type == SW_AIO_READ) { file_req->offset += event->ret; } } if (event->type == SW_AIO_READ) { args[0] = &file_req->filename; args[1] = &zcontent; #if PHP_MAJOR_VERSION < 7 SW_MAKE_STD_ZVAL(zcontent); #else zcontent = &_zcontent; #endif if (ret < 0) { SW_ZVAL_STRING(zcontent, "", 1); } else { SW_ZVAL_STRINGL(zcontent, event->buf, ret, 1); } } else if (event->type == SW_AIO_WRITE) { #if PHP_MAJOR_VERSION < 7 SW_MAKE_STD_ZVAL(zwriten); #else zwriten = &_zwriten; #endif args[0] = &file_req->filename; args[1] = &zwriten; ZVAL_LONG(zwriten, ret); } else if(event->type == SW_AIO_GETHOSTBYNAME) { args[0] = &dns_req->domain; #if PHP_MAJOR_VERSION < 7 SW_MAKE_STD_ZVAL(zcontent); #else zcontent = &_zcontent; #endif if (ret < 0) { SW_ZVAL_STRING(zcontent, "", 1); } else { SW_ZVAL_STRING(zcontent, event->buf, 1); } args[1] = &zcontent; } else { swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete unknown event type[%d].", event->type); return; } if (zcallback) { if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete handler error"); return; } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } } //file io if (file_req) { if (file_req->once == 1) { close_file: close(event->fd); swHashMap_del_int(php_swoole_aio_request, event->task_id); } else if(file_req->type == SW_AIO_WRITE) { if (retval != NULL && !ZVAL_IS_NULL(retval) && !Z_BVAL_P(retval)) { swHashMap_del(php_swoole_open_files, Z_STRVAL_P(file_req->filename), Z_STRLEN_P(file_req->filename)); goto close_file; } else { swHashMap_del_int(php_swoole_aio_request, event->task_id); } } else { if ((retval != NULL && !ZVAL_IS_NULL(retval) && !Z_BVAL_P(retval)) || isEOF) { goto close_file; } //Less than expected, at the end of the file else if (event->ret < event->nbytes) { event->ret = 0; php_swoole_aio_onComplete(event); } //continue to read else { int ret = SwooleAIO.read(event->fd, event->buf, event->nbytes, file_req->offset); if (ret < 0) { swoole_php_fatal_error(E_WARNING, "swoole_async: continue to read failed. Error: %s[%d]", strerror(event->error), event->error); goto close_file; } else { swHashMap_move_int(php_swoole_aio_request, event->task_id, ret); } } } } else if (dns_req) { sw_zval_ptr_dtor(&dns_req->callback); sw_zval_ptr_dtor(&dns_req->domain); efree(dns_req); efree(event->buf); } if (zcontent) { sw_zval_ptr_dtor(&zcontent); } if (zwriten) { sw_zval_ptr_dtor(&zwriten); } if (retval) { sw_zval_ptr_dtor(&retval); } }
static void php_swoole_aio_onComplete(swAio_event *event) { int isEOF = SW_FALSE; int64_t ret; zval *retval = NULL, *zcallback = NULL, *zwriten = NULL; zval *zcontent = NULL; zval **args[2]; file_request *file_req = NULL; dns_request *dns_req = NULL; #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #else zval _zcontent; zval _zwriten; #endif if (event->type == SW_AIO_DNS_LOOKUP) { dns_req = (dns_request *) event->req; if (dns_req->callback == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[0]"); return; } zcallback = dns_req->callback; } else { file_req = swHashMap_find_int(php_swoole_aio_request, event->fd); if (!file_req) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[1]"); return; } if (file_req->callback == NULL && file_req->type == SW_AIO_READ) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[2]"); return; } zcallback = file_req->callback; } ret = event->ret; if (ret < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: Aio Error: %s[%d]", strerror(event->error), event->error); } else if (file_req != NULL) { if (ret == 0) { bzero(event->buf, event->nbytes); isEOF = SW_TRUE; } else if (file_req->once == 1 && ret < file_req->content_length) { swoole_php_fatal_error(E_WARNING, "swoole_async: ret_length[%d] < req->length[%d].", (int) ret, file_req->content_length); } else if (event->type == SW_AIO_READ) { file_req->offset += event->ret; } } if (event->type == SW_AIO_READ) { args[0] = &file_req->filename; args[1] = &zcontent; #if PHP_MAJOR_VERSION < 7 SW_MAKE_STD_ZVAL(zcontent); #else zcontent = &_zcontent; #endif memset(event->buf + ret, 0, 1); SW_ZVAL_STRINGL(zcontent, event->buf, ret, 1); } else if (event->type == SW_AIO_WRITE) { #if PHP_MAJOR_VERSION < 7 SW_MAKE_STD_ZVAL(zwriten); #else zwriten = &_zwriten; #endif args[0] = &file_req->filename; args[1] = &zwriten; ZVAL_LONG(zwriten, ret); if (file_req->once != 1) { swoole_aio_free(event->buf); } } else if(event->type == SW_AIO_DNS_LOOKUP) { args[0] = &dns_req->domain; #if PHP_MAJOR_VERSION < 7 SW_MAKE_STD_ZVAL(zcontent); #else zcontent = &_zcontent; #endif if (ret < 0) { SW_ZVAL_STRING(zcontent, "", 1); } else { SW_ZVAL_STRING(zcontent, event->buf, 1); } args[1] = &zcontent; } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete unknow event type"); return; } if (zcallback) { if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete handler error"); return; } } //readfile/writefile if (file_req != NULL) { if (file_req->once == 1) { close_file: sw_zval_ptr_dtor(&file_req->callback); sw_zval_ptr_dtor(&file_req->filename); swoole_aio_free(event->buf); close(event->fd); swHashMap_del_int(php_swoole_aio_request, event->fd); efree(file_req); } else if(file_req->type == SW_AIO_WRITE) { if (retval != NULL && !Z_BVAL_P(retval)) { swHashMap_del(php_swoole_open_files, Z_STRVAL_P(file_req->filename), Z_STRLEN_P(file_req->filename)); goto close_file; } } else { if (!Z_BVAL_P(retval) || isEOF) { goto close_file; } else if (SwooleAIO.read(event->fd, event->buf, event->nbytes, file_req->offset) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: continue to read failed. Error: %s[%d]", strerror(event->error), event->error); } } } else if (dns_req != NULL) { sw_zval_ptr_dtor(&dns_req->callback); sw_zval_ptr_dtor(&dns_req->domain); efree(dns_req); efree(event->buf); } if (zcontent != NULL) { sw_zval_ptr_dtor(&zcontent); } if (zwriten != NULL) { sw_zval_ptr_dtor(&zwriten); } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } }
static int process_stream_onRead(swReactor *reactor, swEvent *event) { SWOOLE_GET_TSRMLS; process_stream *ps = event->socket->object; char *buf = ps->buffer->str + ps->buffer->length; size_t len = ps->buffer->size - ps->buffer->length; int ret = read(event->fd, buf, len); if (ret > 0) { ps->buffer->length += ret; if (ps->buffer->length == ps->buffer->size) { swString_extend(ps->buffer, ps->buffer->size * 2); } return SW_OK; } else if (ret < 0) { swSysError("read() failed."); return SW_OK; } zval *retval = NULL; zval **args[2]; zval *zdata; SW_MAKE_STD_ZVAL(zdata); SW_ZVAL_STRINGL(zdata, ps->buffer->str, ps->buffer->length, 1); SwooleG.main_reactor->del(SwooleG.main_reactor, ps->fd); swString_free(ps->buffer); args[0] = &zdata; int status; zval *zstatus; SW_MAKE_STD_ZVAL(zstatus); pid_t pid = swWaitpid(ps->pid, &status, WNOHANG); if (pid > 0) { array_init(zstatus); add_assoc_long(zstatus, "code", WEXITSTATUS(status)); add_assoc_long(zstatus, "signal", WTERMSIG(status)); } else { ZVAL_FALSE(zstatus); } args[1] = &zstatus; zval *zcallback = ps->callback; if (zcallback) { if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete handler error"); } sw_zval_free(zcallback); } else { #ifdef SW_COROUTINE php_context *context = ps->context; sw_zval_add_ref(&zdata); add_assoc_zval(zstatus, "output", zdata); int ret = coro_resume(context, zstatus, &retval); if (ret == CORO_END && retval) { sw_zval_ptr_dtor(&retval); } efree(context); #else return SW_OK; #endif } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } sw_zval_ptr_dtor(&zdata); sw_zval_ptr_dtor(&zstatus); close(ps->fd); efree(ps); return SW_OK; }
static void php_swoole_dns_callback_coro(char *domain, swDNSResolver_result *result, void *data) { SWOOLE_GET_TSRMLS; dns_request *req = data; zval *retval = NULL; zval *zaddress; char *address; SW_MAKE_STD_ZVAL(zaddress); if (result->num > 0) { if (SwooleG.dns_lookup_random) { address = result->hosts[rand() % result->num].address; } else { address = result->hosts[0].address; } SW_ZVAL_STRING(zaddress, address, 1); } else { SW_ZVAL_STRING(zaddress, "", 1); } //update cache dns_cache *cache = swHashMap_find(request_cache_map, Z_STRVAL_P(req->domain), Z_STRLEN_P(req->domain)); if (cache == NULL ) { cache = emalloc(sizeof(dns_cache)); swHashMap_add(request_cache_map, Z_STRVAL_P(req->domain), Z_STRLEN_P(req->domain), cache); cache->zaddress = swString_new(20); } swString_write_ptr(cache->zaddress, 0, Z_STRVAL_P(zaddress), Z_STRLEN_P(zaddress)); cache->update_time = (int64_t) swTimer_get_now_msec + (int64_t) (SwooleG.dns_cache_refresh_time * 1000); //timeout if (req->timer) { swTimer_del(&SwooleG.timer, req->timer); req->timer = NULL; } if (req->useless) { efree(req); return; } int ret = coro_resume(req->context, zaddress, &retval); if (ret > 0) { goto free_zdata; } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } //说明已经yield走了 free_zdata: // free 上下文 sw_zval_ptr_dtor(&zaddress); efree(req->context); efree(req); }
static void http_client_coro_onReceive(swClient *cli, char *data, uint32_t length) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *zobject = cli->object; zval *retval = NULL; http_client *http = swoole_get_object(zobject); if (!http->cli) { swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client_coro."); return; } //timeout if (cli->timeout_id > 0) { php_swoole_clear_timer_coro(cli->timeout_id TSRMLS_CC); cli->timeout_id=0; } long parsed_n = php_http_parser_execute(&http->parser, &http_parser_settings, data, length); http_client_property *hcc = swoole_get_property(zobject, 0); zval *zdata; SW_MAKE_STD_ZVAL(zdata); if (parsed_n < 0) { //错误情况 标志位 done defer 保存 sw_zend_call_method_with_0_params(&zobject, swoole_http_client_coro_class_entry_ptr, NULL, "close", &retval); if (retval) { sw_zval_ptr_dtor(&retval); } ZVAL_BOOL(zdata, 0); //return false if (hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT) { //not recv yet sava data hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; hcc->defer_result = 0; goto free_zdata; //wait for recv } goto begin_resume; } //not complete if (!http->completed) { return; } // if(!hcc->defer_chunk_status){ //not recv all wait for next // return; // } ZVAL_BOOL(zdata, 1); //return false if (hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT) { //not recv yet sava data hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; hcc->defer_result = 1; goto free_zdata; } begin_resume: { //if should resume /*if next cr*/ php_context *sw_current_context = swoole_get_property(zobject, 1); hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; // hcc->defer_chunk_status = 0; http->completed = 0; int ret = coro_resume(sw_current_context, zdata, &retval); if (ret > 0) { goto free_zdata; } if (retval != NULL) { sw_zval_ptr_dtor(&retval); } } free_zdata: sw_zval_ptr_dtor(&zdata); }