Commits

Ruslan Osmanov committed 5362d56

Add: evsignal_new, evsignal_add, evsignal_del, evsignal_pending

Comments (0)

Files changed (4)

 }
 /* }}} */
 
+/* {{{ signal_cb */
+static void signal_cb(evutil_socket_t signum, short what, void *arg)
+{
+	php_event_t *e = (php_event_t *) arg;
+
+	PHP_EVENT_ASSERT(e);
+	PHP_EVENT_ASSERT(what & EV_SIGNAL);
+	PHP_EVENT_ASSERT(e->fci && e->fcc);
+
+	zend_fcall_info     *pfci       = e->fci;
+	zval                *arg_data   = e->data;
+	zval                *arg_signum;
+	zval               **args[2];
+	zval                *retval_ptr;
+
+	TSRMLS_FETCH_FROM_CTX(e->thread_ctx);
+
+	if (ZEND_FCI_INITIALIZED(*pfci)) {
+		/* Setup callback args */
+		MAKE_STD_ZVAL(arg_signum);
+		ZVAL_LONG(arg_signum, signum);
+		args[0] = &arg_signum;
+
+		if (arg_data) {
+			Z_ADDREF_P(arg_data);
+		} else {
+			ALLOC_INIT_ZVAL(arg_data);
+		}
+		args[1] = &arg_data;
+
+		/* Prepare callback */
+		pfci->params		 = args;
+		pfci->retval_ptr_ptr = &retval_ptr;
+		pfci->param_count	 = 2;
+		pfci->no_separation  = 1;
+
+        if (zend_call_function(pfci, e->fcc TSRMLS_CC) == SUCCESS
+                && retval_ptr) {
+            zval_ptr_dtor(&retval_ptr);
+        } else {
+            php_error_docref(NULL TSRMLS_CC, E_WARNING,
+                    "An error occurred while invoking the callback");
+        }
+
+        zval_ptr_dtor(&arg_data);
+        zval_ptr_dtor(&arg_signum);
+	}
+}
+/* }}} */
+
 /* {{{ bevent_rw_cb
  * Is called from the bufferevent read and write callbacks */
 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)
 
 
 
+/* {{{ proto resource evsignal_new(resource base, int signum, callable cb[, zval arg = NULL]);
+ * Creates new signal event */
+PHP_FUNCTION(evsignal_new)
+{
+	zval                  *zbase;
+	php_event_base_t      *base;
+	long                   signum;
+	zend_fcall_info        fci    = empty_fcall_info;
+	zend_fcall_info_cache  fcc    = empty_fcall_info_cache;
+	zval                  *arg    = NULL;
+	php_event_t           *e;
+	struct event          *event;
+	
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlf|z",
+				&zbase, &signum, &fci, &fcc, &arg) == FAILURE) {
+		return;
+	}
+	
+	if (signum < 0 || signum >= NSIG) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid signal passed");
+		RETURN_FALSE;
+	}
+
+	PHP_EVENT_FETCH_BASE(base, zbase);
+
+	e = emalloc(sizeof(php_event_t));
+	memset(e, 0, sizeof(php_event_t));
+
+	event = evsignal_new(base, signum, signal_cb, (void *) e);
+	if (!event) {
+		efree(e);
+		RETURN_FALSE;
+	}
+
+	e->event = event;
+
+	if (arg) {
+		Z_ADDREF_P(arg);
+	}
+	e->data = arg;
+
+	PHP_EVENT_COPY_FCALL_INFO(e->fci, e->fcc, &fci, &fcc);
+
+	TSRMLS_SET_CTX(e->thread_ctx);
+
+	e->stream_id = -1; /* stdin fd = 0 */
+
+	ZEND_REGISTER_RESOURCE(return_value, e, le_event);
+}
+/* }}} */
+
+
 /* {{{ proto resource event_new(resource base, mixed fd, int what, callable cb[, zval arg = NULL]);
  * Creates new event */
 PHP_FUNCTION(event_new)

examples/signal.php

 		$this->base = $base;
 	}
 
-	function eventSighandler($no, $events, $c) {
-		if ($events & EVENT_SIGNAL) {
-			echo "Caught signal $no\n"; 
-        	event_base_loopexit($c->base);
-		} else {
-			echo "Unknown error. Stopping\n";
-        	event_base_loopexit($c->base);
-		}
+	function eventSighandler($no, $c) {
+		echo "Caught signal $no\n"; 
+        event_base_loopexit($c->base);
 	}
 }
 
 $base = event_base_new();
 $c    = new MyEventSignal($base);
 $no   = SIGTERM;
-$ev   = event_new($base, $no, EVENT_SIGNAL | EVENT_PERSIST, array($c,'eventSighandler'), $c);
+$ev   = evsignal_new($base, $no, array($c,'eventSighandler'), $c);
 
-event_add($ev);
+evsignal_add($ev);
 
 event_base_loop($base);
 ?>
 ZEND_END_ARG_INFO();
 
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_evsignal_new, 0, 0, 3)
+	ZEND_ARG_INFO(0, base)
+	ZEND_ARG_INFO(0, signum)
+	ZEND_ARG_INFO(0, cb)
+	ZEND_ARG_INFO(0, arg)
+ZEND_END_ARG_INFO();
+
+
 #if LIBEVENT_VERSION_NUMBER >= 0x02010000
 ZEND_BEGIN_ARG_INFO_EX(arginfo_event_config_set_max_dispatch_interval, 0, 0, 4)
 	ZEND_ARG_INFO(0, cfg)
 	PHP_FALIAS(evtimer_add, event_add, arginfo_event_add)
 	PHP_FALIAS(evtimer_del, event_del, arginfo_event_1)
 
+	PHP_FE(evsignal_new,     arginfo_evsignal_new)
+
+	PHP_FALIAS(evsignal_add,     event_add,     arginfo_event_add)
+	PHP_FALIAS(evsignal_del,     event_del,     arginfo_event_1)
+	PHP_FALIAS(evsignal_pending, event_pending, arginfo_event_pending)
+
 	PHP_FE(event_base_new,                 arginfo_event__void)
 	PHP_FE(event_base_new_with_config,     arginfo_event_base_config_1)
 	PHP_FE(event_base_free,                arginfo_event_base_1)
 PHP_FUNCTION(evtimer_set);
 PHP_FUNCTION(evtimer_pending);
 
+PHP_FUNCTION(evsignal_new);
+
 PHP_FUNCTION(event_base_new);
 PHP_FUNCTION(event_base_new_with_config);
 PHP_FUNCTION(event_base_get_method);