Ruslan Osmanov avatar Ruslan Osmanov committed fc264d1 Merge

Merge branch 'pthreads'

Comments (0)

Files changed (11)

  * returns NULL. */
 PHP_METHOD(EventBase, getTimeOfDayCached)
 {
-	zval                  *zbase = getThis();
-	php_event_base_t      *b;
-	struct timeval         tv;
+	zval             *zbase = getThis();
+	php_event_base_t *b;
+	struct timeval    tv;
 
 	if (zend_parse_parameters_none() == FAILURE) {
 		return;
 	if (event_base_gettimeofday_cached(b->base, &tv)) {
 		RETURN_NULL();
 	}
-	
+
 	RETVAL_DOUBLE(PHP_EVENT_TIMEVAL_TO_DOUBLE(tv));
 }
 /* }}} */

classes/buffer_event.c

 static zend_always_inline void bevent_rw_cb(struct bufferevent *bevent, php_event_bevent_t *bev, zend_fcall_info *pfci, zend_fcall_info_cache *pfcc)
 {
 	PHP_EVENT_ASSERT(bev);
+	PHP_EVENT_ASSERT(bevent);
 	PHP_EVENT_ASSERT(bevent == bev->bevent);
 	PHP_EVENT_ASSERT(pfci && pfcc);
 	PHP_EVENT_ASSERT(bev->self);
 
 	zval  *arg_data = bev->data;
+	zval  *arg_self;
 	zval **args[2];
 	zval  *retval_ptr;
 
 	TSRMLS_FETCH_FROM_CTX(bev->thread_ctx);
 
 	if (ZEND_FCI_INITIALIZED(*pfci)) {
+#ifdef HAVE_EVENT_PTHREADS_LIB
+		if (bevent) {
+			bufferevent_lock(bevent);
+		}
+#endif
 		/* Setup callback args */
 
-		if (bev->self) {
-			args[0] = &bev->self;
+		arg_self = bev->self;
+		if (arg_self) {
+			Z_ADDREF_P(arg_self);
+		} else {
+			ALLOC_INIT_ZVAL(arg_self);
 		}
+		args[0] = &bev->self;
+
 		if (arg_data) {
 			Z_ADDREF_P(arg_data);
 		} else {
         }
 
         zval_ptr_dtor(&arg_data);
+
+#ifdef HAVE_EVENT_PTHREADS_LIB
+		if (bevent) {
+			bufferevent_unlock(bevent);
+		}
+#endif
+        zval_ptr_dtor(&arg_self);
 	}
 }
 /* }}} */
 	zend_fcall_info_cache *pfcc = bev->fcc_event;
 
 	PHP_EVENT_ASSERT(pfci && pfcc);
+	PHP_EVENT_ASSERT(bevent);
 	PHP_EVENT_ASSERT(bev->bevent == bevent);
 	PHP_EVENT_ASSERT(bev->self);
 
+
 	zval  *arg_data   = bev->data;
 	zval  *arg_events;
+	zval  *arg_self;
 	zval **args[3];
 	zval  *retval_ptr;
 
 	TSRMLS_FETCH_FROM_CTX(bev->thread_ctx);
 
 	if (ZEND_FCI_INITIALIZED(*pfci)) {
+#ifdef HAVE_EVENT_PTHREADS_LIB
+		if (bevent) {
+			bufferevent_lock(bevent);
+		}
+#endif
+
 		/* Setup callback args */
+
+		arg_self = bev->self;
+		if (arg_self) {
+			Z_ADDREF_P(arg_self);
+		} else {
+			ALLOC_INIT_ZVAL(arg_self);
+		}
 		args[0] = &bev->self;
 
 		MAKE_STD_ZVAL(arg_events);
 
         zval_ptr_dtor(&arg_events);
         zval_ptr_dtor(&arg_data);
+
+		PHP_EVENT_ASSERT(bevent);
+#ifdef HAVE_EVENT_PTHREADS_LIB
+		if (bevent) {
+			bufferevent_unlock(bevent);
+		}
+#endif
+		zval_ptr_dtor(&arg_self);
 	}
 }
 /* }}} */
 
 	PHP_EVENT_FETCH_BEVENT(bev, zself);
 
+#ifdef HAVE_EVENT_PTHREADS_LIB
+	options |= BEV_OPT_THREADSAFE;
+#endif
 	bevent = bufferevent_socket_new(base->base, fd, options);
 	if (bevent == NULL) {
 		php_error_docref(NULL TSRMLS_CC, E_ERROR,
 		bev->bevent = 0;
 
 		/* Do it once */
-		zval_ptr_dtor(&bev->self);
+		if (bev->self) {
+			zval_ptr_dtor(&bev->self);
+			bev->self = NULL;
+		}
 	}
 }
 /* }}} */
 		RETURN_FALSE;
 	}
 
