Commits

Ruslan Osmanov committed 8a20b47

Add: EvEmbed
Fix: EvCheck and EvPerpare arginfos pointed to another class methods

  • Participants
  • Parent commits 4c763a0

Comments (0)

Files changed (9)

+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2012 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Ruslan Osmanov <osmanov@php.net>                             |
+   +----------------------------------------------------------------------+
+*/
+#include "watcher.h"
+
+/* {{{ proto EvEmbed::__construct(EvLoop other, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
+PHP_METHOD(EvEmbed, __construct)
+{
+	zval                  *self;
+	php_ev_object         *o_self;
+	php_ev_object         *o_loop;
+	php_ev_object         *o_loop_other;
+	ev_embed              *embed_watcher;
+	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;
+	}
+
+	o_loop_other   = (php_ev_object *) zend_object_store_get_object(loop_other TSRMLS_CC);
+	loop_other_ptr = PHP_EV_LOOP_FETCH_FROM_OBJECT(o_loop_other);
+
+	if (!(ev_backend(loop_other_ptr) & ev_embeddable_backends())) {
+        php_error_docref(NULL TSRMLS_CC, E_ERROR,
+        		"Passed loop is not embeddable. Check out your backends.");
+        return;
+	}
+
+	PHP_EV_ASSERT(loop_other_ptr);
+
+	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);
+
+	php_ev_set_watcher((ev_watcher *)embed_watcher, sizeof(ev_embed), self,
+			PHP_EV_LOOP_OBJECT_FETCH_FROM_OBJECT(o_loop),
+			&fci, &fcc, data, priority TSRMLS_CC);
+
+	embed_watcher->type = EV_EMBED;
+
+	ev_embed_set(embed_watcher, PHP_EV_LOOP_FETCH_FROM_OBJECT(o_loop_other));
+
+	o_self->ptr = (void *) embed_ptr;
+}
+/* }}} */
+
+/* {{{ proto void EvEmbed::set(EvLoop other) */
+PHP_METHOD(EvEmbed, set)
+{
+	zval          *loop_other;
+	ev_embed      *embed_watcher;
+	php_ev_object *o_loop_other;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O",
+				&loop_other) == FAILURE) {
+		return;
+	}
+
+	o_loop_other  = (php_ev_object *) zend_object_store_get_object(loop_other TSRMLS_CC);
+	embed_watcher = (ev_embed *) PHP_EV_WATCHER_FETCH_FROM_THIS();
+
+	PHP_EV_ASSERT(PHP_EV_LOOP_FETCH_FROM_OBJECT(o_loop_other));
+	PHP_EV_WATCHER_RESET(ev_embed, embed_watcher, (embed_watcher, PHP_EV_LOOP_FETCH_FROM_OBJECT(o_loop_other)));
+}
+/* }}} */
+
+/* {{{ proto void EvEmbed::sweep(void) */
+PHP_METHOD(EvEmbed, sweep)
+{
+	ev_embed *embed_watcher;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	embed_watcher = (ev_embed *) PHP_EV_WATCHER_FETCH_FROM_THIS();
+
+	ev_embed_sweep(php_ev_watcher_loop_ptr(embed_watcher), embed_watcher);
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 sts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4 sts=4
+ */
  */
 
 typedef struct php_ev_periodic {
-	struct ev_periodic     periodic;     /* Contains common watcher vars embedded         */
-	zend_fcall_info       *fci;   /* fci/fcc store specific "rescheduler" callback */
+	struct ev_periodic     periodic;   /* Contains common watcher vars embedded         */
+	zend_fcall_info       *fci;        /* fci/fcc store specific "rescheduler" callback */
 	zend_fcall_info_cache *fcc;
 } php_ev_periodic;
 
 typedef struct php_ev_stat {
-	struct ev_stat  stat;   /* Contains common watcher vars embedded */
+	struct ev_stat  stat;   /* Extending ev_stat */
 	char           *path;
 } php_ev_stat;
 
+typedef struct php_ev_embed {
+	struct ev_embed  embed;   /* Extending ev_embed */
+	zval            *other;   /* Loop to embed      */
+} php_ev_embed;
+
 #endif /* PHP_EV_EMBED_H */
 /*
  * Local variables:
 #if EV_PREPARE_ENABLE
 zend_class_entry *ev_prepare_class_entry_ptr;
 #endif
+#if EV_EMBED_ENABLE
+zend_class_entry *ev_embed_class_entry_ptr;
+#endif
 
 static HashTable classes;
 static HashTable php_ev_properties;
 #if EV_STAT_ENABLE
 static HashTable php_ev_stat_properties;
 #endif
+#if EV_EMBED_ENABLE
+static HashTable php_ev_embed_properties;
+#endif
 
 static zend_object_handlers ev_object_handlers;
 
 /* }}} */
 #endif
 
+#if EV_EMBED_ENABLE
+/* {{{ php_ev_embed_free_storage() */
+static void php_ev_embed_free_storage(void *object TSRMLS_DC)
+{
+	php_ev_object *obj_ptr = (php_ev_object *) object;
+
+	PHP_EV_ASSERT(obj_ptr->ptr);
+
+	ev_embed *ptr           = (ev_embed *) obj_ptr->ptr;
+	php_ev_embed *embed_ptr = (php_ev_embed *) obj_ptr->ptr;
+
+	if (embed_ptr->other) {
+		zval_ptr_dtor(&embed_ptr->other);
+	}
+
+	/* Free base class members */
+	php_ev_watcher_free_storage((ev_watcher *) ptr TSRMLS_CC);
+
+	/* Free common Ev object members and the object itself */
+	php_ev_object_free_storage(object TSRMLS_CC);
+}
+/* }}} */
+#endif
+
 /* {{{ php_ev_register_object 
  * Is called AFTER php_ev_object_new() */
 zend_object_value php_ev_register_object(zend_class_entry *ce, php_ev_object *intern TSRMLS_DC)
 #endif
 #if EV_PREPARE_ENABLE
 	} else if (instanceof_function(ce, ev_prepare_class_entry_ptr TSRMLS_CC)) {
-		/* EvCheck */
+		/* EvPrepare */
 	 	func_free_storage = php_ev_prepare_free_storage;
 #endif
+#if EV_EMBED_ENABLE
+	} else if (instanceof_function(ce, ev_embed_class_entry_ptr TSRMLS_CC)) {
+		/* EvEmbed */
+	 	func_free_storage = php_ev_embed_free_storage;
+#endif
 	} else {
 	 	func_free_storage = php_ev_object_free_storage;
 	}
 	zend_hash_add(&classes, ce->name, ce->name_length + 1, &php_ev_watcher_properties, sizeof(php_ev_watcher_properties), NULL);
 	/* }}} */
 #endif
