- changed status to invalid
Events are not fired when the variable not in global scope, Crash on Windows
Issue #26
invalid
If you create an event as a local variable in some function, it won't work - the event will never be fired. If you move that same event to some longer lived variable (class attribute, global variable), it just works.
Tested on:
XUbuntu 14.04.3:
- PHP 7.0.4
- ext-event 2.0.1
Windows Server 2012 R2:
- PHP 7.0.4
- ext-event 2.0.0
Example, with the bug present:
<?php
function registerEvent(\EventBase $eventBase)
{
$stdin = fopen('php://stdin', 'r');
$e = new \Event($eventBase, $stdin, \Event::READ | \Event::PERSIST,
function ($stream, $events)
{
if ($events & Event::READ) {
$line = fgets($stream);
if ('exit' === trim($line)) {
exit(0);
}
printf("Your line: %s\n%s", $line, 'Enter a string: ');
}
});
$e->add();
}
$base = new \EventBase();
registerEvent($base);
echo 'Enter a string: ';
$base->loop();
Fixed example (works on Ubuntu, crashes on Windows, additional info below):
<?php
$e;
$stdin;
function registerEvent(\EventBase $eventBase)
{
global $e;
global $stdin;
$stdin = fopen('php://stdin', 'r');
$e = new \Event($eventBase, $stdin, \Event::READ | \Event::PERSIST,
function ($stream, $events)
{
if ($events & Event::READ) {
$line = fgets($stream);
if ('exit' === trim($line)) {
exit(0);
}
printf("Your line: %s\n%s", $line, 'Enter a string: ');
}
});
$e->add();
}
$base = new \EventBase();
registerEvent($base);
echo 'Enter a string: ';
$base->loop();
Additional info about crash on Windows:
#!
Problem signature:
Problem Event Name: APPCRASH
Application Name: php.exe
Application Version: 7.0.4.0
Application Timestamp: 56e5f8de
Fault Module Name: ntdll.dll
Fault Module Version: 6.3.9600.17031
Fault Module Timestamp: 530895af
Exception Code: c0000005
Exception Offset: 0000000000065e8e
OS Version: 6.3.9600.2.0.0.272.79
Locale ID: 1031
Additional Information 1: 387f
Additional Information 2: 387f0042a0cdac2563e4feec2f839920
Additional Information 3: e59f
Additional Information 4: e59f38c2e10b121d4c24cd4e95c512bb
Seems like some reference counts are not properly updated?
Comments (1)
-
repo owner - Log in to comment
The events are normal PHP objects with normal lifetime. When an event object goes out of scope, or is unset, or assigned to
null
, or destroyed by other means, it is thus disabled (removed from the event loop, if it is added).There are two common approaches: 1) keeping the watchers/events internally despite of the language scope rules 2) keeping internal structures as long as the language variables are alive.
AFAIK, the
pthreads
extension also requires to retain references toThread
objects. To make user's life easier, it providesPool
class.Perl
AnyEvent
extension also relies on the scope:However, Perl's
Event
extension keeps references internally.So it's just a matter of design.