Commits

Ruslan Osmanov committed 75a0fd8

Add: EvLoop factory methods for the watcher classes
Fix: EvFork constructor param parsing

Comments (0)

Files changed (19)

 */
 #include "watcher.h"
 
-/* {{{ proto EvCheck::__construct(EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
-PHP_METHOD(EvCheck, __construct)
+/* {{{ php_ev_check_object_ctor */
+void php_ev_check_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
-	zval          *self;
-	php_ev_object *o_self;
-	php_ev_object *o_loop;
-	ev_check      *check_watcher;
-
-	zval                  *loop;
-	zval                  *data       = NULL;
-	zend_fcall_info        fci        = empty_fcall_info;
-	zend_fcall_info_cache  fcc        = empty_fcall_info_cache;
-	long                   priority   = 0;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Of|z!l",
-				&loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+	zval                  *self;
+	php_ev_object         *o_self;
+	php_ev_object         *o_loop;
+	ev_check              *check_watcher;
+
+	zval                  *data          = NULL;
+	zend_fcall_info        fci           = empty_fcall_info;
+	zend_fcall_info_cache  fcc           = empty_fcall_info_cache;
+	long                   priority      = 0;
+
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f|z!l",
+					&fci, &fcc, &data, &priority) == FAILURE) {
+			return;
+		}
+
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_check_class_entry_ptr);
+
+		self = return_value; 
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Of|z!l",
+					&loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
-	self          = getThis();
 	o_self        = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
 	o_loop        = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 	check_watcher = (ev_check *) php_ev_new_watcher(sizeof(ev_check), self,
 }
 /* }}} */
 
+
+/* {{{ proto EvCheck::__construct(EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvCheck, __construct)
+{
+	php_ev_check_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
+}
+/* }}} */
+
 /*
  * Local variables:
  * tab-width: 4
 */
 #include "watcher.h"
 
-/* {{{ proto EvChild::__construct(int pid, bool trace, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
-PHP_METHOD(EvChild, __construct)
+/* {{{ php_ev_child_object_ctor */
+void php_ev_child_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
-	long           pid;
-	zend_bool      trace;
-	zval          *self;
-	php_ev_object *o_self;
-	php_ev_object *o_loop;
-	ev_child      *child_watcher;
-
-	zval                  *loop;
-	zval                  *data       = NULL;
-	zend_fcall_info        fci        = empty_fcall_info;
-	zend_fcall_info_cache  fcc        = empty_fcall_info_cache;
-	long                   priority   = 0;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lbOf|z!l",
-				&pid, &trace, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+	long                   pid;
+	zend_bool              trace;
+	zval                  *self;
+	php_ev_object         *o_self;
+	php_ev_object         *o_loop;
+	ev_child              *child_watcher;
+
+	zval                  *data          = NULL;
+	zend_fcall_info        fci           = empty_fcall_info;
+	zend_fcall_info_cache  fcc           = empty_fcall_info_cache;
+	long                   priority      = 0;
+
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lbf|z!l",
+					&pid, &trace, &fci, &fcc, &data, &priority) == FAILURE) {
+			return;
+		}
+
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_child_class_entry_ptr);
+
+		self = return_value; 
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lbOf|z!l",
+					&pid, &trace, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
-	self          = getThis();
 	o_self        = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
 	o_loop        = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 	child_watcher = (ev_child *) php_ev_new_watcher(sizeof(ev_child), self,
 	ev_child_set(child_watcher, pid, trace);
 
 	o_self->ptr = (void *) child_watcher;
+
+}
+/* }}} */
+
+/* {{{ proto EvChild::__construct(int pid, bool trace, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvChild, __construct)
+{
+	php_ev_child_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
 }
 /* }}} */
 
 */
 #include "watcher.h"
 
-/* {{{ proto EvEmbed::__construct(EvLoop other, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
-PHP_METHOD(EvEmbed, __construct)
+/* {{{ php_ev_embed_object_ctor */
+void php_ev_embed_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
-	zval                  *self;
+	zval                  *self = NULL;
 	php_ev_object         *o_self;
 	php_ev_object         *o_loop;
 	php_ev_object         *o_loop_other;
 	ev_loop               *loop_other_ptr;
 	php_ev_embed          *embed_ptr;
 
