Example #1
0
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;
}
Example #2
0
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);
}
Example #5
0
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;

}
Example #6
0
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;
}
Example #7
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);
}
Example #13
0
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;
}
Example #15
0
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);
}
Example #20
0
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);
}
Example #21
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);
}
Example #22
0
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);
}
Example #23
0
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;
}
Example #25
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);
#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;
    }
}
Example #26
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);
    }
}
Example #27
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;
#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);
    }
}
Example #28
0
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;
}
Example #29
0
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);
}