+#ifdef HAVE_EVENT_PTHREADS_LIB
+	options |= BEV_OPT_THREADSAFE;
+#endif
 	bevent = bufferevent_openssl_filter_new(base->base,
     		bev_underlying->bevent,
     		ssl, state, options);
 	/* Attach ectx to ssl for callbacks */
 	SSL_set_ex_data(ssl, php_event_ssl_data_index, ectx);
 
+#ifdef HAVE_EVENT_PTHREADS_LIB
+	options |= BEV_OPT_THREADSAFE;
+#endif
 	bevent = bufferevent_openssl_socket_new(base->base, fd, ssl, state, options);
 	if (bevent == NULL) {
 		php_error_docref(NULL TSRMLS_CC, E_ERROR,
 #endif
 
 /* {{{ proto bool Event::setPriority(int priority);
- * Make event pending. */
+ * Set event priority. */
 PHP_METHOD(Event, setPriority)
 {
 	zval        *zevent = getThis();

classes/ssl_context.c

 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
 {
 	SSL                      *ssl;
-	X509                     *err_cert;
 	int                       ret      = preverify_ok;
 	int                       err;
 	int                       depth;
 	PHP_EVENT_ASSERT(ectx && ectx->ht);
 	ht = ectx->ht;
 
-	err_cert = X509_STORE_CTX_get_current_cert(ctx);
+	X509_STORE_CTX_get_current_cert(ctx);
 	err      = X509_STORE_CTX_get_error(ctx);
 	depth    = X509_STORE_CTX_get_error_depth(ctx);
 
 PHP_ARG_WITH(event-core, for event core support,
 [  --with-event-core        Include core libevent support])
 
+PHP_ARG_WITH(event-pthreads, for event thread safety support,
+[  --with-event-pthreads    Include libevent's pthreads library and enable thread safety support in event], yes, no)
+
 PHP_ARG_WITH(event-extra, for event extra functionality support,
 [  --with-event-extra       Include libevent protocol-specific functionality support including HTTP, DNS, and RPC], yes, no)
 
     EVENT_LIBS="-L$EVENT_DIR/$PHP_LIBDIR"
     EVENT_LIBDIR=$EVENT_DIR/$PHP_LIBDIR
   fi
-  LDFLAGS="$EVENT_LIBS -levent_core $LDFLAGS"
+  LDFLAGS="$EVENT_LIBS -levent_core -levent_pthreads $LDFLAGS"
 
   dnl {{{ event_core
 	AC_CHECK_LIB(event_core, event_free, [
     classes/event_util.c"
   dnl }}}
 
+  dnl {{{ --with-event-pthreads
+  if test "$PHP_EVENT_PTHREADS" != "no"; then
+	  AC_CHECK_LIB(event_pthreads, evthread_use_pthreads, [
+	    PHP_ADD_LIBRARY_WITH_PATH(event_pthreads, $EVENT_LIBDIR, EVENT_SHARED_LIBADD)
+      LDFLAGS="-lpthread -levent_pthreads $LDFLAGS"
+      AC_DEFINE(HAVE_EVENT_PTHREADS_LIB, 1, [ ])
+	  ], [
+      AC_MSG_ERROR([evthread_use_pthreads not found in event_pthreads library, or the library is not installed])
+	  ])
+  fi
+  dnl }}}
+
   dnl {{{ --with-event-extra
   if test "$PHP_EVENT_EXTRA" != "no"; then
     AC_CHECK_LIB(event_extra, evdns_base_free, [
     <email>osmanov@php.net</email>
     <active>yes</active>
   </lead>
-  <date>2013-03-05</date>
+  <date>2013-03-08</date>
   <!--{{{ Current version -->
   <version>
-    <release>1.2.7</release>
+    <release>1.3.0</release>
     <api>1.3.1</api>
   </version>
   <stability>
   Add: Event::$data property
   Fix: Event::__construct failed with Event::TIMEOUT flag
   Fix: memory leak in EventBuffer::readLine
+  Add: --with-event-pthreads configure option
+  Fix: EventBase::reInit method's arginfo
   ]]></notes>
   <!--}}}-->
   <!--{{{ Contents -->
   <extsrcrelease>
     <configureoption default="no" name="enable-event-debug" prompt="Enable internal debugging in event"/>
     <configureoption default="/usr" name="with-event-libevent-dir" prompt="libevent installation prefix"/>
+    <configureoption default="yes" name="with-event-pthreads" prompt="Include libevent's pthreads library and enable thread safety support in event"/>
     <configureoption default="yes" name="with-event-extra" prompt="Include libevent protocol-specific functionality support including HTTP, DNS, and RPC"/>
     <configureoption default="yes" name="with-event-openssl" prompt="Include libevent OpenSSL support"/>
     <configureoption default="no" name="with-openssl-dir" prompt="openssl installation prefix"/>
   </extsrcrelease>
   <!--{{{ changelog-->
   <changelog>
-    <!--{{{ 1.2.7-beta-->
+    <!--{{{ 1.3.0-beta-->
     <release>
       <version>
-        <release>1.2.7</release>
+        <release>1.3.0</release>
         <api>1.3.1</api>
       </version>
       <stability>
   Add: Event::$data property
   Fix: Event::__construct failed with Event::TIMEOUT flag
   Fix: memory leak in EventBuffer::readLine
+  Add: --with-event-pthreads configure option
+  Fix: EventBase::reInit method's arginfo
   ]]></notes>
     </release>
     <!--}}}-->
 		PHP_EVENT_FREE_FCALL_INFO(b->fci_write, b->fcc_write);
 		PHP_EVENT_FREE_FCALL_INFO(b->fci_event, b->fcc_event);
 
-#if 0
+		/* XXX */
 		if (b->self) {
 			zval_ptr_dtor(&b->self);
 			b->self = NULL;
 		}
-#endif
+
+		if (b->bevent) {
+			bufferevent_free(b->bevent);
+			b->bevent = NULL;
+		}
+
 		if (b->input) {
 			zval_ptr_dtor(&b->input);
 			b->input = NULL;
 			zval_ptr_dtor(&b->output);
 			b->output= NULL;
 		}
-
-		if (b->bevent) {
-			bufferevent_free(b->bevent);
-			b->bevent = NULL;
-		}
 	}
 
 	event_generic_object_free_storage(ptr TSRMLS_CC);
     php_event_ssl_data_index = SSL_get_ex_new_index(0, "PHP EventSslContext index", NULL, NULL, NULL);
 #endif /* HAVE_EVENT_OPENSSL_LIB */
 
+#ifdef HAVE_EVENT_PTHREADS_LIB
+# ifdef WIN32
+# error "Windows is not supported right now"
+	evthread_use_windows_threads();
+# else
+	evthread_use_pthreads();
+# endif
+#endif
+
 	/* Handle libevent's error logging more gracefully than it's default
 	 * logging to stderr, or calling abort()/exit() */
 	event_set_fatal_callback(fatal_error_cb);
 	event_set_log_callback(log_cb);
+
 #ifdef PHP_EVENT_DEBUG
 	event_enable_debug_mode();
+# ifdef HAVE_EVENT_PTHREADS_LIB
+	evthread_enable_lock_debuging();
+# endif
 #endif
 
 	return SUCCESS;
 #else
 	php_info_print_table_row(2, "OpenSSL support", "disabled");
 #endif
+#ifdef HAVE_EVENT_PTHREADS_LIB
+	php_info_print_table_row(2, "Thread safety support", "enabled");
+#else
+	php_info_print_table_row(2, "Thread safety support", "disabled");
+#endif
 
 	php_info_print_table_row(2, "Version", PHP_EVENT_VERSION);
 	php_info_print_table_end();
 #ifndef PHP_EVENT_H
 #define PHP_EVENT_H
 
-#define PHP_EVENT_VERSION "1.2.7-beta"
+#define PHP_EVENT_VERSION "1.3.0-beta"
 
 
 extern zend_module_entry event_module_entry;
 #include <event2/buffer.h>
 #include <event2/util.h>
 
+#ifdef HAVE_EVENT_PTHREADS_LIB
+# include <event2/thread.h>
+#endif
+
 #ifdef HAVE_EVENT_EXTRA_LIB
 # include <event2/listener.h>
 # include <event2/dns.h>
 	ZEND_ARG_INFO(0, flags)
 ZEND_END_ARG_INFO();
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_event_reinit, 0, 0, 1)
-	ZEND_ARG_INFO(0, base)
-ZEND_END_ARG_INFO();
-
 ZEND_BEGIN_ARG_INFO_EX(arginfo_evtimer_new, 0, 0, 2)
 	ZEND_ARG_INFO(0, base)
 	ZEND_ARG_INFO(0, cb)
 	PHP_ME(EventBase, gotStop,            arginfo_event__void,              ZEND_ACC_PUBLIC)
 	PHP_ME(EventBase, gotExit,            arginfo_event__void,              ZEND_ACC_PUBLIC)
 	PHP_ME(EventBase, getTimeOfDayCached, arginfo_event__void,              ZEND_ACC_PUBLIC)
-	PHP_ME(EventBase, reInit,             arginfo_event_reinit,             ZEND_ACC_PUBLIC)
+	PHP_ME(EventBase, reInit,             arginfo_event__void,              ZEND_ACC_PUBLIC)
 #if LIBEVENT_VERSION_NUMBER >= 0x02010100
 	PHP_ME(EventBase, updateCacheTime, arginfo_event__void, ZEND_ACC_PUBLIC)
 #endif
 	REPLACE_ZVAL_VALUE(ppz, value, 1);
 }
 
-static inline void _prop_read_zval(const zval *pz, zval **retval)
+static inline void _prop_read_zval(zval *pz, zval **retval)
 {
 	if (!pz) {
 		ALLOC_INIT_ZVAL(*retval);
 	}
 
     MAKE_STD_ZVAL(*retval);
-    REPLACE_ZVAL_VALUE(retval, pz, 1);
+    /*REPLACE_ZVAL_VALUE(retval, pz, 1);*/
+    ZVAL_ZVAL(*retval, pz, 1, 0);
 }
 
 
 }
 /* }}} */
 
+
 /* {{{ event_data_prop_get_ptr_ptr */
 static zval **event_data_prop_get_ptr_ptr(php_event_abstract_object_t *obj TSRMLS_DC)
 {
 /* }}} */
 
 
-
 /* {{{ event_buffer_length_prop_read */
 static int event_buffer_length_prop_read(php_event_abstract_object_t *obj, zval **retval TSRMLS_DC)
 {
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.