-	zval                  *loop;
 	zval                  *loop_other;
 	zval                  *data           = NULL;
 	zend_fcall_info        fci            = empty_fcall_info;
 	zend_fcall_info_cache  fcc            = empty_fcall_info_cache;
 	long                   priority       = 0;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO|fz!l",
-				&loop_other, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|fz!l",
+					&loop_other, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO|fz!l",
+					&loop_other, ev_loop_class_entry_ptr,
+					&loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
 	o_loop_other   = (php_ev_object *) zend_object_store_get_object(loop_other TSRMLS_CC);
 
 	PHP_EV_ASSERT(loop_other_ptr);
 
+	if (!self) { /* Factory */
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_embed_class_entry_ptr);
+		self = return_value; 
+	}
+
 	embed_ptr = (php_ev_embed *) emalloc(sizeof(php_ev_embed));
 	memset(embed_ptr, 0, sizeof(php_ev_embed));
 
 	embed_watcher = &embed_ptr->embed;
 
-	self          = getThis();
 	o_self        = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
 	o_loop        = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 
 }
 /* }}} */
 
+
+/* {{{ proto EvEmbed::__construct(EvLoop other, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvEmbed, __construct)
+{
+	php_ev_embed_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
+}
+/* }}} */
+
 /* {{{ proto void EvEmbed::set(EvLoop other) */
 PHP_METHOD(EvEmbed, set)
 {
 */
 
 #include "php_ev.h"
+#include "util.h"
 
 #if HAVE_EV
 
 }
 /* }}} */
 
+
 /* Private functions }}} */
 
 
 /* }}} */
 
 
-#include "loop.c" 
 #include "io.c"
 #include "timer.c"
 #if EV_PERIODIC_ENABLE
 #if EV_FORK_ENABLE
 # include "fork.c"
 #endif
