Commits

Ruslan Osmanov committed 8c94af1

Fix: segmentation fault after watcher restart(Frank Mayer)
Fix: missing get_gc property handler
Fix: operators applied to uninitialized EvWatcher::data property caused unexpected results

Comments (0)

Files changed (8)

 /* }}} */
 #endif
 
-
+/* {{{ php_ev_get_gc */
+static HashTable *php_ev_get_gc(zval *object, zval ***table, int *n TSRMLS_DC)
+{
+	*table = NULL;
+	*n = 0;
+	return zend_std_get_properties(object TSRMLS_CC);
+}
+/* }}} */
 
 /* {{{ php_ev_get_property_ptr_ptr */
 #if PHP_VERSION_ID >= 50500
 #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4
 	ev_object_handlers.get_properties       = get_properties;
 #endif
+	ev_object_handlers.get_gc               = php_ev_get_gc;
 
 	zend_hash_init(&classes, 0, NULL, NULL, 1);
 	php_ev_register_classes(TSRMLS_C);
     <email>osmanov@php.net</email>
     <active>yes</active>
   </lead>
-  <date>2013-08-05</date>
+  <date>2013-08-16</date>
   <!--{{{ Current version -->
   <version>
-    <release>0.2.9</release>
+    <release>0.2.10</release>
     <api>0.2.0</api>
   </version>
   <stability>
   </stability>
   <license uri="http://www.php.net/license">PHP</license>
   <notes><![CDATA[
-  Fix: memory leaks in objects derived from EvWatcher 
-  Refact: some frequent checks optimized
+  Fix: segmentation fault after watcher restart(Frank Mayer)
+  Fix: missing get_gc property handler
+  Fix: operators applied to uninitialized EvWatcher::data property caused unexpected results
   ]]></notes>
   <!--}}}-->
   <!--{{{ Contents -->
         <file role="src" name="11_watcher_data.phpt"/>
         <file role="src" name="12_watcher_leak.phpt"/>
         <file role="src" name="bug64788.phpt"/>
+        <file role="src" name="13_watcher_data.phpt"/>
+        <file role="src" name="14_get_gc.phpt"/>
       </dir>
       <dir name="libev">
         <file role="doc" name="LICENSE"/>
   </extsrcrelease>
   <!--{{{ changelog-->
   <changelog>
+    <!--{{{ 0.2.10 -->
+    <release>
+      <version>
+        <release>0.2.10</release>
+        <api>0.2.0</api>
+      </version>
+      <stability>
+        <release>stable</release>
+        <api>stable</api>
+      </stability>
+      <license uri="http://www.php.net/license">PHP</license>
+      <notes><![CDATA[
+  Fix: segmentation fault after watcher restart(Frank Mayer)
+  Fix: missing get_gc property handler
+  Fix: operators applied to uninitialized EvWatcher::data property caused unexpected results
+  ]]></notes>
+    </release>
+    <!--}}}-->
     <!--{{{ 0.2.9 -->
     <release>
       <version>
 	 * of value, since it breaks refcount in read_property()
 	 * causing further leaks and memory access violations */
 	REPLACE_ZVAL_VALUE(ppz, value, PZVAL_IS_REF((zval *)value));
-
 #endif
 }
 
 	if (!obj->ptr) return NULL;
 
 	if (!PHP_EV_LOOP_OBJECT_FETCH_FROM_OBJECT(obj)->data) {
-		MAKE_STD_ZVAL(PHP_EV_LOOP_OBJECT_FETCH_FROM_OBJECT(obj)->data);
+		ALLOC_INIT_ZVAL(PHP_EV_LOOP_OBJECT_FETCH_FROM_OBJECT(obj)->data);
 	}
 	return &(PHP_EV_LOOP_OBJECT_FETCH_FROM_OBJECT(obj)->data);
 }
 /* {{{ ev_watcher_prop_data_get_ptr_ptr */
 static zval **ev_watcher_prop_data_get_ptr_ptr(php_ev_object *obj TSRMLS_DC)
 {
-	if (!obj->ptr) return NULL;
+	if (!obj->ptr) {
+		return NULL;
+	}
 
 	zval *data = PHP_EV_WATCHER_FETCH_FROM_OBJECT(obj)->data;
 	if (!data) {
-		MAKE_STD_ZVAL(PHP_EV_WATCHER_FETCH_FROM_OBJECT(obj)->data);
+		ALLOC_INIT_ZVAL(PHP_EV_WATCHER_FETCH_FROM_OBJECT(obj)->data);
 	}
 
 	return &PHP_EV_WATCHER_FETCH_FROM_OBJECT(obj)->data;
 extern zend_module_entry ev_module_entry;
 #define phpext_ev_ptr &ev_module_entry
 
-#define PHP_EV_VERSION "0.2.9"
+#define PHP_EV_VERSION "0.2.10"
 
 #endif /* PHP_EV_H */
 

tests/13_watcher_data.phpt

+--TEST--
+Check whether modification of uninitialized EvWatcher::data property is correct
+--FILE--
+<?php
+// Create and start timer firing after 2 seconds
+$w = new EvTimer(0, .2, function ($w) {
+	echo ++$w->data;
+	if (!isset($w->data)) {
+		$w->stop();
+		return;
+	}
+	$w->data >= 8 and $w->stop();
+}, NULL);
+
+Ev::run();
+$w->again();
+Ev::run();
+?>
+--EXPECT--
+123456789
+--TEST--
+Check for get_gc property handler
+--FILE--
+<?php
+class x {
+        public $t = null;
+ 
+        public function __construct() {
+                $this->t = new EvTimer(0, .5, function () { });
+        }
+}
+echo "1";
+new x();
+gc_collect_cycles();
+echo "2"; // check whether it segfaults here
+?>
+--EXPECT--
+12
 	TSRMLS_FETCH_FROM_CTX(php_ev_watcher_thread_ctx(watcher));
 
 	/* libev might have stopped watcher */
-	if (UNEXPECTED(php_ev_watcher_flags(watcher) & PHP_EV_WATCHER_FLAG_UNREFED
-			&& !ev_is_active(watcher))) {
+	if (php_ev_watcher_flags(watcher) & PHP_EV_WATCHER_FLAG_UNREFED
+			&& !ev_is_active(watcher)) {
 		PHP_EV_WATCHER_REF(watcher);
 	}
 
 #define PHP_EV_WATCHER_FLAG_UNREFED      (1<<1)
 #define PHP_EV_WATCHER_FLAG_SELF_UNREFED (1<<2)
 
+#if 0
 #define PHP_EV_WATCHER_SELF_UNREF(w)                                             \
 	do {                                                                         \
 		if (EXPECTED(php_ev_watcher_self(w) != NULL)                             \
         	php_ev_watcher_flags(w) &= ~PHP_EV_WATCHER_FLAG_SELF_UNREFED; \
     	}                                                                 \
 	} while (0)
+#endif
+#define PHP_EV_WATCHER_SELF_UNREF(w)
+#define PHP_EV_WATCHER_SELF_REF(w)
+
 
 #define PHP_EV_WATCHER_UNREF(w)                                                     \
 	do {                                                                            \