php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #62077 EV_PERSIST flag not passed to php callback
Submitted: 2012-05-20 15:09 UTC Modified: 2012-05-21 11:34 UTC
From: harvey dot robin at gmail dot com Assigned: tony2001 (profile)
Status: Not a bug Package: libevent (PECL)
PHP Version: Irrelevant OS: Linux (Fedora 17)
Private report: No CVE-ID: None
 [2012-05-20 15:09 UTC] harvey dot robin at gmail dot com
Description:
------------
Raised events don't contain the EV_PERSIST flag in cases where you pass this to event_set().

My computer setup:

Fedora 17 - x86_64
PHP 5.4.1 (fedora)
php-libevent - built from source, SVN rev is #325757
libevent packages:
 [robin@robin-desktop libevent]$ rpm -qa '*libevent*'
 libevent-2.0.18-1.fc17.x86_64
 libevent-devel-2.0.18-1.fc17.x86_64



Test script:
---------------
<?php

$base = event_base_new();
$event = event_new();
$fd = getTestSocket ();

event_set($event, $fd, EV_WRITE | EV_PERSIST, "testCallback", array($event, $base));

event_base_set($event, $base);
event_add($event);
event_base_loop($base);

function testCallback ($fd, $events, $arg) {
    printf("Callback invoked with flags: %s\n", implode("\n", getFlags($events)));
    event_base_loopexit($arg[1]);
}

function getFlags ($val) {
    $r = array();
    if ($val & EV_READ) {
        $r[] = 'EV_READ';
    }
    if ($val & EV_WRITE) {
        $r[] = 'EV_WRITE';
    }
    if ($val & EV_TIMEOUT) {
        $r[] = 'EV_TIMEOUT';
    }
    if ($val & EV_SIGNAL) {
        $r[] = 'EV_SIGNAL';
    }
    if ($val & EV_PERSIST) {
        $r[] = 'EV_PERSIST';
    }
    return $r;
}


function getTestSocket () {
    $host = '72.249.45.9';
    $port = 80;
    if (! ($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
        throw new Exception("Failed to create inet socket", 7895);
    } else if (! socket_connect($sock, $host, $port)) {
        throw new Exception("Failed to connect inet socket ({$host}, {$port})", 7564);
    } else if (! socket_set_nonblock($sock)) {
        throw new Exception("Failed to switch connection in to non-blocking mode.", 2357);
    }
    return $sock;
}

Expected result:
----------------
Callback invoked with flags: EV_WRITE, EV_PERSIST

Actual result:
--------------
Callback invoked with flags: EV_WRITE

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-05-20 15:12 UTC] harvey dot robin at gmail dot com
[EDIT - corrected bug summary]
 [2012-05-20 15:12 UTC] harvey dot robin at gmail dot com
-Summary: EV_PERSIST flag not passed to +Summary: EV_PERSIST flag not passed to php callback
 [2012-05-21 07:23 UTC] tony2001@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: tony2001
 [2012-05-21 08:36 UTC] tony2001@php.net
-Status: Assigned +Status: Not a bug
 [2012-05-21 08:36 UTC] tony2001@php.net
Unfortunatel, libevent itself works this way.
It's kinda complex to demonstrate, but I'll try.
1) get libevent sources
2) open up select.c about line 185, its should be function select_dispatch().
3) there is a for cycle at the bottom of it and it calls evmap_io_active() with res argument, which has either EV_READ set, or EV_WRITE set, or both.
4) now that evmap_io_active() function actually looks at the events and calls event_active_nolock() function with this argument: (ev->ev_events & events) for flags, where ev->ev_events is what you passed to event_set() before and events is EV_READ, or EV_WRITE, or both.
After that the actuall callback is called, so you can't get EV_PERSIST there, whatever you do.
 [2012-05-21 11:34 UTC] harvey dot robin at gmail dot com
OK, thanks, I understand.  It might be worth tweaking the docs here:

http://www.php.net/manual/en/function.event-set.php

..the documentation of the callback function states that you can receive these 
events:

EV_TIMEOUT, EV_SIGNAL, EV_READ, EV_WRITE and EV_PERSIST

Thanks for you time.
--Robin
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Aug 24 17:01:27 2019 UTC