+#include "loop.c" 
 
 
 /* {{{ Global functions */
 	ZEND_ARG_INFO(0, signum)
 ZEND_END_ARG_INFO();
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_io, 0, 0, 3)
+	ZEND_ARG_INFO(0, fd)
+	ZEND_ARG_INFO(0, events)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_timer, 0, 0, 3)
+	ZEND_ARG_INFO(0, after)
+	ZEND_ARG_INFO(0, repeat)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+
+#if EV_PERIODIC_ENABLE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_periodic, 0, 0, 3)
+	ZEND_ARG_INFO(0, offset)
+	ZEND_ARG_INFO(0, interval)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+#endif
+#if EV_SIGNAL_ENABLE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_signal, 0, 0, 2)
+	ZEND_ARG_INFO(0, signum)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+#endif
+#if EV_CHILD_ENABLE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_child, 0, 0, 3)
+	ZEND_ARG_INFO(0, pid)
+	ZEND_ARG_INFO(0, trace)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+#endif
+#if EV_STAT_ENABLE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_stat, 0, 0, 3)
+	ZEND_ARG_INFO(0, path)
+	ZEND_ARG_INFO(0, interval)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+#endif
+#if EV_IDLE_ENABLE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_idle, 0, 0, 1)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+#endif
+#if EV_CHECK_ENABLE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_check, 0, 0, 1)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+#endif
+#if EV_PREPARE_ENABLE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_prepare, 0, 0, 1)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+#endif
+#if EV_EMBED_ENABLE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_embed, 0, 0, 1)
+	ZEND_ARG_INFO(0, other)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+#endif
+#if EV_FORK_ENABLE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_loop_fork, 0, 0, 1)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, data)
+	ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO();
+#endif
+
 /* EvLoop }}} */
 
 /* {{{ EvWatcher */
 
 /* {{{ ev_loop_class_entry_functions */
 const zend_function_entry ev_loop_class_entry_functions[] = {
-	PHP_ME(EvLoop, __construct,          arginfo_ev_default_loop,      ZEND_ACC_PUBLIC  | ZEND_ACC_CTOR)
-	PHP_ME(EvLoop, default_loop,         arginfo_ev_default_loop,      ZEND_ACC_PUBLIC  | ZEND_ACC_STATIC)
-	PHP_ME(EvLoop, loop_fork,            arginfo_ev__void,             ZEND_ACC_PUBLIC)
-	PHP_ME(EvLoop, verify,               arginfo_ev__void,             ZEND_ACC_PUBLIC)
-	PHP_ME(EvLoop, invoke_pending,       arginfo_ev__void,             ZEND_ACC_PUBLIC)
-	PHP_ME(EvLoop, now_update,           arginfo_ev__void,             ZEND_ACC_PUBLIC)
-	PHP_ME(EvLoop, suspend,              arginfo_ev__void,             ZEND_ACC_PUBLIC)
-	PHP_ME(EvLoop, resume,               arginfo_ev__void,             ZEND_ACC_PUBLIC)
-	PHP_ME(EvLoop, now,                  arginfo_ev__void,             ZEND_ACC_PUBLIC)
-	PHP_ME(EvLoop, run,                  arginfo_ev_run,               ZEND_ACC_PUBLIC)
-	PHP_ME(EvLoop, break,                arginfo_ev_break,             ZEND_ACC_PUBLIC)
-	PHP_ME(EvLoop, feed_signal_event,    arginfo_ev_feed_signal_event, ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, __construct,       arginfo_ev_default_loop,      ZEND_ACC_PUBLIC  | ZEND_ACC_CTOR)
+	PHP_ME(EvLoop, default_loop,      arginfo_ev_default_loop,      ZEND_ACC_PUBLIC  | ZEND_ACC_STATIC)
+	PHP_ME(EvLoop, loop_fork,         arginfo_ev__void,             ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, verify,            arginfo_ev__void,             ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, invoke_pending,    arginfo_ev__void,             ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, now_update,        arginfo_ev__void,             ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, suspend,           arginfo_ev__void,             ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, resume,            arginfo_ev__void,             ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, now,               arginfo_ev__void,             ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, run,               arginfo_ev_run,               ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, break,             arginfo_ev_break,             ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, feed_signal_event, arginfo_ev_feed_signal_event, ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, io,                arginfo_ev_loop_io,           ZEND_ACC_PUBLIC)
+	PHP_ME(EvLoop, timer,             arginfo_ev_loop_timer,        ZEND_ACC_PUBLIC)
+#if EV_PERIODIC_ENABLE
+	PHP_ME(EvLoop, periodic,          arginfo_ev_loop_periodic,     ZEND_ACC_PUBLIC)
+#endif
+#if EV_SIGNAL_ENABLE
+	PHP_ME(EvLoop, signal,            arginfo_ev_loop_signal,       ZEND_ACC_PUBLIC)
+#endif
+#if EV_CHILD_ENABLE
+	PHP_ME(EvLoop, child,             arginfo_ev_loop_child,        ZEND_ACC_PUBLIC)
+#endif
+#if EV_STAT_ENABLE
+	PHP_ME(EvLoop, stat,              arginfo_ev_loop_stat,         ZEND_ACC_PUBLIC)
+#endif
+#if EV_IDLE_ENABLE
+	PHP_ME(EvLoop, idle,              arginfo_ev_loop_idle,         ZEND_ACC_PUBLIC)
+#endif
+#if EV_CHECK_ENABLE
+	PHP_ME(EvLoop, check,             arginfo_ev_loop_check,        ZEND_ACC_PUBLIC)
+#endif
+#if EV_PREPARE_ENABLE
+	PHP_ME(EvLoop, prepare,           arginfo_ev_loop_prepare,      ZEND_ACC_PUBLIC)
+#endif
+#if EV_EMBED_ENABLE
+	PHP_ME(EvLoop, embed,             arginfo_ev_loop_embed,        ZEND_ACC_PUBLIC)
+#endif
+#if EV_FORK_ENABLE
+	PHP_ME(EvLoop, fork,              arginfo_ev_loop_fork,         ZEND_ACC_PUBLIC)
+#endif
 
 	{ NULL, NULL, NULL }
 };
 PHP_METHOD(EvLoop, run);
 PHP_METHOD(EvLoop, break);
 PHP_METHOD(EvLoop, feed_signal_event);