+
+#if EV_EMBED_ENABLE
+	/* {{{ EvEmbed */
+	PHP_EV_REGISTER_CLASS_ENTRY_EX("EvEmbed", ev_embed_class_entry_ptr, ev_embed_class_entry_functions, ev_watcher_class_entry_ptr);
+	ce = ev_embed_class_entry_ptr;
+	zend_hash_init(&php_ev_embed_properties, 0, NULL, NULL, 1);
+	PHP_EV_ADD_CLASS_PROPERTIES(&php_ev_embed_properties, ev_embed_property_entries);
+	zend_hash_merge(&php_ev_embed_properties, &php_ev_watcher_properties, NULL, NULL, sizeof(php_ev_prop_handler), 0);
+	PHP_EV_DECL_CLASS_PROPERTIES(ce, ev_embed_property_entry_info);
+	zend_hash_add(&classes, ce->name, ce->name_length + 1, &php_ev_embed_properties, sizeof(php_ev_embed_properties), NULL);
+	/* }}} */
+#endif
 }
 /* }}} */
 
 #if EV_STAT_ENABLE
 	zend_hash_destroy(&php_ev_stat_properties);
 #endif
+#if EV_EMBED_ENABLE
+	zend_hash_destroy(&php_ev_embed_properties);
+#endif
+
 	zend_hash_destroy(&classes);
 
 	return SUCCESS;
 #if EV_PREPARE_ENABLE
 # include "prepare.c";
 #endif
+#if EV_EMBED_ENABLE
+# include "embed.c";
+#endif
 
 #endif /* HAVE_EV */
 
 /* }}} */
 #endif
 
+#if EV_EMBED_ENABLE
+/* {{{ EvEmbed */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ev_embed, 0, 0, 2)
+	ZEND_ARG_INFO(0, loop)
+	ZEND_ARG_INFO(0, other)
+	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_embed_set, 0, 0, 1)
+	ZEND_ARG_INFO(0, other)
+ZEND_END_ARG_INFO();
+/* }}} */
+#endif
+
 /* ARGINFO }}} */
 
 
 #if EV_CHECK_ENABLE
 /* {{{ ev_check_class_entry_functions */
 const zend_function_entry ev_check_class_entry_functions[] = {
-	PHP_ME(EvIdle, __construct, arginfo_ev_check, ZEND_ACC_PUBLIC  | ZEND_ACC_CTOR)
+	PHP_ME(EvCheck, __construct, arginfo_ev_check, ZEND_ACC_PUBLIC  | ZEND_ACC_CTOR)
 	{ NULL, NULL, NULL }
 };
 /* }}} */
 #if EV_PREPARE_ENABLE
 /* {{{ ev_prepare_class_entry_functions */
 const zend_function_entry ev_prepare_class_entry_functions[] = {
-	PHP_ME(EvIdle, __construct, arginfo_ev_prepare, ZEND_ACC_PUBLIC  | ZEND_ACC_CTOR)
+	PHP_ME(EvPrepare, __construct, arginfo_ev_prepare, ZEND_ACC_PUBLIC  | ZEND_ACC_CTOR)
 	{ NULL, NULL, NULL }
 };
 /* }}} */
 #endif
 
