Bug with Evtimer:stop()

Issue #6 resolved
Frank Mayer created an issue

Pecl-Ev 0.2.9 on PHP 5.5.1

Short version:

After having stopped a timer, the variable (outside the loop) returns an int instead of the timer object.

Long Version:

Current simple timer example on php.net states:

<?php
// Create and start timer firing after 2 seconds
$w1 = new EvTimer(2, 0, function () {
    echo "2 seconds elapsed\n";
});

// Create and launch timer firing after 2 seconds repeating each second
// until we manually stop it
$w2 = new EvTimer(2, 1, function ($w) {
    echo "is called every second, is launched after 2 seconds\n";
    echo "iteration = ", Ev::iteration(), PHP_EOL;

    // Stop the watcher after 5 iterations
    Ev::iteration() == 5 and $w->stop();
    // Stop the watcher if further calls cause more than 10 iterations
    Ev::iteration() >= 10 and $w->stop();
});

// Create stopped timer. It will be inactive until we start it ourselves
$w_stopped = EvTimer::createStopped(10, 5, function($w) {
    echo "Callback of a timer created as stopped\n";

    // Stop the watcher after 2 iterations
    Ev::iteration() >= 2 and $w->stop();
});

// Loop until Ev::stop() is called or all of watchers stop
Ev::run();

// Start and look if it works
$w_stopped->start();
echo "Run single iteration\n";
Ev::run(Ev::RUN_ONCE);

echo "Restart the second watcher and try to handle the same events, but don't block\n";
$w2->again();
Ev::run(Ev::RUN_NOWAIT);

$w = new EvTimer(10, 0, function() {});
echo "Running a blocking loop\n";
Ev::run();
echo "END\n";
?>

running that example, I get the following: Note the fatal error and the segfault in the end...

#  php libev01.php
is called every second, is launched after 2 seconds
iteration = 1
is called every second, is launched after 2 seconds
iteration = 2
2 seconds elapsed
is called every second, is launched after 2 seconds
iteration = 3
is called every second, is launched after 2 seconds
iteration = 4
is called every second, is launched after 2 seconds
iteration = 5
Run single iteration
Callback of a timer created as stopped
Restart the second watcher and try to handle the same events, but don't block
PHP Fatal error:  Call to a member function again() on a non-object in /var/www/html/test01/nonframework/libev01.php on line 36
Segmentation fault (core dumped)

Putting some debug code directly after $w2's definition and at the end...:

<?php
// Create and start timer firing after 2 seconds
$w1 = new EvTimer(2, 0, function () {
    echo "2 seconds elapsed\n";
});

// Create and launch timer firing after 2 seconds repeating each second
// until we manually stop it
$w2 = new EvTimer(1, 1, function ($w) {
    echo "is called every second, is launched after 2 seconds\n";
    echo "iteration = ", Ev::iteration(), PHP_EOL;

    // Stop the watcher after 5 iterations
    Ev::iteration() == 5 and $w->stop();
    // Stop the watcher if further calls cause more than 10 iterations
    Ev::iteration() >= 10 and $w->stop();
});
echo "w2 (directly after definition):\n";
var_dump($w2);

// Create stopped timer. It will be inactive until we start it ourselves
$w_stopped = EvTimer::createStopped(1, 2, function($w) {
        echo "Callback of a timer created as stopped\n";

        // Stop the watcher after 2 iterations
        Ev::iteration() >= 2 and $w->stop();
    });

// Loop until Ev::stop() is called or all of watchers stop
Ev::run();

// Start and look if it works
$w_stopped->start();
echo "Run single iteration\n";
Ev::run(Ev::RUN_ONCE);

//echo "Restart the second watcher and try to handle the same events, but don't block\n";
//$w2->again();
//Ev::run(Ev::RUN_NOWAIT);

$w = new EvTimer(2, 0, function() {});
echo "Running a blocking loop\n";
Ev::run();
echo "END\n";
echo "w2:\n";
var_dump($w2);

echo "w:\n";
var_dump($w);
?>

reveals that after the stop has taken place $w2 is an (int) instead of being an object:

php libev01.php
w2 (directly after definition):
object(EvTimer)#4 (6) {
  ["repeat"]=>
  float(1)
  ["remaining"]=>
  float(1)
  ["is_active"]=>
  bool(true)
  ["data"]=>
  NULL
  ["is_pending"]=>
  bool(false)
  ["priority"]=>
  int(0)
}
is called every second, is launched after 2 seconds
iteration = 1
is called every second, is launched after 2 seconds
iteration = 2
2 seconds elapsed
is called every second, is launched after 2 seconds
iteration = 3
is called every second, is launched after 2 seconds
iteration = 4
is called every second, is launched after 2 seconds
iteration = 5
Run single iteration
Callback of a timer created as stopped
Running a blocking loop
END
w2:
int(139857347141160)
w:
object(EvTimer)#7 (6) {
  ["repeat"]=>
  bool(false)
  ["remaining"]=>
  float(-0.0020891260064673)
  ["is_active"]=>
  bool(false)
  ["data"]=>
  NULL
  ["is_pending"]=>
  bool(false)
  ["priority"]=>
  int(0)
}
Segmentation fault (core dumped)

Comments (3)

  1. Log in to comment