+PHP_METHOD(EvLoop, io);
+PHP_METHOD(EvLoop, timer);
+#if EV_PERIODIC_ENABLE
+PHP_METHOD(EvLoop, periodic);
+#endif
+#if EV_SIGNAL_ENABLE
+PHP_METHOD(EvLoop, signal);
+#endif
+#if EV_CHILD_ENABLE
+PHP_METHOD(EvLoop, child);
+#endif
+#if EV_STAT_ENABLE
+PHP_METHOD(EvLoop, stat);
+#endif
+#if EV_IDLE_ENABLE
+PHP_METHOD(EvLoop, idle);
+#endif
+#if EV_CHECK_ENABLE
+PHP_METHOD(EvLoop, check);
+#endif
+#if EV_PREPARE_ENABLE
+PHP_METHOD(EvLoop, prepare);
+#endif
+#if EV_EMBED_ENABLE
+PHP_METHOD(EvLoop, embed);
+#endif
+#if EV_FORK_ENABLE
+PHP_METHOD(EvLoop, fork);
+#endif
 /* }}} */
 
 /* {{{ EvWatcher */
 */
 #include "watcher.h"
 
-/* {{{ proto EvFork::__construct(EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
-PHP_METHOD(EvFork, __construct)
+/* {{{ php_ev_fork_object_ctor */
+void php_ev_fork_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
-	zval          *self;
-	php_ev_object *o_self;
-	php_ev_object *o_loop;
-	ev_fork      *fork_watcher;
-
-	zval                  *loop;
-	zval                  *data       = NULL;
-	zend_fcall_info        fci        = empty_fcall_info;
-	zend_fcall_info_cache  fcc        = empty_fcall_info_cache;
-	long                   priority   = 0;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Of|z!l",
-				&loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+	zval                  *self;
+	php_ev_object         *o_self;
+	php_ev_object         *o_loop;
+	ev_fork               *fork_watcher;
+
+	zval                  *data         = NULL;
+	zend_fcall_info        fci          = empty_fcall_info;
+	zend_fcall_info_cache  fcc          = empty_fcall_info_cache;
+	long                   priority     = 0;
+
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f|z!l",
+					&fci, &fcc, &data, &priority) == FAILURE) {
+			return;
+		}
+
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_fork_class_entry_ptr);
+
+		self = return_value; 
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Of|z!l",
+					&loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
-	self          = getThis();
 	o_self        = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
 	o_loop        = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 	fork_watcher = (ev_fork *) php_ev_new_watcher(sizeof(ev_fork), self,
 }
 /* }}} */
 
+
+/* {{{ proto EvFork::__construct(EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvFork, __construct)
+{
+	php_ev_fork_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
+}
+/* }}} */
+
 /*
  * Local variables:
  * tab-width: 4
 */
 #include "watcher.h"
 
-/* {{{ proto EvIdle::__construct(EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
-PHP_METHOD(EvIdle, __construct)
+/* {{{ php_ev_idle_object_ctor */
+void php_ev_idle_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
-	zval          *self;
-	php_ev_object *o_self;
-	php_ev_object *o_loop;
-	ev_idle      *idle_watcher;
-
-	zval                  *loop;
-	zval                  *data       = NULL;
-	zend_fcall_info        fci        = empty_fcall_info;
-	zend_fcall_info_cache  fcc        = empty_fcall_info_cache;
-	long                   priority   = 0;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Of|z!l",
-				&loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+	zval                  *self;
+	php_ev_object         *o_self;
+	php_ev_object         *o_loop;
+	ev_idle               *idle_watcher;
+
+	zval                  *data         = NULL;
+	zend_fcall_info        fci          = empty_fcall_info;
+	zend_fcall_info_cache  fcc          = empty_fcall_info_cache;
+	long                   priority     = 0;
+
+
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f|z!l",
+					&fci, &fcc, &data, &priority) == FAILURE) {
+			return;
+		}
+
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_idle_class_entry_ptr);
+
+		self = return_value; 
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Of|z!l",
+					&loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
-	self          = getThis();
-	o_self        = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
-	o_loop        = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
+	o_self       = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
+	o_loop       = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 	idle_watcher = (ev_idle *) php_ev_new_watcher(sizeof(ev_idle), self,
 			PHP_EV_LOOP_OBJECT_FETCH_FROM_OBJECT(o_loop),
 			&fci, &fcc, data, priority TSRMLS_CC);
 }
 /* }}} */
 
