-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New function: pcntl_daemonize & pcntl_setaffinity. #416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,13 @@ | |
#include <sys/resource.h> | ||
#endif | ||
|
||
#ifdef HAVE_SCHED_SETAFFINITY | ||
#ifndef __USE_GNU | ||
#define __USE_GNU | ||
#endif | ||
#include <sched.h> | ||
#endif | ||
|
||
#include <errno.h> | ||
|
||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather made it more readable: daemonize() falied with error %s (errno %d) and also use strerror for actual error message, since errno is rarely very informative by itself. |
||
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) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
--TEST-- | ||
pcntl_daemonize() | ||
--SKIPIF-- | ||
<?php | ||
if (!extension_loaded("pcntl")) print "skip"; | ||
?> | ||
--FILE-- | ||
<?php | ||
echo "ok. Processor will run in the background\n"; | ||
pcntl_daemonize(); | ||
sleep(10000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is a good idea to do this in a test. |
||
echo "hello world\n"; | ||
?> | ||
--EXPECT-- | ||
ok |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--TEST-- | ||
pcntl_setaffinity() | ||
--SKIPIF-- | ||
<?php | ||
if (!extension_loaded("pcntl")) print "skip"; | ||
if (!extension_loaded("posix")) print "skip"; | ||
?> | ||
--FILE-- | ||
<?php | ||
echo "ok. Please run 'taskset -pc ".posix_getpid()."'\n"; | ||
var_dump(pcntl_setaffinity(posix_getpid(), 0)); | ||
echo "Binding the cpu0\n"; | ||
sleep(10000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is a good idea for a test. |
||
?> | ||
--EXPECT-- | ||
ok | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it how this test works for you? Where did the rest of the echoed message go? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've read __USE_GNU shouldn't be used directly: http://stackoverflow.com/questions/7296963/gnu-source-and-use-gnu
Is it right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if you want to use GNU extensions, you'd probably want to define _GNU_SOURCE before including the header (just as outlined in the man page of sched_setaffinity).