Commits

Ruslan Osmanov committed 3206bf7

Forced passing EventBase argument by reference

Comments (0)

Files changed (11)

classes/buffer_event.c

 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	if (ppzfd) {
 		/* php_event_zval_to_fd reports error
 	 	 * in case if it is not a valid socket resource */
 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	PHP_EVENT_FETCH_BASE(base, zbase);
 
 	if (bufferevent_pair_new(base->base, options, bevent_pair)) {
 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	if (!is_valid_ssl_state(state)) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING,
 				"Invalid state specified");
 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	if (!is_valid_ssl_state(state)) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING,
 				"Invalid state specified");
 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	PHP_EVENT_FETCH_BASE(base, zbase);
 
 	PHP_EVENT_FETCH_DNS_BASE(dnsb, getThis());
 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	if (what & ~(EV_TIMEOUT | EV_READ | EV_WRITE | EV_SIGNAL | EV_PERSIST | EV_ET)) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid mask");
 		ZVAL_NULL(zself);
 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	if (what != -1) {
 		if (what & ~(EV_TIMEOUT | EV_READ | EV_WRITE | EV_SIGNAL | EV_PERSIST | EV_ET)) {
 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid events mask");
 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	PHP_EVENT_FETCH_BASE(b, zbase);
 
 	PHP_EVENT_INIT_CLASS_OBJECT(return_value, php_event_ce);
 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	PHP_EVENT_FETCH_EVENT(e, zevent);
 
 	if (evtimer_pending(e->event, NULL)) {
 	zval                  *arg    = NULL;
 	php_event_t           *e;
 	struct event          *event;
-	
+
 
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Olf|z",
 				&zbase, php_event_base_ce, &signum, &fci, &fcc, &arg) == FAILURE) {
 		return;
 	}
-	
+
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	if (signum < 0 || signum >= NSIG) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid signal passed");
 		RETURN_FALSE;

classes/event_util.c

 
 #ifdef HAVE_EVENT_OPENSSL_LIB/* {{{ */
 /* {{{ proto bool EventUtil::sslRandPoll(void);
- * 
+ *
  * Generates entropy by means of OpenSSL's RAND_poll()
  */
 PHP_METHOD(EventUtil, sslRandPoll)
 	zval            **l_onoff  , **l_linger;
 	zval            **sec      , **usec;
 	evutil_socket_t   fd;
-	
+
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZllZ",
 				&ppzfd, &level, &optname, &zoptval) == FAILURE) {
 		return;
 		RETURN_FALSE;
 	}
 