+/* {{{ proto EvIdle::__construct(EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvIdle, __construct)
+{
+	php_ev_idle_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
+}
+/* }}} */
+
 /*
  * Local variables:
  * tab-width: 4
 #include "util.h"
 #include "watcher.h"
 
-/* {{{ proto EvIo::__construct(mixed fd, int events, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
-PHP_METHOD(EvIo, __construct)
+/* {{{ php_ev_io_object_ctor */
+void php_ev_io_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
-	zval                  *self;
+	zval                  *self       = NULL;
 	zval                  *z_fd;
 	php_ev_object         *o_self;
 	php_ev_object         *o_loop;
 	ev_io                 *io_watcher;
-	php_socket_t          fd;
+	php_socket_t           fd;
 
-	zval                  *loop;
 	zval                  *data       = NULL;
 	zend_fcall_info        fci        = empty_fcall_info;
 	zend_fcall_info_cache  fcc        = empty_fcall_info_cache;
 	long                   priority   = 0;
 	long                   events;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zlOf|z!l",
-				&z_fd, &events, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zlf|z!l",
+					&z_fd, &events, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zlOf|z!l",
+					&z_fd, &events, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
 	if (events & ~(EV_READ | EV_WRITE)) {
 		return;
 	}
 
-	self    = getThis();
+	if (!self) { /* Factory */
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_io_class_entry_ptr);
+		self = return_value; 
+	}
+
 	o_self  = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
 	o_loop  = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 	io_watcher = (ev_io *) php_ev_new_watcher(sizeof(ev_io), self,
 
 	io_watcher->type = EV_IO;
 	
-#if 0
-	php_stream *fd_stream;
-	php_stream_from_zval_no_verify(fd_stream, &z_fd);
-	if (fd_stream == NULL) {
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed obtaining fd");
-		return;
-	}
-	ev_io_set(io_watcher, Z_LVAL_P(z_fd), events);
-#endif
 	ev_io_set(io_watcher, fd, events);
 
 	o_self->ptr = (void *) io_watcher;
 }
 /* }}} */
 
+
+/* {{{ proto EvIo::__construct(mixed fd, int events, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvIo, __construct)
+{
+	php_ev_io_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
+}
+/* }}} */
+
 /* {{{ proto void EvIo::set(resource fd, int events) */
 PHP_METHOD(EvIo, set)
 {
 }
 /* }}} */
 
