예제 #1
0
static int swoole_mysql_onRead(swReactor *reactor, swEvent *event)
{
#if PHP_MAJOR_VERSION < 7
    TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL);
#endif

    mysql_client *client = event->socket->object;
    int sock = event->fd;

    zval *zobject = client->object;
    swString *buffer = client->buffer;
    int ret;

    zval **args[2];

    zval *callback = NULL;
    zval *retval = NULL;
    zval *result = NULL;

    while(1)
    {
        ret = recv(sock, buffer->str + buffer->length, buffer->size - buffer->length, 0);
        if (ret < 0)
        {
            if (errno == EINTR)
            {
                continue;
            }
            else
            {
                switch (swConnection_error(errno))
                {
                case SW_ERROR:
                    swSysError("Read from socket[%d] failed.", event->fd);
                    return SW_ERR;
                case SW_CLOSE:
                    goto close_fd;
                case SW_WAIT:
                    goto parse_response;
                default:
                    return SW_ERR;
                }
            }
        }
        else if (ret == 0)
        {
            close_fd:
            if (client->state == SW_MYSQL_STATE_READ_END)
            {
                goto parse_response;
            }

            sw_zend_call_method_with_0_params(&zobject, swoole_mysql_class_entry_ptr, NULL, "close", &retval);
            if (retval)
            {
                sw_zval_ptr_dtor(&retval);
            }

            if (client->callback)
            {
                args[0] = &zobject;
                args[1] = &result;

                SW_ALLOC_INIT_ZVAL(result);
                ZVAL_BOOL(result, 0);

                callback = client->callback;
                if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 2, args, 0, NULL TSRMLS_CC) != SUCCESS)
                {
                    swoole_php_fatal_error(E_WARNING, "swoole_async_mysql callback[2] handler error.");
                }
                if (result)
                {
                    sw_zval_ptr_dtor(&result);
                }
                sw_zval_ptr_dtor(&callback);
                client->callback = NULL;
                client->state = SW_MYSQL_STATE_QUERY;
                if (retval)
                {
                    sw_zval_ptr_dtor(&retval);
                }
            }

            return SW_OK;
        }
        else
        {
            buffer->length += ret;
            //recv again
            if (buffer->length == buffer->size)
            {
                if (swString_extend(buffer, buffer->size * 2) < 0)
                {
                    swoole_php_fatal_error(E_ERROR, "malloc failed.");
                    reactor->del(SwooleG.main_reactor, event->fd);
                }
                continue;
            }

            parse_response:
            if (mysql_response(client) < 0)
            {
                return SW_OK;
            }

            //remove from eventloop
            reactor->del(reactor, event->fd);

            zend_update_property_long(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("affected_rows"), client->response.affected_rows TSRMLS_CC);
            zend_update_property_long(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("insert_id"), client->response.insert_id TSRMLS_CC);
            client->state = SW_MYSQL_STATE_QUERY;

            args[0] = &zobject;

            //OK
            if (client->response.response_type == 0)
            {
                SW_ALLOC_INIT_ZVAL(result);
                ZVAL_BOOL(result, 1);
            }
            //ERROR
            else if (client->response.response_type == 255)
            {
                SW_ALLOC_INIT_ZVAL(result);
                ZVAL_BOOL(result, 0);

                zend_update_property_string(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("error"), client->response.server_msg TSRMLS_CC);
                zend_update_property_long(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("errno"), client->response.error_code TSRMLS_CC);
            }
            //ResultSet
            else
            {
                result = client->response.result_array;
            }

            args[1] = &result;
            callback = client->callback;
            if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 2, args, 0, NULL TSRMLS_CC) != SUCCESS)
            {
                swoole_php_fatal_error(E_WARNING, "swoole_async_mysql callback[2] handler error.");
                reactor->del(SwooleG.main_reactor, event->fd);
            }

            /* free memory */
            if (retval)
            {
                sw_zval_ptr_dtor(&retval);
            }
            if (result)
            {
                sw_zval_ptr_dtor(&result);
#if PHP_MAJOR_VERSION > 5
                efree(result);
#endif
            }
            //free callback object
            sw_zval_ptr_dtor(&callback);
            //clear buffer
            swString_clear(client->buffer);
            if (client->response.columns)
            {
                efree(client->response.columns);
            }
            if (client->object)
            {
                sw_zval_ptr_dtor(&client->object);
            }
#if PHP_MAJOR_VERSION > 5
            if (client->response.result_array)
            {
                efree(client->response.result_array);
            }
#endif
            bzero(&client->response, sizeof(client->response));
            return SW_OK;
        }
    }
    return SW_OK;
}
예제 #2
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;
}