-	errno = 0;
+	/*errno = 0;*/
 
 	switch (optname) {
 		case SO_LINGER: {
 			opt_ptr = &tv;
 			break;
 		}
-		
+
 		default:
 			convert_to_long_ex(zoptval);
 			ov = Z_LVAL_PP(zoptval);
 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	PHP_EVENT_FETCH_BASE(b, zbase);
 
 	PHP_EVENT_FETCH_HTTP(http, getThis());

classes/http_connection.c

 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	PHP_EVENT_FETCH_BASE(b, zbase);
 
 	if (zdns_base) {

classes/listener.c

 		return;
 	}
 
+	PHP_EVENT_REQUIRE_BASE_BY_REF(zbase);
+
 	PHP_EVENT_FETCH_BASE(base, zbase);
 
 	if (Z_TYPE_PP(ppztarget) == IS_STRING) {
 		listener = evconnlistener_new(base->base, _php_event_listener_cb,
 				(void *) l, flags, backlog, fd);
 	}
-	
+
 	if (!listener) {
 		ZVAL_NULL(zself);
 		return;
   This is an extension to efficiently schedule I/O, time and signal based
   events using the best I/O notification mechanism available for specific platform.
   This is a port of libevent to the PHP infrastructure.
-  
+
   Version 1.0.0 introduces:
   * new OO API breaking backwards compatibility
   * support of libevent 2+ including HTTP, DNS, OpenSSL and the event listener.
     <email>remi@php.net</email>
     <active>yes</active>
   </contributor>
-  <date>2013-10-08</date>
+  <date>2014-01-16</date>
   <!--{{{ Current version -->
   <version>
     <release>1.9.0</release>
   Windows support introduced(thanks to Anatol Belski <ab@php.net>)
 
   LIBEVENT_VERSION is now reported in phpinfo(Remi <remi@php.net>)
+
+   Forced passing EventBase argument by reference. A method accepting EventBase
+   will generate fatal error in case if corresponding argument is not passed by
+   reference.
   ]]></notes>
   <!--}}}-->
   <!--{{{ Contents -->
   </extsrcrelease>
   <!--{{{ changelog-->
   <changelog>
-    <!--{{{ Current version -->
+    <!--{{{ 1.9.0 -->
     <release>
       <version>
         <release>1.9.0</release>
   Windows support introduced(thanks to Anatol Belski <ab@php.net>)
 
   LIBEVENT_VERSION is now reported in phpinfo(Remi <remi@php.net>)
+
+   Forced passing EventBase argument by reference. A method accepting EventBase
+   will generate fatal error in case if corresponding argument is not passed by
+   reference.
   ]]></notes>
     </release>
     <!--}}}-->
 ZEND_END_ARG_INFO();
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_event__construct, 0, 0, 4)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, fd)
 	ZEND_ARG_INFO(0, what)
 	ZEND_ARG_INFO(0, cb)
 ZEND_END_ARG_INFO();
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_event_set, 0, 0, 2)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, fd)
 	ZEND_ARG_INFO(0, what)
 	ZEND_ARG_INFO(0, cb)
 ZEND_END_ARG_INFO();
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_evtimer_new, 0, 0, 2)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, cb)
 	ZEND_ARG_INFO(0, arg)
 ZEND_END_ARG_INFO();
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_evtimer_set, 0, 0, 2)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, cb)
 	ZEND_ARG_INFO(0, arg)
 ZEND_END_ARG_INFO();
 
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_evsignal_new, 0, 0, 3)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, signum)
 	ZEND_ARG_INFO(0, cb)
 	ZEND_ARG_INFO(0, arg)
 ZEND_END_ARG_INFO();
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_bufferevent__construct, 0, 0, 1)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, socket)
 	ZEND_ARG_INFO(0, options)
 	ZEND_ARG_INFO(0, readcb)
 ZEND_END_ARG_INFO();
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_bufferevent_pair_new, 0, 0, 1)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, options)
 ZEND_END_ARG_INFO();
 
 
 #ifdef HAVE_EVENT_OPENSSL_LIB
 ZEND_BEGIN_ARG_INFO_EX(arginfo_bufferevent_ssl_filter, 0, 0, 4)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, underlying)
 	ZEND_ARG_INFO(0, ctx)
 	ZEND_ARG_INFO(0, state)
 ZEND_END_ARG_INFO();
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_bufferevent_ssl_socket, 0, 0, 4)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, socket)
 	ZEND_ARG_INFO(0, ctx)
 	ZEND_ARG_INFO(0, state)
 
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_event_evhttp_connection__construct, 0, 0, 4)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, dns_base)
 	ZEND_ARG_INFO(0, address)
 	ZEND_ARG_INFO(0, port)
 ZEND_END_ARG_INFO();
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_event_http__construct, 0, 0, 1)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 ZEND_END_ARG_INFO();
 
 
 /* {{{ ARGINFO for extra API */
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_evdns__construct, 0, 0, 2)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, initialize)
 ZEND_END_ARG_INFO();
 
 
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_evconnlistener__construct, 0, 0, 6)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, cb)
 	ZEND_ARG_INFO(0, data)
 	ZEND_ARG_INFO(0, flags)
 ZEND_END_ARG_INFO();
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_evconnlistener_new_bind, 0, 0, 5)
-	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(1, base)
 	ZEND_ARG_INFO(0, cb)
 	ZEND_ARG_INFO(0, data)
 	ZEND_ARG_INFO(0, flags)
 		RETURN_FALSE;                     \
 	} while (0)
 
+#define PHP_EVENT_REQUIRE_BASE_BY_REF(zbase)                  \
+	do {                                                      \
+		if (!Z_ISREF_P((zbase))) {                            \
+			php_error_docref(NULL TSRMLS_CC, E_ERROR,         \
+					"EventBase must be passed by reference"); \
+		}                                                     \
+	} while (0)
 
 #if defined(PHP_WIN32)
 #if defined(ZTS)

tests/11-gc-cycles.phpt

 Check for get_gc property handler
 --FILE--
 <?php
- 
+
 class x {
-        public $t = null;
- 
-        public function __construct() {
-                $this->t = Event::timer(new EventBase(), function () { });
-                $this->t->free();
-        }
+	public $t = null;
+
+	public function __construct() {
+		$b = new EventBase();
+		$this->t = Event::timer($b, function () { });
+		$this->t->free();
+	}
 }
- 
+
 
 echo "1";
 new x();