+/* {{{ proto EvIo EvLoop::io(mixed fd, int events, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvLoop, io)
+{
+	php_ev_io_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+
+/* {{{ proto EvTimer EvLoop::timer(double after, double repeat, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvLoop, timer)
+{
+	php_ev_timer_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+
+#if EV_PERIODIC_ENABLE
+/* {{{ proto EvPeriodic EvLoop::periodic(double offset, double interval, callable reschedule_cb, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvLoop, periodic)
+{
+	php_ev_periodic_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+#endif
+
+#if EV_SIGNAL_ENABLE
+/* {{{ proto EvSignal EvLoop::signal(int signum, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvLoop, signal)
+{
+	php_ev_signal_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+#endif
+
+#if EV_CHILD_ENABLE
+/* {{{ proto EvChild EvLoop::child(int pid, bool trace, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvLoop, child)
+{
+	php_ev_child_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+#endif
+
+#if EV_STAT_ENABLE
+/* {{{ proto EvStat EvLoop::stat(string path, double interval, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvLoop, stat)
+{
+	php_ev_stat_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+#endif
+
+#if EV_IDLE_ENABLE
+/* {{{ proto EvIdle EvLoop::idle(callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvLoop, idle)
+{
+	php_ev_idle_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+#endif
+
+#if EV_CHECK_ENABLE
+/* {{{ proto EvCheck EvLoop::check() */
+PHP_METHOD(EvLoop, check)
+{
+	php_ev_check_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+#endif
+
+#if EV_PREPARE_ENABLE
+/* {{{ proto EvPrepare EvLoop::prepare() */
+PHP_METHOD(EvLoop, prepare)
+{
+	php_ev_prepare_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+#endif
+
+#if EV_EMBED_ENABLE
+/* {{{ proto EvEmbed EvLoop::embed() */
+PHP_METHOD(EvLoop, embed)
+{
+	php_ev_embed_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+#endif
+
+#if EV_FORK_ENABLE
+/* {{{ proto EvFork EvLoop::fork() */
+PHP_METHOD(EvLoop, fork)
+{
+	php_ev_fork_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, getThis());
+}
+/* }}} */
+#endif
+
 /*
  * Local variables:
  * tab-width: 4
     ce->create_object = parent_ce->create_object; /*php_ev_object_create; */    \
 }
 
+#define PHP_EV_INIT_CLASS_OBJECT(pz, pce) \
+        Z_TYPE_P(pz) = IS_OBJECT;         \
+        object_init_ex(pz, pce);          \
+        Z_SET_REFCOUNT_P(pz, 1);          \
+        Z_UNSET_ISREF_P(pz);
+
 #define PHP_EV_ADD_CLASS_PROPERTIES(a, b)                                                      \
 {                                                                                              \
     int i = 0;                                                                                 \
 {
 	PHP_EV_ASSERT(obj->ptr);
 
-	php_ev_loop *loop_obj = PHP_EV_LOOP_OBJECT_FETCH_FROM_OBJECT(obj);
-
 	MAKE_STD_ZVAL(*retval);
 	ZVAL_LONG(*retval, ev_depth(PHP_EV_LOOP_FETCH_FROM_OBJECT(obj)));
 
 }
 /* }}} */
 
-
-/* {{{ proto EvPeriodic::__construct(double offset, double interval, callable reschedule_cb, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) 
- * NOTE: reschedule_cb could be NULL */
-PHP_METHOD(EvPeriodic, __construct)
+/* {{{ php_ev_periodic_object_ctor */
+void php_ev_periodic_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
 	double                 offset;
 	double                 interval;
 	zend_fcall_info        fci_reschedule;
 	zend_fcall_info_cache  fcc_reschedule;
 
-	zval                  *self;
+	zval                  *self             = NULL;
 	php_ev_object         *o_self;
 	php_ev_object         *o_loop;
 	ev_periodic           *periodic_watcher;
 	php_ev_periodic       *periodic_ptr;
 
-	zval                  *loop;
 	zval                  *data             = NULL;
 	zend_fcall_info        fci              = empty_fcall_info;
 	zend_fcall_info_cache  fcc              = empty_fcall_info_cache;
 	long                   priority         = 0;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddf!Of|z!l",
-				&offset, &interval, &fci_reschedule, &fcc_reschedule,
-				&loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddf!f|z!l",
+					&offset, &interval, &fci_reschedule, &fcc_reschedule,
+					&fci, &fcc, &data, &priority) == FAILURE) {
+			return;
+		}
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddf!Of|z!l",
+					&offset, &interval, &fci_reschedule, &fcc_reschedule,
+					&loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
 	PHP_EV_CHECK_REPEAT(interval);
 
+	if (!self) { /* Factory */
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_periodic_class_entry_ptr);
+		self = return_value; 
+	}
+
 	periodic_ptr = (php_ev_periodic *) emalloc(sizeof(php_ev_periodic));
 	memset(periodic_ptr, 0, sizeof(php_ev_periodic));
 
 	periodic_watcher = &periodic_ptr->periodic;
 
-	self             = getThis();
 	o_self           = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
 	o_loop           = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 
 
 	o_self->ptr = (void *) periodic_ptr;
 }
+
+/* }}} */
+
+
+/* {{{ proto EvPeriodic::__construct(double offset, double interval, callable reschedule_cb, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) 
+ * NOTE: reschedule_cb could be NULL */
+PHP_METHOD(EvPeriodic, __construct)
+{
+	php_ev_periodic_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
+}
 /* }}} */
 
 /* {{{ proto void EvPeriodic::set(double offset, double interval[, callable reschedule_cb]) */
 */
 #include "watcher.h"
 