+#if EV_EMBED_ENABLE
+/* {{{ ev_embed_class_entry_functions */
+const zend_function_entry ev_embed_class_entry_functions[] = {
+	PHP_ME(EvEmbed, __construct, arginfo_ev_embed,     ZEND_ACC_PUBLIC  | ZEND_ACC_CTOR)
+	PHP_ME(EvEmbed, set,         arginfo_ev_embed_set, ZEND_ACC_PUBLIC)
+	PHP_ME(EvEmbed, sweep,       arginfo_ev__void,     ZEND_ACC_PUBLIC)
+	{ NULL, NULL, NULL }
+};
+/* }}} */
+#endif
 /*
  * Local variables:
  * tab-width: 4
 /* }}} */
 #endif
 
+#if EV_EMBED_ENABLE
+/* {{{ EvEmbed */
+PHP_METHOD(EvEmbed, __construct);
+PHP_METHOD(EvEmbed, set);
+PHP_METHOD(EvEmbed, sweep);
+/* }}} */
+#endif
+
 #endif /* PHP_EV_FE_H */
 
 /* 
                                              \
         MAKE_STD_ZVAL(*retval);              \
         REPLACE_ZVAL_VALUE(retval, data, 1); \
-                                             \
     } while (0)
 
 #define PHP_EV_PROP_ZVAL_WRITE(ppz)                                     \
 {
 	PHP_EV_ASSERT(obj->ptr);
 
-	/*ev_stat *stat_watcher = (ev_stat *) PHP_EV_WATCHER_FETCH_FROM_OBJECT(obj);*/
 	php_ev_stat *stat_ptr = (php_ev_stat *) PHP_EV_WATCHER_FETCH_FROM_OBJECT(obj);
 
-
 	MAKE_STD_ZVAL(*retval);
 	ZVAL_STRING(*retval, stat_ptr->path, 1);
 
 /* }}} */
 #endif
 
+#if EV_EMBED_ENABLE
+/* {{{ EvEmbed property handlers */
+
+/* {{{ ev_embed_prop_other_read */
+static int ev_embed_prop_other_read(php_ev_object *obj, zval **retval TSRMLS_DC)
+{
+	PHP_EV_ASSERT(obj->ptr);
+
+	php_ev_embed *embed_ptr = (php_ev_embed *) PHP_EV_WATCHER_FETCH_FROM_OBJECT(obj);
+
+	PHP_EV_PROP_ZVAL_READ(embed_ptr->other);
+
+	return SUCCESS;
+}
+/* }}} */
+
+/* }}} */
+#endif
+
 /* {{{ ev_loop_property_entries[] */
 const php_ev_property_entry ev_loop_property_entries[] = {
 	{"data",            sizeof("data")            - 1, ev_loop_prop_data_read,            ev_loop_prop_data_write},
 /* }}} */
 #endif
 
+#if EV_EMBED_ENABLE
+/* {{{ ev_embed_property_entries[] */
+const php_ev_property_entry ev_embed_property_entries[] = {
+	{"other", sizeof("other") - 1, ev_embed_prop_other_read, NULL},
+    {NULL, 0, NULL, NULL}
+};
+/* }}} */
+
+/* {{{ ev_embed_property_entry_info[] */
+const zend_property_info ev_embed_property_entry_info[] = {
+	{ZEND_ACC_PUBLIC, "embed", sizeof("embed") - 1, -1, 0, NULL, 0, NULL},
+	{0, NULL, 0, -1, 0, NULL, 0, NULL},
+};
+/* }}} */
+#endif
+
 /*
  * Local variables:
  * tab-width: 4
 extern const zend_function_entry ev_idle_class_entry_functions[];
 extern const zend_function_entry ev_check_class_entry_functions[];
 extern const zend_function_entry ev_prepare_class_entry_functions[];
+extern const zend_function_entry ev_embed_class_entry_functions[];
 
 extern const php_ev_property_entry ev_test_property_entries[];
 extern const php_ev_property_entry ev_loop_property_entries[];
 extern const php_ev_property_entry ev_signal_property_entries[];
 extern const php_ev_property_entry ev_child_property_entries[];
 extern const php_ev_property_entry ev_stat_property_entries[];
+extern const php_ev_property_entry ev_embed_property_entries[];
 
 extern const zend_property_info ev_test_property_entry_info[];
 extern const zend_property_info ev_loop_property_entry_info[];
 extern const zend_property_info ev_signal_property_entry_info[];
 extern const zend_property_info ev_child_property_entry_info[];
 extern const zend_property_info ev_stat_property_entry_info[];
+extern const zend_property_info ev_embed_property_entry_info[];
 
 #endif /* PHP_EV_PRIV_H */
 
 	struct ev_watcher     *w;                          /* Head of linked list                                      */
 } php_ev_loop;
 
-#if 0
-/* php_ev_periodic is special type for periodic watcher.
- * I.e. we don't want to embed extra members into EV_COMMON
- * Extends ev_watcher
- */
-
-typedef struct php_ev_periodic {
-	struct ev_watcher      w;     /* Contains common watcher vars embedded         */
-	zend_fcall_info       *fci;   /* fci/fcc store specific "rescheduler" callback */
-	zend_fcall_info_cache *fcc;
-} php_ev_periodic;
-#endif
-
 /* Property handlers */
 
 typedef int (*php_ev_read_t)(php_ev_object  *obj, zval **retval TSRMLS_DC);