示例#1
0
文件: Timer.c 项目: akrick/swoole-src
int swTimer_init(long msec)
{
    if (SwooleGS->start && (swIsMaster() || swIsManager()))
    {
        swWarn("cannot use timer in master and manager process.");
        return SW_ERR;
    }

    if (swReactorTimer_now(&SwooleG.timer.basetime) < 0)
    {
        return SW_ERR;
    }

    SwooleG.timer._current_id = -1;
    SwooleG.timer._next_msec = msec;
    SwooleG.timer._next_id = 1;

    SwooleG.timer.heap = swHeap_new(1024, SW_MIN_HEAP);
    if (!SwooleG.timer.heap)
    {
        return SW_ERR;
    }

    if (swIsTaskWorker())
    {
        swSystemTimer_init(msec, SwooleG.use_timer_pipe);
    }
    else
    {
        swReactorTimer_init(msec);
    }

    return SW_OK;
}
示例#2
0
long php_swoole_add_timer(int ms, zval *callback, zval *param, int is_tick TSRMLS_DC)
{
    if (ms > 86400000)
    {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "The given parameters is too big.");
        return SW_ERR;
    }

    char *func_name = NULL;
    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 SW_ERR;
    }
    efree(func_name);

    if (SwooleGS->start > 0 && swIsTaskWorker())
    {
        swoole_php_error(E_WARNING, "cannot use swoole_server->after in task worker.");
    }

    swTimer_callback *cb = emalloc(sizeof(swTimer_callback));

    cb->data = param;
    cb->callback = callback;

    if (is_tick)
    {
        cb->type = SW_TIMER_TICK;
    }
    else
    {
        cb->type = SW_TIMER_AFTER;
    }

    php_swoole_check_reactor();
    php_swoole_check_timer(ms);

   sw_zval_add_ref(&cb->callback);
    if (cb->data)
    {
       sw_zval_add_ref(&cb->data);
    }

    return SwooleG.timer.add(&SwooleG.timer, ms, is_tick, cb);
}
示例#3
0
int swTimer_init(long msec)
{
    if (swTimer_now(&SwooleG.timer.basetime) < 0)
    {
        return SW_ERR;
    }

    SwooleG.timer.heap = swHeap_new(1024, SW_MIN_HEAP);
    if (!SwooleG.timer.heap)
    {
        return SW_ERR;
    }

    SwooleG.timer.map = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, NULL);
    if (!SwooleG.timer.map)
    {
        swHeap_free(SwooleG.timer.heap);
        SwooleG.timer.heap = NULL;
        return SW_ERR;
    }

    SwooleG.timer._current_id = -1;
    SwooleG.timer._next_msec = msec;
    SwooleG.timer._next_id = 1;
    SwooleG.timer.add = swTimer_add;
    SwooleG.timer.round = 0;

    if (swIsTaskWorker())
    {
        swSystemTimer_init(msec, SwooleG.use_timer_pipe);
    }
    else
    {
        swReactorTimer_init(msec);
    }

    return SW_OK;
}
示例#4
0
long php_swoole_add_timer(int ms, zval *callback, zval *param, int persistent TSRMLS_DC)
{
    if (ms > SW_TIMER_MAX_VALUE)
    {
        swoole_php_fatal_error(E_WARNING, "The given parameters is too big.");
        return SW_ERR;
    }
    if (ms <= 0)
    {
        swoole_php_fatal_error(E_WARNING, "Timer must be greater than 0");
        return SW_ERR;
    }

    char *func_name = NULL;

    zend_fcall_info_cache *func_cache = emalloc(sizeof(zend_fcall_info_cache));
    if (!sw_zend_is_callable_ex(callback, NULL, 0, &func_name, NULL, func_cache, NULL TSRMLS_CC))
    {
        efree(func_cache);
        efree(func_name);
        swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name);
        return SW_ERR;
    }
    efree(func_name);

    if (!swIsTaskWorker())
    {
        php_swoole_check_reactor();
    }

    php_swoole_check_timer(ms);
    swTimer_callback *cb = emalloc(sizeof(swTimer_callback));

    cb->data = &cb->_data;
    cb->callback = &cb->_callback;
    memcpy(cb->callback, callback, sizeof(zval));
    if (param)
    {
        memcpy(cb->data, param, sizeof(zval));
    }
    else
    {
        cb->data = NULL;
    }


    if (SwooleG.enable_coroutine)
    {
        cb->func_cache = func_cache;
    }
    else
    {
        efree(func_cache);
    }

    swTimerCallback timer_func;
    if (persistent)
    {
        cb->type = SW_TIMER_TICK;
        timer_func = php_swoole_onInterval;
    }
    else
    {
        cb->type = SW_TIMER_AFTER;
        timer_func = php_swoole_onTimeout;
    }

    sw_zval_add_ref(&cb->callback);
    if (cb->data)
    {
        sw_zval_add_ref(&cb->data);
    }

    swTimer_node *tnode = SwooleG.timer.add(&SwooleG.timer, ms, persistent, cb, timer_func);
    if (tnode == NULL)
    {
        swoole_php_fatal_error(E_WARNING, "add timer failed.");
        return SW_ERR;
    }
    else
    {
        tnode->type = SW_TIMER_TYPE_PHP;
        return tnode->id;
    }
}
示例#5
0
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;
}