-/* {{{ proto EvPrepare::__construct(EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
-PHP_METHOD(EvPrepare, __construct)
+/* {{{ php_ev_prepare_object_ctor */
+void php_ev_prepare_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
 	zval                  *self;
 	php_ev_object         *o_self;
 	php_ev_object         *o_loop;
 	ev_prepare            *prepare_watcher;
 
-	zval                  *loop;
 	zval                  *data            = NULL;
 	zend_fcall_info        fci             = empty_fcall_info;
 	zend_fcall_info_cache  fcc             = empty_fcall_info_cache;
 	long                   priority        = 0;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Of|z!l",
-				&loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f|z!l",
+					&fci, &fcc, &data, &priority) == FAILURE) {
+			return;
+		}
+
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_prepare_class_entry_ptr);
+
+		self = return_value; 
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Of|z!l",
+					&loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
-	self            = getThis();
 	o_self          = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
 	o_loop          = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 	prepare_watcher = (ev_prepare *) php_ev_new_watcher(sizeof(ev_prepare), self,
 }
 /* }}} */
 
+
+/* {{{ proto EvPrepare::__construct(EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvPrepare, __construct)
+{
+	php_ev_prepare_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
+}
+/* }}} */
+
 /*
  * Local variables:
  * tab-width: 4
 extern const zend_property_info ev_stat_property_entry_info[];
 extern const zend_property_info ev_embed_property_entry_info[];
 
+void php_ev_io_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop);
+void php_ev_timer_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop);
+void php_ev_periodic_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop);
+void php_ev_child_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop);
+void php_ev_stat_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop);
+void php_ev_idle_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop);
+void php_ev_check_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop);
+void php_ev_prepare_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop);
+void php_ev_embed_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop);
+void php_ev_fork_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop);
+
 #endif /* PHP_EV_PRIV_H */
 
 /*
 */
 #include "watcher.h"
 
-/* {{{ proto EvSignal::__construct(int signum, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
-PHP_METHOD(EvSignal, __construct)
+/* {{{ php_ev_signal_object_ctor */
+void php_ev_signal_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
 	long           signum;
 	zval          *self;
 	php_ev_object *o_loop;
 	ev_signal     *signal_watcher;
 
-	zval                  *loop;
 	zval                  *data       = NULL;
 	zend_fcall_info        fci        = empty_fcall_info;
 	zend_fcall_info_cache  fcc        = empty_fcall_info_cache;
 	long                   priority   = 0;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lOf|z!l",
-				&signum, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lf|z!l",
+					&signum, &fci, &fcc, &data, &priority) == FAILURE) {
+			return;
+		}
+
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_periodic_class_entry_ptr);
+
+		self = return_value; 
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lOf|z!l",
+					&signum, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
-	self          = getThis();
 	o_self        = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
 	o_loop        = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 	signal_watcher = (ev_signal *) php_ev_new_watcher(sizeof(ev_signal), self,
 }
 /* }}} */
 
+/* {{{ proto EvSignal::__construct(int signum, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvSignal, __construct)
+{
+	php_ev_signal_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
+}
+/* }}} */
+
 /* {{{ proto void EvSignal::set(int signum) */
 PHP_METHOD(EvSignal, set)
 {
 }
 /* }}} */
 
-
-/* {{{ proto EvStat::__construct(string path, double interval, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
-PHP_METHOD(EvStat, __construct)
+/* {{{ php_ev_stat_object_ctor */
+void php_ev_stat_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
 	char                  *path;
 	int                    path_len;
 	double                 interval;
-	zval                  *self;
+	zval                  *self         = NULL;
 	php_ev_object         *o_self;
 	php_ev_object         *o_loop;
 	ev_stat               *stat_watcher;
 	php_ev_stat           *stat_ptr;
 
-	zval                  *loop;
 	zval                  *data         = NULL;
 	zend_fcall_info        fci          = empty_fcall_info;
 	zend_fcall_info_cache  fcc          = empty_fcall_info_cache;
 	long                   priority     = 0;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pdOf|z!l",
