php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #57086 event_have_events returns true even with no events
Submitted: 2006-06-14 00:38 UTC Modified: 2013-07-16 06:16 UTC
From: e at osterman dot com Assigned:
Status: Wont fix Package: event (PECL)
PHP Version: 5.1.2 OS: Debian / RedHat
Private report: No CVE-ID: None
 [2006-06-14 00:38 UTC] e at osterman dot com
Description:
------------
Per the source comments, "Returns true if there are any scheduled events, false otherwise". In the concise example below, it returns true even though only event_init has been called.

Tested on:  PHP 5.1.2-1+b1 , PHP 5.1




Reproduce code:
---------------
<?

dl('event.so');

event_init();

if( event_have_events() )
    echo "Have events!\n";
else
    echo "Have no events!\n";

?>



Expected result:
----------------
Have no events!

Actual result:
--------------
Have events!

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-01-30 12:12 UTC] polone at townnews dot com
This problem is occuring for me as well with version 0.9.1. The issue is related to the fact that event_init() adds a "hidden" signal event to a static C function called signal_cb(). That event never appears to happen, or continues to reschedule itself.
 [2007-02-11 20:05 UTC] e at osterman dot com
I ended up fixing #7892, #7893, #7894, #7895. Here is a patch. Feel free to contact me if you have any problems.


Problems:
* Globals event_count_active and event_count were not initialized to 0. Initializing them fixed #7892 and #7894.
* Dispatch didn't check for initialization. Checking for initialization fixed #7893.
* Execution success/failure of call_user_func_ex were not returned by callback_to_php so that event_process_active would keep rescheduling bad events. Returning the result of call_user_func_ex and checking it in event_process_active for success fixed #7895. (My interpretation of the problem, but fix works for me).



diff -ruN event-0.9.1/event.c event-0.9.1-patched/event.c
--- event-0.9.1/event.c 2004-12-15 21:33:36.000000000 -0800
+++ event-0.9.1-patched/event.c 2007-02-11 16:38:28.000000000 -0800
@@ -191,7 +191,7 @@
 RB_GENERATE(event_tree, php_event, ev_timeout_node, php_event_compare);

 #if HAVE_SIGACTION
-static void signal_cb(int fd, short mask, void *arg TSRMLS_DC)
+int signal_cb(int fd, short mask, void *arg TSRMLS_DC)
 {
        int sig[32];
        struct php_event *ev;
@@ -208,6 +208,7 @@
                        }
                }
        } while (n == sizeof(sig));
+       return SUCCESS;
 }
 #endif

@@ -294,6 +295,9 @@
        }
 #endif

+       EVENT_G(event_count_active) = 0;
+       EVENT_G(event_count) = 0;
+
        RETURN_STRING(EVENT_G(evsel)->name, 1);
 }
 /* }}} */
@@ -626,6 +630,7 @@
        struct php_event *ev;
        struct event_list *activeq = NULL;
        int i;
+       int res;
        short ncalls;

        if (!EVENT_G(event_count_active))
@@ -637,7 +642,6 @@
                        break;
                }
        }
-
        for (ev = TAILQ_FIRST(activeq); ev; ev = TAILQ_FIRST(activeq)) {
                event_queue_remove(ev, EVLIST_ACTIVE TSRMLS_CC);

@@ -647,11 +651,13 @@
                while (ncalls) {
                        ncalls--;
                        ev->ev_ncalls = ncalls;
-                       (*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg TSRMLS_CC);
+                       res = (*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg TSRMLS_CC);
+                       if( res != SUCCESS )
+                               break;
                }

                /* re-add the event if its a persistent timeout only event */
-               if (ev->ev_events == (EV_TIMEOUT|EV_PERSIST)) {
+               if ( res == SUCCESS && ev->ev_events == (EV_TIMEOUT|EV_PERSIST)) {
                        event_add(ev, &ev->ev_timeout_interval TSRMLS_CC);
                }
        }
@@ -677,7 +683,11 @@
        struct timeval tv;
        int res, done;
        long flags = 0;
-
+
+       if (!EVENT_G(evsel)) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Event enginte not initialized");
+               RETURN_FALSE;
+       }

        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags)) {
                RETURN_LONG(-1);
@@ -767,8 +777,7 @@
        RETURN_LONG(res);
 }
 /* }}} */
-
-static void callback_to_php(int fd, short events, void *arg TSRMLS_DC)
+int callback_to_php(int fd, short events, void *arg TSRMLS_DC)
 {
        struct php_event *ev = (struct php_event*)arg;
        zval *retval = NULL;
@@ -793,8 +802,25 @@
        zval_ptr_dtor(&zevents);

        if (res != SUCCESS) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "callback failed");
+               if( EG(exception) )
+               {
+                       char ex_class_name[128];
+                       if( Z_TYPE_P(EG(exception)) == IS_OBJECT )
+                       {
+                               if (Z_TYPE_P(EG(exception)) == IS_OBJECT) {
+                                       strncpy(ex_class_name, Z_OBJ_CLASS_NAME_P(EG(exception)), 127);
+                                       ex_class_name[127] = '\0';
+                               } else {
+                                       strcpy(ex_class_name, "Unknown Exception");
+                               }
+                       }
+
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "callback failed; %s thrown", ex_class_name);
+               }
+               else
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "callback failed");
        }
+       return res;
 }

 static int event_set_for_php(int isnew, struct php_event *event, zval *zstream, long events, zval *cb, zval *cbarg TSRMLS_DC)
diff -ruN event-0.9.1/php_event_int.h event-0.9.1-patched/php_event_int.h
--- event-0.9.1/php_event_int.h 2004-12-15 19:30:18.000000000 -0800
+++ event-0.9.1-patched/php_event_int.h 2007-02-11 16:07:28.000000000 -0800
@@ -68,7 +68,7 @@

 #define TIMEOUT_DEFAULT                {5, 0}

-typedef void (*php_event_callback)(int, short, void *arg TSRMLS_DC);
+typedef int (*php_event_callback)(int, short, void *arg TSRMLS_DC);

 struct php_event {
 #ifdef PHP_WIN32
 [2013-07-16 06:16 UTC] osmanov@php.net
-Status: Open +Status: Wont fix
 [2013-07-16 06:16 UTC] osmanov@php.net
Thank you for taking the time to report a problem with PHP.
Unfortunately you are not using a current version of PHP -- 
the problem might already be fixed. Please download a new
PHP version from http://www.php.net/downloads.php

If you are able to reproduce the bug with one of the latest
versions of PHP, please change the PHP version on this bug report
to the version you tested and change the status back to "Open".
Again, thank you for your continued support of PHP.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Dec 27 01:01:28 2024 UTC