Commits

Ruslan Osmanov committed 641dbb3

Fix: memory access violation when calling Event::timer and Event::signal
Fix: memory leaks
100% test coverage

  • Participants
  • Parent commits 465e943

Comments (0)

Files changed (7)

classes/buffer_event.c

 	}
 
 	bev->self = zself;
+#if 0
 	Z_ADDREF_P(zself);
+#endif
 
+#if 0
 	/* Make sure base destroyed after the bufferevent
 	 * XXX Really need this? */
 	Z_ADDREF_P(zbase);
+#endif
 }
 /* }}} */
 
 
 
 /* {{{ proto Event Event::timer(EventBase base, callable cb[, zval arg = NULL]);
- * Creates new timer event */
+ * Factory method for timer event */
 PHP_METHOD(Event, timer)
 {
 	zval                  *zbase;
 
 	PHP_EVENT_FETCH_BASE(b, zbase);
 
-	e = (php_event_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
+	PHP_EVENT_INIT_CLASS_OBJECT(return_value, php_event_ce);
+	PHP_EVENT_FETCH_EVENT(e, return_value);
 
 	event = evtimer_new(b->base, timer_cb, (void *) e);
 	if (!event) {
 
 
 /* {{{ proto Event signal(EventBase base, int signum, callable cb[, zval arg = NULL]);
- * Creates new signal event */
+ * Factory method for signal event */
 PHP_METHOD(Event, signal)
 {
 	zval                  *zbase;
 
 	PHP_EVENT_FETCH_BASE(b, zbase);
 
-	e = (php_event_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
+	PHP_EVENT_INIT_CLASS_OBJECT(return_value, php_event_ce);
+	PHP_EVENT_FETCH_EVENT(e, return_value);
 
 	event = evsignal_new(b->base, signum, signal_cb, (void *) e);
 	if (!event) {
 	PHP_EVENT_ASSERT(e && e->event);
 
 	if (e->data) {
-		/*zval_ptr_dtor(&e->data);*/
+		zval_ptr_dtor(&e->data);
+#if 0
 		Z_DELREF_P(e->data);
+#endif
 	}
 
 	PHP_EVENT_FREE_FCALL_INFO(e->fci, e->fcc);
 	PHP_EVENT_ASSERT(b && b->bevent);
 
 	if (b->data) {
-		/*zval_ptr_dtor(&b->data);*/
+		zval_ptr_dtor(&b->data);
+#if 0
 		Z_DELREF_P(b->data);
+#endif
 	}
 
 	PHP_EVENT_FREE_FCALL_INFO(b->fci_read,  b->fcc_read);
 	}
 
 	if (b->self) {
+#if 0
 		Z_DELREF_P(b->self);
+#endif
+		zval_ptr_dtor(&b->data);
 	}
 
 	bufferevent_free(b->bevent);
 	}
 
 	if (l->base) {
+#if 0
 		Z_DELREF_P(l->base);
+#endif
+		zval_ptr_dtor(&l->base);
 	}
 
 	if (l->data) {
+#if 0
 		Z_DELREF_P(l->data);
+#endif
+		zval_ptr_dtor(&l->data);
 	}
 
 	if (l->self) {
+#if 0
 		Z_DELREF_P(l->self);
+#endif
+		zval_ptr_dtor(&l->self);
 	}
 
 	PHP_EVENT_FREE_FCALL_INFO(l->fci, l->fcc);
 	PHP_EVENT_ASSERT(evcon && evcon->conn);
 
 	if (evcon->base) {
+#if 0
 		Z_DELREF_P(evcon->base);
+#endif
+		zval_ptr_dtor(&evcon->base);
 	}
 
 	if (evcon->dns_base) {
+#if 0
 		Z_DELREF_P(evcon->dns_base);
+#endif
+		zval_ptr_dtor(&evcon->dns_base);
 	}
 
 	evhttp_connection_free(evcon->conn);
 	PHP_ME(Event, removeTimer, arginfo_event__void, ZEND_ACC_PUBLIC)
 #endif
 
-	PHP_ME(Event, timer,        arginfo_evtimer_new,  ZEND_ACC_PUBLIC)
+	PHP_ME(Event, timer,        arginfo_evtimer_new,  ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
 	PHP_ME(Event, setTimer,     arginfo_evtimer_set,  ZEND_ACC_PUBLIC)
 	PHP_ME(Event, timerPending, arginfo_event__void,  ZEND_ACC_PUBLIC)
-	PHP_ME(Event, signal,       arginfo_evsignal_new, ZEND_ACC_PUBLIC)
+	PHP_ME(Event, signal,       arginfo_evsignal_new, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
 
 	PHP_MALIAS(Event, addTimer,  add, arginfo_event_add,   ZEND_ACC_PUBLIC)
 	PHP_MALIAS(Event, delTimer,  del, arginfo_event__void, ZEND_ACC_PUBLIC)

tests/02-features.phpt

 Check for event configuration features 
 --FILE--
 <?php 
-$cfg = event_config_new();
+$cfg = new EventConfig();
 
-if (event_config_require_features($cfg, EVENT_FEATURE_FDS)) {
-	$base = event_base_new_with_config($cfg);
+if ($cfg->requireFeatures(EventConfig::FEATURE_FDS)) {
+	$base = new EventBase($cfg);
 
-	if (event_base_get_features($base) & EVENT_FEATURE_FDS) {
+	if ($base->getFeatures() & EventConfig::FEATURE_FDS) {
 		echo "FDS\n";
 	}
 }
 
-if (event_config_require_features($cfg, EVENT_FEATURE_ET)) {
-	$base = event_base_new_with_config($cfg);
+if ($cfg->requireFeatures(EventConfig::FEATURE_ET)) {
+	$base = new EventBase($cfg);
 
-	if (event_base_get_features($base) & EVENT_FEATURE_ET) {
+	if ($base->getFeatures() & EventConfig::FEATURE_ET) {
 		echo "ET\n";
 	}
 }
 
-if (event_config_require_features($cfg, EVENT_FEATURE_O1)) {
-	$base = event_base_new_with_config($cfg);
+if ($cfg->requireFeatures(EventConfig::FEATURE_O1)) {
+	$base = new EventBase($cfg);
 
-	if (event_base_get_features($base) & EVENT_FEATURE_O1) {
+	if ($base->getFeatures() & EventConfig::FEATURE_O1) {
 		echo "O1\n";
 	}
 }

tests/03-event-del.phpt

 Check for event_add and event_del
 --FILE--
 <?php 
-$base = event_base_new();
+$base = new EventBase();
 
-$e1 = event_timer_new($base, function () { echo "not ok 3\n"; });
-event_add($e1, 0.1);
+$e1 = Event::timer($base, function () { echo "not ok 3\n"; });
+$e1->add(0.1);
 
-$e2 = event_timer_new($base, function () { echo "ok 3\n"; });
-event_add($e2, 0.2);
+$e2 = Event::timer($base, function () { echo "ok 3\n"; });
+$e2->add(0.2);
 
-event_timer_pending($e1) and print("ok 1\n");
-event_timer_pending($e2) and print("ok 2\n");
+$e1->timerPending() and print("ok 1\n");
+$e2->timerPending() and print("ok 2\n");
 
-event_del($e1);
-event_timer_pending($e1) and print("not ok 4\n");
+$e1->del();
+$e1->timerPending() and print("not ok 4\n");
 
-event_base_loop($base, EVENT_LOOP_ONCE);
+$base->loop(EventBase::LOOP_ONCE);
 
-event_timer_set($e1, $base, function() { echo "ok 4\n"; });
-event_add($e1, 0.3);
-event_base_loop($base, EVENT_LOOP_ONCE);
-
-event_del($e1);
-event_del($e2);
-event_base_loop($base);
+$e1->setTimer($base, function() { echo "ok 4\n"; });
+$e1->add(0.3);
+$base->loop(EventBase::LOOP_ONCE);
 
+$e1->del();
+$e2->del();
+$base->loop();
 ?>
 --EXPECT--
 ok 1

tests/04-bevent-socket.phpt

 Check for event_buffer sockets 
 --FILE--
 <?php 
-$base = event_base_new();
-$bev = bufferevent_socket_new($base, NULL, EVENT_BEV_OPT_CLOSE_ON_FREE);
+$base = new EventBase();
+$bev = new EventBufferEvent($base, NULL, EventBufferEvent::OPT_CLOSE_ON_FREE);
 
-if (! bufferevent_socket_connect($bev, "www.php.net:80", TRUE)) {
-	exit("event_buffer_socket_connect failed\n");
+if (!$bev->connect("www.php.net:80", TRUE)) {
+	exit("Connection failed\n");
 }
 
-bufferevent_setcb($bev, NULL, NULL, function ($bev, $events, $data) {
-	if ($events & EVENT_BEV_EVENT_CONNECTED) {
+$bev->setCallbacks(NULL, NULL, function ($bev, $events, $data) {
+	if ($events & EventBufferEvent::CONNECTED) {
 		/* We're connected to 127.0.0.1:8080.   Ordinarily we'd do
 		something here, like start reading or writing. */
 		echo "Connected\n";
-	} elseif ($events & EVENT_BEV_EVENT_ERROR) {
+	} elseif ($events & EventBufferEvent::ERROR) {
 		exit("EVENT_BEV_EVENT_ERROR error occured\n");
  	}	
 }, "data");
 
-event_base_dispatch($base);
+$base->dispatch();
 ?>
 --EXPECT--
 Connected