Выход из цикла тайм-аута Libevent

У меня возникли некоторые трудности с тем, чтобы расширение PHP libevent вышло из цикла по тайм-ауту. Вот что у меня есть на основе демонстраций на страницах документации PHP.net:

// From here: http://www.php.net/manual/en/libevent.examples.php

function print_line($fd, $events, $arg) {
    static $max_requests = 0;
    $max_requests++;

    printf("Received event: %s after %s\n%s", implode(getEventFlags($events)), getTimer(), fgets($fd));

    if ($max_requests == 10) {
        // exit loop after 3 writes
        echo " [EXIT]\n";
        event_base_loopexit($arg[1]);
    }
}

// create base and event
$base = event_base_new();
$event = event_new();


getTimer(); // Initialise time

$fd = STDIN;
event_set($event, $fd, EV_READ | EV_PERSIST, "print_line", array($event, $base));
event_base_set($event, $base);
event_add($event, 2000000);
event_base_loop($base);

// extract flags from bitmask
function getEventFlags ($ebm) {
    $expFlags = array('EV_TIMEOUT', 'EV_SIGNAL', 'EV_READ', 'EV_WRITE', 'EV_PERSIST');
    $ret = array();
    foreach ($expFlags as $exf) {
        if ($ebm & constant($exf)) {
            $ret[] = $exf;
        }
    }
    return $ret;
}

// Used to track time!
function getTimer () {
    static $ts;
    if (is_null($ts)) {
        $ts = microtime(true);
        return "Timer initialised";
    }
    $newts = microtime(true);
    $r = sprintf("Delta: %.3f", $newts - $ts);
    $ts = $newts;
    return $r;
}

Я вижу, что значение тайм-аута, переданное в event_add, влияет на события, переданные в print_line(), если между этими событиями больше 2 секунд, я получаю EV_TIMEOUT вместо EV_READ. Однако я хочу, чтобы libevent вызывал print_line, как только истекло время ожидания, а не ждал следующего события, чтобы дать мне время ожидания.

Я пробовал использовать event_base_loopexit($base, 2000000), это приводит к немедленному завершению цикла событий без блокировки событий. Я также пытался передать EV_TIMEOUT в event_set, похоже, это не имеет никакого эффекта.

Кому-нибудь удалось заставить это работать раньше? Я знаю, что event_buffer_* работает с тайм-аутами, однако я хочу использовать стандартные функции event_base. Одна из ошибок PECL говорит о функциях event_timer_*, и эти функции существуют на моем system, однако они вообще не документированы.


person Robin    schedule 05.02.2012    source источник


Ответы (1)


Проблема в fgets() в:

printf("Received event: %s after %s\n%s", implode(getEventFlags($events)), getTimer(), fgets($fd));

Это блокирует обработку и ожидает данных из STDIN (но их нет по тайм-ауту)

Измените на что-то вроде этого:

$text = '';
if ($events & EV_READ) {
    $text = fgets($fd);
}
printf("Received event: %s after %s\n%s", implode(getEventFlags($events)), getTimer(), $text);
person user1262888    schedule 11.03.2012