static void promise_resolve_context_call(promise_resolve_context_t *context, zval *value) { zval retval; if (!context->self) { if (!ZVAL_IS_NULL(&context->callback)) { skyray_promise_call_handler(&context->callback, value, &retval); zval_ptr_dtor(&retval); } return; } if (!ZVAL_IS_NULL(&context->callback)) { skyray_promise_call_handler(&context->callback, value, &retval); if (!EG(exception)) { skyray_promise_do_resolve(context->self, &retval, 0); } else { ZVAL_OBJ(&retval, EG(exception)); EG(exception) = NULL; skyray_promise_do_reject(context->self, &retval, 0); } } else { skyray_promise_do_resolve(context->self, &context->late->result, 0); } }
static sb4 oci_bind_input_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp) /* {{{ */ { struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx; pdo_oci_bound_param *P = (pdo_oci_bound_param*)param->driver_data; if (!param || !param->parameter) { php_error_docref(NULL, E_WARNING, "param is NULL in oci_bind_input_cb; this should not happen"); return OCI_ERROR; } *indpp = &P->indicator; if (P->thing) { *bufpp = P->thing; *alenp = sizeof(void*); } else if (ZVAL_IS_NULL(param->parameter)) { /* insert a NULL value into the column */ P->indicator = -1; /* NULL */ *bufpp = 0; *alenp = -1; } else if (!P->thing) { /* regular string bind */ convert_to_string(param->parameter); *bufpp = Z_STRVAL_P(param->parameter); *alenp = Z_STRLEN_P(param->parameter); } *piecep = OCI_ONE_PIECE; return OCI_CONTINUE; } /* }}} */
static PHP_METHOD(swoole_process, signal) { zval *callback = NULL; long signo = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &signo, &callback) == FAILURE) { return; } if (!SWOOLE_G(cli)) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "cannot use swoole_process::signal here."); RETURN_FALSE; } if (SwooleGS->start) { if (signo == SIGTERM || signo == SIGALRM) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot use swoole_process::signal in swoole_server."); RETURN_FALSE; } } if (callback == NULL || ZVAL_IS_NULL(callback)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "no callback."); RETURN_FALSE; } char *func_name; if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "function '%s' is not callable", func_name); efree(func_name); RETURN_FALSE; } efree(func_name); sw_zval_add_ref(&callback); signal_callback[signo] = callback; #if PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 4 SwooleG.use_signalfd = 1; #else SwooleG.use_signalfd = 0; #endif php_swoole_check_reactor(); /** * for swSignalfd_setup */ SwooleG.main_reactor->check_signalfd = 1; swSignal_add(signo, php_swoole_onSignal); RETURN_TRUE; }
void skyray_promise_then(skyray_promise_t *self, zval *on_fulfilled, zval *on_rejected, zval *retval) { zval *result, params[2], function_name; if (Z_TYPE(self->result) != IS_UNDEF) { result = skyray_promise_unwrap(self); ZVAL_NULL(¶ms[0]); ZVAL_NULL(¶ms[1]); ZVAL_STR(&function_name, intern_str_then); if (on_fulfilled) { ZVAL_COPY_VALUE(¶ms[0], on_fulfilled); } if (on_rejected) { ZVAL_COPY_VALUE(¶ms[1], on_rejected); } call_user_function(NULL, result, &function_name, retval, 2, params); assert(EG(exception) == NULL); } else { object_init_ex(retval, skyray_ce_Promise); skyray_promise_t *promise = skyray_promise_from_obj(Z_OBJ_P(retval)); promise_resolve_context_t *context; if (on_fulfilled != NULL && !ZVAL_IS_NULL(on_fulfilled)) { context = promise_resolve_context_create(promise, on_fulfilled, NULL); } else { context = promise_resolve_context_create(promise, NULL, self); } zend_hash_next_index_insert_ptr(&self->on_fulfilled, context); if (on_rejected != NULL && !ZVAL_IS_NULL(on_rejected)) { context = promise_resolve_context_create(promise, on_rejected, NULL); } else { context = promise_resolve_context_create(promise, NULL, self); } zend_hash_next_index_insert_ptr(&self->on_rejcted, context); } }
static sw_inline void client_execute_callback(swClient *cli, enum client_callback_type type) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *callback = NULL; zval *retval = NULL; zval **args[1]; zval *zobject = cli->object; client_callback *cb = swoole_get_property(zobject, 0); char *callback_name; switch(type) { case SW_CLIENT_CALLBACK_onConnect: callback = cb->onConnect; callback_name = "onConnect"; break; case SW_CLIENT_CALLBACK_onError: callback = cb->onError; callback_name = "onError"; break; case SW_CLIENT_CALLBACK_onClose: callback = cb->onClose; callback_name = "onClose"; break; default: return; } if (callback == NULL || ZVAL_IS_NULL(callback)) { swoole_php_fatal_error(E_WARNING, "object have not %s callback.", callback_name); return; } args[0] = &zobject; if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) { swoole_php_fatal_error(E_WARNING, "%s handler error.", callback_name); return; } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval) { sw_zval_ptr_dtor(&retval); } }
void skyray_http_request_resolve_queries_if_needed(skyray_http_request_t *self) { if (!ZVAL_IS_NULL(&self->query_params) || ZVAL_IS_NULL(&self->uri)) { return; } array_init(&self->query_params); php_url *url = php_url_parse_ex(Z_STR(self->uri)->val, Z_STR(self->uri)->len); if (!url->query) { php_url_free(url); return; } zend_string *query = zend_string_init(url->query, strlen(url->query), 0); char *res = estrdup(url->query); sapi_module.treat_data(PARSE_STRING, res, &self->query_params); zend_string_free(query); php_url_free(url); }
void skyray_promise_done(skyray_promise_t *self, zval *on_fulfilled, zval *on_rejected) { zval *result, params[2], function_name, retval; if (Z_TYPE(self->result) != IS_UNDEF) { result = skyray_promise_unwrap(self); ZVAL_NULL(¶ms[0]); ZVAL_NULL(¶ms[1]); ZVAL_STR(&function_name, intern_str_done); if (on_fulfilled) { ZVAL_COPY_VALUE(¶ms[0], on_fulfilled); } if (on_rejected) { ZVAL_COPY_VALUE(¶ms[1], on_rejected); } call_user_function(NULL, result, &function_name, &retval, 2, params); zval_ptr_dtor(&retval); } else { promise_resolve_context_t *context; if (on_fulfilled != NULL && !ZVAL_IS_NULL(on_fulfilled)) { context = promise_resolve_context_create(NULL, on_fulfilled, NULL); zend_hash_next_index_insert_ptr(&self->on_fulfilled, context); } if (on_rejected != NULL && !ZVAL_IS_NULL(on_rejected)) { context = promise_resolve_context_create(NULL, on_rejected, NULL); } else { context = promise_resolve_context_create(NULL, NULL, self); } zend_hash_next_index_insert_ptr(&self->on_rejcted, context); } }
SKYRAY_METHOD(HttpRequest, getUri) { if (zend_parse_parameters_none() == FAILURE) { return; } skyray_http_request_t *intern = skyray_http_request_from_obj(Z_OBJ_P(getThis())); if (ZVAL_IS_NULL(&intern->uri)) { RETURN_STRING("/"); } else { RETURN_ZVAL(&intern->uri, 1, 0); } }
SKYRAY_METHOD(HttpRequest, getCookieParams) { if (zend_parse_parameters_none() == FAILURE) { return; } skyray_http_request_t *intern = skyray_http_request_from_obj(Z_OBJ_P(getThis())); skyray_http_request_resolve_cookies_if_needed(intern); if (ZVAL_IS_NULL(&intern->cookie_params)) { RETURN_EMPTY_ARR(); } else { RETURN_ZVAL(&intern->cookie_params, 1, 0); } }
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 skyray_http_request_resolve_cookies_if_needed(skyray_http_request_t *self) { if (!ZVAL_IS_NULL(&self->cookie_params)) { return; } zval *lines = skyray_http_message_get_header(&self->message, intern_str_cookie, 0); if (!lines) { return; } array_init(&self->cookie_params); zend_array *ht = Z_ARR_P(lines); zend_array *ht2; zval tmp, *data;; zend_hash_internal_pointer_reset(ht); while(zend_hash_has_more_elements(ht) == SUCCESS) { array_init(&tmp); data = zend_hash_get_current_data(ht); php_explode(intern_str_param_delimiter, Z_STR_P(data), &tmp, ZEND_LONG_MAX); ht2 = Z_ARR_P(&tmp); zend_hash_internal_pointer_reset(ht2); while (zend_hash_has_more_elements(ht2) == SUCCESS) { data = zend_hash_get_current_data(ht2); char *c = strchr(Z_STR_P(data)->val, '='); int len = c - Z_STR_P(data)->val; add_assoc_str_ex(&self->cookie_params, Z_STR_P(data)->val, len, zend_string_init(c + 1, Z_STR_P(data)->len - len - 1, 0)); zend_hash_move_forward(ht2); } zval_ptr_dtor(&tmp); zend_hash_move_forward(ht); } }
PHP_METHOD(midgard_connection, get_instance) { zval *instance; if (zend_parse_parameters_none() == FAILURE) { return; } instance = zend_read_static_property(php_midgard_connection_class, "instance", sizeof("instance")-1, 1 TSRMLS_CC); if (instance == NULL || ZVAL_IS_NULL(instance)) { /* instance is not found. we need to create it */ zval_ptr_dtor(&instance); MAKE_STD_ZVAL(instance); object_init_ex(instance, php_midgard_connection_class); zend_call_method_with_0_params(&instance, php_midgard_connection_class, &php_midgard_connection_class->constructor, "__construct", NULL); MGDG(connection_established) = TRUE; } zval_add_ref(&instance); RETURN_ZVAL(instance, 1, 1); }
void php_couchbase_get_resource(INTERNAL_FUNCTION_PARAMETERS, zval *zvres, int argflags, int *ec, php_couchbase_res **pres) { *ec = PHP_COUCHBASE_RES_ERETURN; *pres = NULL; if (argflags & PHP_COUCHBASE_ARG_F_OO) { zvres = zend_read_property(couchbase_ce, getThis(), ZEND_STRL(COUCHBASE_PROPERTY_HANDLE), 1 TSRMLS_CC); if (ZVAL_IS_NULL(zvres) || IS_RESOURCE != Z_TYPE_P(zvres)) { *ec = PHP_COUCHBASE_RES_EINVAL; return; } } ZEND_FETCH_RESOURCE2(*pres, php_couchbase_res *, &zvres, -1, PHP_COUCHBASE_RESOURCE, le_couchbase, le_pcouchbase); if ((argflags & PHP_COUCHBASE_ARG_F_NOCONN) == 0 && (*pres)->is_connected == 0) { *ec = PHP_COUCHBASE_RES_ENOTCONN; return; } if ((argflags & PHP_COUCHBASE_ARG_F_ASYNC) == 0 && (*pres)->async) { *ec = PHP_COUCHBASE_RES_EBUSY; return; } *ec = PHP_COUCHBASE_RES_OK; }
static PHP_METHOD(swoole_process, signal) { zval *callback = NULL; long signo = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &signo, &callback) == FAILURE) { return; } if (!SWOOLE_G(cli)) { swoole_php_fatal_error(E_ERROR, "cannot use swoole_process::signal here."); RETURN_FALSE; } if (SwooleGS->start && (swIsWorker() || swIsMaster() || swIsManager() || swIsTaskWorker())) { if (signo == SIGTERM || signo == SIGALRM) { swoole_php_fatal_error(E_WARNING, "cannot use swoole_process::signal in swoole_server."); RETURN_FALSE; } } if (callback == NULL || ZVAL_IS_NULL(callback)) { callback = signal_callback[signo]; if (callback) { sw_zval_ptr_dtor(&callback); swSignal_add(signo, NULL); RETURN_TRUE; } else { swoole_php_error(E_WARNING, "no callback."); RETURN_FALSE; } } char *func_name; if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) { swoole_php_error(E_WARNING, "function '%s' is not callable", func_name); efree(func_name); RETURN_FALSE; } efree(func_name); #if PHP_MAJOR_VERSION >= 7 zval *tmp = emalloc(sizeof(zval)); memcpy(tmp, callback, sizeof(zval)); callback = tmp; #endif sw_zval_add_ref(&callback); if (signal_callback[signo]) { sw_zval_ptr_dtor(&callback); } signal_callback[signo] = callback; #if PHP_MAJOR_VERSION >= 7 || (PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 4) SwooleG.use_signalfd = 1; #else SwooleG.use_signalfd = 0; #endif php_swoole_check_reactor(); /** * for swSignalfd_setup */ SwooleG.main_reactor->check_signalfd = 1; swSignal_add(signo, php_swoole_onSignal); RETURN_TRUE; }
static int http2_client_build_header(zval *zobject, zval *req, char *buffer, int buffer_len TSRMLS_DC) { char *date_str = NULL; int ret; int index = 0; int find_host = 0; zval *cookies = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("cookies"), 1 TSRMLS_CC); zval *method = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("method"), 1 TSRMLS_CC); zval *path = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("path"), 1 TSRMLS_CC); zval *headers = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("headers"), 1 TSRMLS_CC); nghttp2_nv nv[1024]; http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_CORO_PROPERTY); if (ZVAL_IS_NULL(method) || Z_TYPE_P(method) != IS_STRING || Z_STRLEN_P(method) == 0) { http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("GET")); } else { http2_add_header(&nv[index++], ZEND_STRL(":method"), Z_STRVAL_P(method), Z_STRLEN_P(method)); } if (ZVAL_IS_NULL(path) || Z_TYPE_P(path) != IS_STRING || Z_STRLEN_P(path) == 0) { http2_add_header(&nv[index++], ZEND_STRL(":path"), "/", 1); } else { http2_add_header(&nv[index++], ZEND_STRL(":path"), Z_STRVAL_P(path), Z_STRLEN_P(path)); } if (hcc->ssl) { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("https")); } else { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("http")); } //Host index++; if (headers && !ZVAL_IS_NULL(headers)) { HashTable *ht = Z_ARRVAL_P(headers); zval *value = NULL; char *key = NULL; uint32_t keylen = 0; int type; SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) { if (!key) { break; } if (*key == ':') { continue; } if (strncasecmp("Host", key, keylen) == 0) { http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value)); find_host = 1; } else { http2_add_header(&nv[index++], key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); } } SW_HASHTABLE_FOREACH_END(); (void)type; }
static PHP_METHOD(swoole_redis, __construct) { zval *zset = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &zset) == FAILURE) { return; } swRedisClient *redis = emalloc(sizeof(swRedisClient)); bzero(redis, sizeof(swRedisClient)); redis->object = getThis(); redis->timeout = SW_REDIS_CONNECT_TIMEOUT; redis->database = -1; if (zset && !ZVAL_IS_NULL(zset)) { php_swoole_array_separate(zset); zend_update_property(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("setting"), zset TSRMLS_CC); sw_zval_ptr_dtor(&zset); HashTable *vht; zval *ztmp; vht = Z_ARRVAL_P(zset); /** * timeout */ if (php_swoole_array_get_value(vht, "timeout", ztmp)) { convert_to_double(ztmp); redis->timeout = (double) Z_DVAL_P(ztmp); } /** * password */ if (php_swoole_array_get_value(vht, "password", ztmp)) { convert_to_string(ztmp); if (Z_STRLEN_P(ztmp) >= 1 << 8) { swoole_php_fatal_error(E_WARNING, "redis password is too long."); } else if (Z_STRLEN_P(ztmp) > 0) { redis->password = estrdup(Z_STRVAL_P(ztmp)); redis->password_len = Z_STRLEN_P(ztmp); } } /** * database */ if (php_swoole_array_get_value(vht, "database", ztmp)) { convert_to_long(ztmp); if (Z_LVAL_P(ztmp) > 1 << 8) { swoole_php_fatal_error(E_WARNING, "redis database number is too big."); } else { redis->database = (int8_t) Z_LVAL_P(ztmp); } } } sw_copy_to_stack(redis->object, redis->_object); swoole_set_object(getThis(), redis); }
static int http2_client_build_header(zval *zobject, http2_client_request *req, char *buffer, int buffer_len TSRMLS_DC) { char *date_str = NULL; int ret; zval *zheader = sw_zend_read_property(swoole_http2_client_class_entry_ptr, zobject, ZEND_STRL("requestHeaders"), 1 TSRMLS_CC); int index = 0; int find_host = 0; nghttp2_nv nv[1024]; http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_PROPERTY_INDEX); if (req->type == HTTP_GET) { http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("GET")); } else { http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("POST")); } http2_add_header(&nv[index++], ZEND_STRL(":path"), req->uri, req->uri_len); if (hcc->ssl) { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("https")); } else { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("http")); } //Host index++; if (zheader && !ZVAL_IS_NULL(zheader)) { HashTable *ht = Z_ARRVAL_P(zheader); zval *value = NULL; char *key = NULL; uint32_t keylen = 0; int type; SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) { if (!key) { break; } if (*key == ':') { continue; } if (strncasecmp("Host", key, keylen) == 0) { http2_add_header(&nv[3], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value)); find_host = 1; } else { http2_add_header(&nv[index++], key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); } } SW_HASHTABLE_FOREACH_END(); (void)type; }
static int http_client_coro_execute(zval *zobject, char *uri, zend_size_t uri_len TSRMLS_DC) { if (uri_len <= 0) { swoole_php_fatal_error(E_WARNING, "path is empty."); return SW_ERR; } http_client *http = swoole_get_object(zobject); //http is not null when keeping alive if (http) { //http not ready if (http->state != HTTP_CLIENT_STATE_READY) { //swWarn("fd=%d, state=%d, active=%d, keep_alive=%d", http->cli->socket->fd, http->state, http->cli->socket->active, http->keep_alive); swoole_php_fatal_error(E_WARNING, "Operation now in progress phase %d.", http->state); return SW_ERR; } else if (!http->cli->socket->active) { swoole_php_fatal_error(E_WARNING, "connection#%d is closed.", http->cli->socket->fd); return SW_ERR; } } else { php_swoole_check_reactor(); http = http_client_create(zobject TSRMLS_CC); } if (http == NULL) { return SW_ERR; } if (http->body == NULL) { http->body = swString_new(SW_HTTP_RESPONSE_INIT_SIZE); if (http->body == NULL) { swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); return SW_ERR; } } else { swString_clear(http->body); } if (http->uri) { efree(http->uri); } http->uri = estrdup(uri); http->uri_len = uri_len; //if connection exists if (http->cli) { http_client_coro_send_http_request(zobject TSRMLS_CC); return SW_OK; } swClient *cli = php_swoole_client_new(zobject, http->host, http->host_len, http->port); if (cli == NULL) { return SW_ERR; } http->cli = cli; zval *ztmp; HashTable *vht; zval *zset = sw_zend_read_property(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("setting"), 1 TSRMLS_CC); if (zset && !ZVAL_IS_NULL(zset)) { vht = Z_ARRVAL_P(zset); /** * timeout */ if (php_swoole_array_get_value(vht, "timeout", ztmp)) { convert_to_double(ztmp); http->timeout = (double) Z_DVAL_P(ztmp); } /** * keep_alive */ if (php_swoole_array_get_value(vht, "keep_alive", ztmp)) { convert_to_boolean(ztmp); http->keep_alive = (int) Z_LVAL_P(ztmp); } //client settings php_swoole_client_check_setting(http->cli, zset TSRMLS_CC); } if (cli->socket->active == 1) { swoole_php_fatal_error(E_WARNING, "swoole_http_client is already connected."); return SW_ERR; } #if PHP_MAJOR_VERSION < 7 sw_zval_add_ref(&zobject); #endif cli->object = zobject; //sw_copy_to_stack(cli->object, hcc->_object); cli->open_eof_check = 0; cli->open_length_check = 0; cli->reactor_fdtype = PHP_SWOOLE_FD_STREAM_CLIENT; cli->onReceive = http_client_coro_onReceive; cli->onConnect = http_client_coro_onConnect; cli->onClose = http_client_coro_onClose; cli->onError = http_client_coro_onError; return cli->connect(cli, http->host, http->port, http->timeout, 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_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); } }