static void php_swoole_aio_onDNSCompleted(swAio_event *event) { int64_t ret; zval *retval = NULL, *zcallback = NULL; zval **args[2]; dns_request *dns_req = NULL; zval _zcontent; dns_req = (dns_request *) event->req; zcallback = dns_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); } args[0] = &dns_req->domain; zval *zcontent = &_zcontent; if (ret < 0) { SW_ZVAL_STRING(zcontent, "", 1); } else { SW_ZVAL_STRING(zcontent, event->buf, 1); } args[1] = &zcontent; if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL) == FAILURE) { swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete handler error"); return; } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR); } 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 (retval) { sw_zval_ptr_dtor(&retval); } }
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 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 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 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_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 php_swoole_aio_onFileCompleted(swAio_event *event) { int isEOF = SW_FALSE; int64_t ret; zval *retval = NULL, *zcallback = NULL, *zwriten = NULL; zval *zcontent = NULL; zval **args[2]; zval _zcontent; zval _zwriten; bzero(&_zcontent, sizeof(zval)); bzero(&_zwriten, sizeof(zval)); file_request *file_req = event->object; 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 (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; zcontent = &_zcontent; if (ret < 0) { SW_ZVAL_STRING(zcontent, "", 1); } else { SW_ZVAL_STRINGL(zcontent, event->buf, ret, 1); } } else if (event->type == SW_AIO_WRITE) { zwriten = &_zwriten; args[0] = &file_req->filename; args[1] = &zwriten; ZVAL_LONG(zwriten, ret); } else { swoole_php_fatal_error(E_WARNING, "swoole_async: onFileCompleted 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->once == 1) { close_file: close(event->fd); php_swoole_file_request_free(file_req); } 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 { php_swoole_file_request_free(file_req); } } 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_onFileCompleted(event); } //continue to read else { swAio_event ev; ev.fd = event->fd; ev.buf = event->buf; ev.type = SW_AIO_READ; ev.nbytes = event->nbytes; ev.offset = file_req->offset; ev.flags = 0; ev.object = file_req; ev.handler = swAio_handler_read; ev.callback = php_swoole_aio_onFileCompleted; int ret = swAio_dispatch(&ev); 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; } } } if (zcontent) { sw_zval_ptr_dtor(&zcontent); } if (zwriten) { sw_zval_ptr_dtor(&zwriten); } if (retval) { sw_zval_ptr_dtor(&retval); } }
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; }
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); } }