Commits

Ruslan Osmanov committed 838e663

Fix: property and class HashTable's were not free'd in MSHUTDOWN
Add: Event:: property
Fix: Event::__construct failed with Event::TIMEOUT flag

Comments (0)

Files changed (5)

 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid signal passed");
 			RETURN_FALSE;
 		}
+	} else if (what & EV_TIMEOUT) {
+		fd = -1;
 	} else {
 		fd = (evutil_socket_t) php_event_zval_to_fd(ppzfd TSRMLS_CC);
 		if (fd < 0) {
 	PHP_EVENT_FETCH_EVENT(e, zself);
 
 	if (e->event) {
-		event_del(e->event);
+		/* No need in
+		 * event_del(e->event);
+		 * since event_free makes event non-pending internally */
 		event_free(e->event);
 		e->event = NULL;
+
+		zval_ptr_dtor(&zself);
 	}
 
-	/*zval_ptr_dtor(&zself);*/
 }
 /* }}} */
 
 
 	PHP_EVENT_FETCH_EVENT(e, zevent);
 
-	if (event_del(e->event)) {
+	if (e->event == NULL || event_del(e->event)) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed deletting event");
 		RETURN_FALSE;
 	}

examples/timer.php

+<?php
+$base = new EventBase();
+$e = new Event($base, -1, Event::TIMEOUT, function($fd, $what, $e) {
+	echo "2 seconds elapsed\n";
+	$e->delTimer();
+});
+$e->data = $e;
+$e->addTimer(2);
+$base->loop();
+?>
     <email>osmanov@php.net</email>
     <active>yes</active>
   </lead>
-  <date>2013-03-03</date>
+  <date>2013-03-05</date>
   <!--{{{ Current version -->
   <version>
     <release>1.2.7</release>
   Fix: possible memory access violations in EventBufferEvent input/output property handlers
   Change: Event::$timer_pending property removed; generic Event::$pending property added
   Fix: With OPT_LEAVE_SOCKETS_BLOCKING flag EventListener::__construct turned fd to non-blocking mode
+  Fix: property and class HashTable's were not free'd in MSHUTDOWN
+  Add: Event::$data property
+  Fix: Event::__construct failed with Event::TIMEOUT flag
   ]]></notes>
   <!--}}}-->
   <!--{{{ Contents -->
         <file role="doc" name="listener.php"/>
         <file role="doc" name="misc.php"/>
         <file role="doc" name="signal.php"/>
+        <file role="doc" name="timer.php"/>
         <file role="doc" name="uppercase_proxy.php"/>
       </dir>
       <dir name="src">
   Fix: possible memory access violations in EventBufferEvent input/output property handlers
   Change: Event::$timer_pending property removed; generic Event::$pending property added
   Fix: With OPT_LEAVE_SOCKETS_BLOCKING flag EventListener::__construct turned fd to non-blocking mode
+  Fix: property and class HashTable's were not free'd in MSHUTDOWN
+  Add: Event::$data property
+  Fix: Event::__construct failed with Event::TIMEOUT flag
   ]]></notes>
     </release>
     <!--}}}-->
 
 	PHP_EVENT_ASSERT(e);
 
