From dabdda8f86374f90b440f069e3bc73dc2ffe9a3d Mon Sep 17 00:00:00 2001 From: matyhtf Date: Wed, 21 Aug 2013 14:24:24 +0800 Subject: [PATCH] add pcntl_daemonize & pcntl_setaffinity. --- ext/pcntl/config.m4 | 2 + ext/pcntl/pcntl.c | 81 ++++++++++++++++++++++++++ ext/pcntl/php_pcntl.h | 6 ++ ext/pcntl/tests/pcntl_daemonize.phpt | 15 +++++ ext/pcntl/tests/pcntl_setaffinity.phpt | 16 +++++ 5 files changed, 120 insertions(+) create mode 100644 ext/pcntl/tests/pcntl_daemonize.phpt create mode 100644 ext/pcntl/tests/pcntl_setaffinity.phpt diff --git a/ext/pcntl/config.m4 b/ext/pcntl/config.m4 index 2ef07f140c0cb..f5382c18fd4a0 100644 --- a/ext/pcntl/config.m4 +++ b/ext/pcntl/config.m4 @@ -10,5 +10,7 @@ if test "$PHP_PCNTL" != "no"; then AC_CHECK_FUNCS(waitpid, [ AC_DEFINE(HAVE_WAITPID,1,[ ]) ], [ AC_MSG_ERROR(pcntl: waitpid() not supported by this platform) ]) AC_CHECK_FUNCS(sigaction, [ AC_DEFINE(HAVE_SIGACTION,1,[ ]) ], [ AC_MSG_ERROR(pcntl: sigaction() not supported by this platform) ]) AC_CHECK_FUNCS([getpriority setpriority wait3 sigprocmask sigwaitinfo sigtimedwait]) + AC_CHECK_FUNCS(daemon, [ AC_DEFINE(HAVE_DAEMON,1,[ ]) ], [ AC_MSG_ERROR(pcntl: daemon() not supported by this platform) ]) + AC_CHECK_FUNCS(sched_setaffinity, [ AC_DEFINE(HAVE_SCHED_SETAFFINITY,1,[ ]) ], [ AC_MSG_ERROR(pcntl: sched_setaffinity() not supported by this platform) ]) PHP_NEW_EXTENSION(pcntl, pcntl.c php_signal.c, $ext_shared, cli) fi diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index b66f4722e8108..c8ea10d19dbae 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -44,6 +44,13 @@ #include #endif +#ifdef HAVE_SCHED_SETAFFINITY +#ifndef __USE_GNU +#define __USE_GNU +#endif +#include +#endif + #include ZEND_DECLARE_MODULE_GLOBALS(pcntl) @@ -137,6 +144,20 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_setpriority, 0, 0, 1) ZEND_END_ARG_INFO() #endif +#ifdef HAVE_DAEMON + ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_daemonize, 0, 0, 0) + ZEND_ARG_INFO(0, nochdir) + ZEND_ARG_INFO(0, noclose) + ZEND_END_ARG_INFO() +#endif + +#ifdef HAVE_SCHED_SETAFFINITY + ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_setaffinity, 0, 0, 2) + ZEND_ARG_INFO(0, pid) + ZEND_ARG_INFO(0, cpu_id) + ZEND_END_ARG_INFO() +#endif + ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_strerror, 0, 0, 1) ZEND_ARG_INFO(0, errno) ZEND_END_ARG_INFO() @@ -171,6 +192,12 @@ const zend_function_entry pcntl_functions[] = { #if HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT PHP_FE(pcntl_sigwaitinfo, arginfo_pcntl_sigwaitinfo) PHP_FE(pcntl_sigtimedwait, arginfo_pcntl_sigtimedwait) +#endif +#ifdef HAVE_DAEMON + PHP_FE(pcntl_daemonize, arginfo_pcntl_daemonize) +#endif +#ifdef HAVE_SCHED_SETAFFINITY + PHP_FE(pcntl_setaffinity, arginfo_pcntl_setaffinity) #endif PHP_FE_END }; @@ -202,6 +229,11 @@ static void pcntl_signal_dispatch(); void php_register_signal_constants(INIT_FUNC_ARGS) { +#ifdef HAVE_SCHED_SETAFFINITY + /* cpu affinity*/ + REGISTER_LONG_CONSTANT("PCNTL_CPU_NUM", (long) sysconf(_SC_NPROCESSORS_ONLN), CONST_CS | CONST_PERSISTENT); +#endif + /* Wait Constants */ #ifdef WNOHANG REGISTER_LONG_CONSTANT("WNOHANG", (long) WNOHANG, CONST_CS | CONST_PERSISTENT); @@ -1178,6 +1210,55 @@ PHP_FUNCTION(pcntl_setpriority) /* }}} */ #endif +#ifdef HAVE_SCHED_SETAFFINITY +/* {{{ proto bool pcntl_setaffinity(int pid, int cpu_id) + set the cpu affinity of any process */ +PHP_FUNCTION(pcntl_setaffinity) +{ + long pid, cpu; + cpu_set_t cpu_set; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &pid, &cpu) == FAILURE) { + return; + } + int cpu_num = sysconf(_SC_NPROCESSORS_ONLN); + if (cpu >= cpu_num) { + zend_error(E_WARNING, "cpu[%ld] not exists.", cpu); + RETURN_FALSE; + } + CPU_ZERO(&cpu_set); + CPU_SET(cpu, &cpu_set); + + if (sched_setaffinity(pid, sizeof(cpu_set), &cpu_set) < 0) { + zend_error(E_WARNING, "set cpu affinity fail. errno=%d", errno); + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ +#endif + +#ifdef HAVE_DAEMON +/* {{{ proto bool pcntl_daemonize(int nochdir, int noclose) + run in the background */ +PHP_FUNCTION(pcntl_daemonize) +{ + long nochdir = 0, noclose = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &nochdir, &noclose) == FAILURE) { + return; + } + + if (daemon(nochdir, noclose) < 0) { + zend_error(E_WARNING, "daemonize fail. errno=%d", errno); + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ +#endif + + /* {{{ proto int pcntl_get_last_error(void) Retrieve the error number set by the last pcntl function which failed. */ PHP_FUNCTION(pcntl_get_last_error) diff --git a/ext/pcntl/php_pcntl.h b/ext/pcntl/php_pcntl.h index 280a45bbaffc0..b38895c76ce51 100644 --- a/ext/pcntl/php_pcntl.h +++ b/ext/pcntl/php_pcntl.h @@ -58,6 +58,12 @@ PHP_FUNCTION(pcntl_getpriority); #ifdef HAVE_SETPRIORITY PHP_FUNCTION(pcntl_setpriority); #endif +#ifdef HAVE_DAEMON +PHP_FUNCTION(pcntl_daemonize); +#endif +#ifdef HAVE_SCHED_SETAFFINITY +PHP_FUNCTION(pcntl_setaffinity); +#endif struct php_pcntl_pending_signal { struct php_pcntl_pending_signal *next; diff --git a/ext/pcntl/tests/pcntl_daemonize.phpt b/ext/pcntl/tests/pcntl_daemonize.phpt new file mode 100644 index 0000000000000..55e612e5b7645 --- /dev/null +++ b/ext/pcntl/tests/pcntl_daemonize.phpt @@ -0,0 +1,15 @@ +--TEST-- +pcntl_daemonize() +--SKIPIF-- + +--FILE-- + +--EXPECT-- +ok diff --git a/ext/pcntl/tests/pcntl_setaffinity.phpt b/ext/pcntl/tests/pcntl_setaffinity.phpt new file mode 100644 index 0000000000000..53b85bafcb93d --- /dev/null +++ b/ext/pcntl/tests/pcntl_setaffinity.phpt @@ -0,0 +1,16 @@ +--TEST-- +pcntl_setaffinity() +--SKIPIF-- + +--FILE-- + +--EXPECT-- +ok