-				&path, &path_len, &interval, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pdf|z!l",
+					&path, &path_len, &interval, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_stat_class_entry_ptr);
+
+		self = return_value; 
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pdOf|z!l",
+					&path, &path_len, &interval, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
 	stat_ptr = (php_ev_stat *) emalloc(sizeof(php_ev_stat));
 
 	stat_watcher = &stat_ptr->stat;
 
-	self         = getThis();
 	o_self       = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
 	o_loop       = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 
 }
 /* }}} */
 
+/* {{{ proto EvStat::__construct(string path, double interval, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvStat, __construct)
+{
+	php_ev_stat_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
+}
+/* }}} */
+
 /* {{{ proto void EvStat::set(string path, double interval) */
 PHP_METHOD(EvStat, set)
 {
 */
 #include "watcher.h"
 
-/* {{{ proto EvTimer::__construct(double after, double repeat, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
-PHP_METHOD(EvTimer, __construct)
+/* {{{ php_ev_timer_object_ctor */
+void php_ev_timer_object_ctor(INTERNAL_FUNCTION_PARAMETERS, zval *loop)
 {
 	double         after;
 	double         repeat;
-	zval          *self;
+	zval          *self          = NULL;
 	php_ev_object *o_self;
 	php_ev_object *o_loop;
 	ev_timer      *timer_watcher;
 
-	zval                  *loop;
 	zval                  *data       = NULL;
 	zend_fcall_info        fci        = empty_fcall_info;
 	zend_fcall_info_cache  fcc        = empty_fcall_info_cache;
 	long                   priority   = 0;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddOf|z!l",
-				&after, &repeat, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
-				&data, &priority) == FAILURE) {
-		return;
+	if (loop) { /* Factory */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddf|z!l",
+					&after, &repeat, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+	} else { /* Ctor */
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddOf|z!l",
+					&after, &repeat, &loop, ev_loop_class_entry_ptr, &fci, &fcc,
+					&data, &priority) == FAILURE) {
+			return;
+		}
+
+		self = getThis();
 	}
 
 	PHP_EV_CHECK_REPEAT(repeat);
 
-	self          = getThis();
+	if (!self) { /* Factory */
+		PHP_EV_INIT_CLASS_OBJECT(return_value, ev_timer_class_entry_ptr);
+		self = return_value; 
+	}
+
 	o_self        = (php_ev_object *) zend_object_store_get_object(self TSRMLS_CC);
 	o_loop        = (php_ev_object *) zend_object_store_get_object(loop TSRMLS_CC);
 	timer_watcher = (ev_timer *) php_ev_new_watcher(sizeof(ev_timer), self,
 }
 /* }}} */
 
+
+/* {{{ proto EvTimer::__construct(double after, double repeat, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvTimer, __construct)
+{
+	php_ev_timer_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL);
+}
+/* }}} */
+
 /* {{{ proto void EvTimer::set(double after, double repeat) */
 PHP_METHOD(EvTimer, set)
 {
 		/* PHP stream or PHP socket resource  */
 		if (ZEND_FETCH_RESOURCE_NO_RETURN(stream, php_stream *, ppfd, -1, NULL, php_file_le_stream())) {
 			/* PHP stream */
-			if (php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL,
-						(void*) &file_desc, 1) != SUCCESS || file_desc < 0) {
-				return -1;
+			if (php_stream_can_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL)) {
+				if (php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL,
+							(void*) &file_desc, 1) != SUCCESS || file_desc < 0) {
+					return -1;
+				}
+			} else if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO | PHP_STREAM_CAST_INTERNAL)) {
+				if (php_stream_cast(stream, PHP_STREAM_AS_STDIO | PHP_STREAM_CAST_INTERNAL,
+							(void*) &file_desc, 1) != SUCCESS || file_desc < 0) {
+					return -1;
+				}
+			} else { /* STDIN, STDOUT, STDERR etc. */
+				php_stream_from_zval_no_verify(stream, ppfd);
+				if (stream == NULL) {
+					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed obtaining fd");
+					return -1;
+				}
+				file_desc = Z_LVAL_P(*ppfd);
 			}
 		} else {
 			/* PHP socket resource */
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.