-	if (e->data) {
-		zval_ptr_dtor(&e->data);
+	if (e->event) {
+		/* No need in
+		 * event_del(e->event);
+		 * since event_free makes event non-pending internally */
+		event_free(e->event);
+		e->event = NULL;
 	}
 
-	PHP_EVENT_FREE_FCALL_INFO(e->fci, e->fcc);
-
 	if (e->stream_id >= 0) { /* stdin fd == 0 */
 		zend_list_delete(e->stream_id);
 	}
 
-	if (e->event) {
-		event_del(e->event);
-		event_free(e->event);
+	if (e->data) {
+		zval_ptr_dtor(&e->data);
+		e->data = NULL;
 	}
 
+	PHP_EVENT_FREE_FCALL_INFO(e->fci, e->fcc);
+
 	event_generic_object_free_storage(ptr TSRMLS_CC);
 }
 /* }}} */
 	if (!b->internal && b->base) {
 		/* TODO: what if events bound to the event_base are not destroyed? */
 		event_base_free(b->base);
+		b->base = NULL;
 	}
 
 	event_generic_object_free_storage(ptr TSRMLS_CC);
 /* {{{ PHP_MSHUTDOWN_FUNCTION */
 PHP_MSHUTDOWN_FUNCTION(event)
 {
+	zend_hash_destroy(&event_properties);
+	zend_hash_destroy(&event_bevent_properties);
+	zend_hash_destroy(&event_buffer_properties);
+	zend_hash_destroy(&event_buffer_pos_properties);
+	zend_hash_destroy(&event_ssl_context_properties);
+
+	zend_hash_destroy(&classes);
+
 #ifdef HAVE_EVENT_OPENSSL_LIB
 	/* Removes memory allocated when loading digest and cipher names
 	 * in the OpenSSL_add_all_ family of functions */
 #include "src/priv.h"
 #include "src/util.h"
 
+static inline void _prop_write_zval(zval **ppz, const zval *value)
+{
+	if (!*ppz) {
+		MAKE_STD_ZVAL(*ppz);
+	}
+
+    /* Make a copy of the zval, avoid direct binding to the address
+     * of value, since it breaks refcount in read_property()
+     * causing further leaks and memory access violations */
+	REPLACE_ZVAL_VALUE(ppz, value, 1);
+}
+
+static inline void _prop_read_zval(const zval *pz, zval **retval)
+{
+	if (!pz) {
+		ALLOC_INIT_ZVAL(*retval);
+		return;
+	}
+
+    MAKE_STD_ZVAL(*retval);
+    REPLACE_ZVAL_VALUE(retval, pz, 1);
+}
+
+
+
 /* {{{ get_ssl_option */
 static zval **get_ssl_option(const HashTable *ht, ulong idx)
 {
 }
 /* }}} */
 
+/* {{{ event_data_prop_get_ptr_ptr */
+static zval **event_data_prop_get_ptr_ptr(php_event_abstract_object_t *obj TSRMLS_DC)
+{
+	php_event_t *e = (php_event_t *) obj;
+
+	PHP_EVENT_ASSERT(e->event);
+
+	return (e->data ? &e->data : NULL);
+}
+/* }}} */
+
+/* {{{ event_data_prop_read  */
+static int event_data_prop_read(php_event_abstract_object_t *obj, zval **retval TSRMLS_DC)
+{
+	php_event_t *e = (php_event_t *) obj;
+
+	PHP_EVENT_ASSERT(e->event);
+
+	_prop_read_zval(e->data, retval);
+
+	return SUCCESS;
+}
+/* }}} */
+
+/* {{{ event_data_prop_write */
+static int event_data_prop_write(php_event_abstract_object_t *obj, zval *value TSRMLS_DC)
+{
+	php_event_t *e = (php_event_t *) obj;
+
+	PHP_EVENT_ASSERT(e->event);
+
+	_prop_write_zval(&e->data, value);
+
+	return SUCCESS;
+}
+/* }}} */
+
 
 
 /* {{{ event_buffer_length_prop_read */
 
 
 const php_event_property_entry_t event_property_entries[] = {
-	{"pending",           sizeof("pending") - 1, event_pending_prop_read, NULL, NULL},
+	{"pending", sizeof("pending") - 1, event_pending_prop_read, NULL,                  NULL},
+	{"data",    sizeof("data")    - 1, event_data_prop_read,    event_data_prop_write, event_data_prop_get_ptr_ptr},
     {NULL, 0, NULL, NULL, NULL}
 };
 const php_event_property_entry_t event_bevent_property_entries[] = {
 
 const zend_property_info event_property_entry_info[] = {
 	{ZEND_ACC_PUBLIC, "pending", sizeof("pending") - 1, -1, 0, NULL, 0, NULL},
+	{ZEND_ACC_PUBLIC, "data",    sizeof("data")    - 1, -1, 0, NULL, 0, NULL},
 	{0, NULL, 0, -1, 0, NULL, 0, NULL}
 };
 const zend_property_info event_bevent_property_entry_info[] = {
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.