com php-src: Implemented proc_nice() for Windows (FR #49806): NEWS UPGRADING UPGRADING .INTERNALS ext/standard/exec.c ext/standard/tests/gener
al_functions/proc_nice_basic-win.phpt ext/standard/te sts/general_functions/proc_nice_basic.phpt win32/ build/config.w32 win32/build/config.w32.h .in
win32/nice.c win32/nice.h
| From: | Kalle Sommer Nielsen | Date: | Sun, 16 Oct 2016 02:17:35 +0000 |
| Subject: | com php-src: Implemented proc_nice() for Windows (FR #49806): NEWS UPGRADING UPGRADING .INTERNALS ext/standard/exec.c ext/standard/tests/gener al_functions/proc_nice_basic-win.phpt ext/standard/te sts/general_functions/proc_nice_basic.phpt win32/ build/config.w32 win32/build/config.w32.h .in win32/nice.c win32/nice.h |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-95112@lists.php.net to get a copy of this message | ||
Commit: 64945e9387e415fe38c05d7e483ad2d075567336
Author: Kalle Sommer Nielsen <kalle@php.net> Sun, 16 Oct 2016 04:17:35 +0200
Parents: 2dbddf224157414da649adbb41974245c05ac8e4
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=64945e9387e415fe38c05d7e483ad2d075567336
Log:
Implemented proc_nice() for Windows (FR #49806)
The core implementation details are described in win32/nice.c for values sent to proc_nice(), these
can however be discussed to maybe comply with those of wmic, Anatol, thoughts?
The test supplied uses wmic for testing the functionality, it could potentially fail on systems
where either wmic is not available or the system language is not english (as Microsoft tends to
translate even CLI programs).
Bugs:
https://bugs..php.net/49806
Changed paths:
M NEWS
M UPGRADING
M UPGRADING.INTERNALS
M ext/standard/exec.c
A ext/standard/tests/general_functions/proc_nice_basic-win.phpt
M ext/standard/tests/general_functions/proc_nice_basic.phpt
M win32/build/config.w32
M win32/build/config.w32.h.in
A win32/nice.c
A win32/nice.h
diff --git a/NEWS b/NEWS index df57efc..1add54a 100644 --- a/NEWS +++ b/NEWS @@ -5,8 +5,9 @@ PHP NEWS - Core: . Removed the sql.safe_mode directive. (Kalle) . Fixed bug #54535 (WSA cleanup executes before MSHUTDOWN). (Kalle) - . Implemented bug #69791 (Disallow mail header injections by extra headers) + . Implemented FR #69791 (Disallow mail header injections by extra headers) (Yasuo) + . Implemented FR #49806 (proc_nice() for Windows). (Kalle) - EXIF: . Added support for vendor specific tags for the following formats: diff --git a/UPGRADING b/UPGRADING index 38250ed..b874ad6 100644 --- a/UPGRADING +++ b/UPGRADING @@ -35,6 +35,7 @@ PHP 7.2 UPGRADE NOTES - Standard: . Simplified password hashing API updated to support Argon2i hashes when PHP is compiled with libargon2 (https://wiki.php.net/rfc/argon2_password_hash). + . proc_nice() is now supported on Windows platforms. ======================================== 3. Changes in SAPI modules diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 1444589..71ade7b 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -23,6 +23,10 @@ PHP 7.1 INTERNALS UPGRADE NOTES b. Windows build system changes + * nice() now have a Windows alternative that is implemented in win32/nice.c, using + SetPriorityClass(). See the implementation for more in-depth details. This also + defines HAVE_NICE. + ======================== 3. Module changes ======================== diff --git a/ext/standard/exec.c b/ext/standard/exec.c index bf9100b..0cf2b57 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -557,7 +557,11 @@ PHP_FUNCTION(proc_nice) errno = 0; php_ignore_value(nice(pri)); if (errno) { +#ifdef PHP_WIN32 + php_error_docref(NULL, E_WARNING, php_win_err()); +#else php_error_docref(NULL, E_WARNING, "Only a super user may attempt to increase the priority of a process"); +#endif RETURN_FALSE; } diff --git a/ext/standard/tests/general_functions/proc_nice_basic-win.phpt b/ext/standard/tests/general_functions/proc_nice_basic-win.phpt new file mode 100644 index 0000000..45d7c92 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_basic-win.phpt @@ -0,0 +1,96 @@ +--TEST-- +proc_nice() basic behaviour +--SKIPIF-- +<?php +/* No function_exists() check, proc_nice() is always available on Windows */ + +if (!defined('PHP_WINDOWS_VERSION_MAJOR')) { + die('skip: Only for Windows'); +} + +if (PHP_SAPI != 'cli') { + die('skip: Only for CLI'); +} + +if (getenv('SKIP_SLOW_TESTS')) { + doe('skip: Slow test'); +} +?> +--FILE-- +<?php +function get_priority_from_wmic() { + static $bin, $pid; + + if (!$bin) { + $t = explode('\\', PHP_BINARY); + + $bin = end($t); + $pid = getmypid(); + } + + $t = ''; + $p = popen('wmic process where name="' . $bin . '"', 'r'); + + if (!$p) { + return false; + } + + while(!feof($p)) { + $t .= fread($p, 1024); + } + + pclose($p); + + $t = explode(PHP_EOL, $t); + + $f = false; + $m = [ + strpos($t[0], ' ProcessId' ), + strpos($t[0], ' Priority ') + ]; + + foreach ($t as $n => $l) { + if (!$n || empty($l)) { + continue; + } + + $d = []; + + foreach ($m as $c) { + $d[] = (int) substr($l, $c + 1, strpos($l, ' ', $c + 2) - ($c + 1)); + } + + if ($d[0] === $pid) { + return $d[1]; + } + } + + return false; +} + +$p = [ + /* '<verbose name>' => ['<wmic value>', '<proc_nice value>'] */ + + 'Idle' => [6, -10], + 'Below normal' => [4, -3], + 'Normal' => [8, 0], + 'Above normal' => [10, 4], + 'High priority' => [13, 5], + 'Real time' => [24, 8] + ]; + +foreach ($p as $test => $data) { + printf('Testing \'%s\' (%d): ', $test, $data[1]); + + proc_nice($data[1]); + + print (get_priority_from_wmic() === $data[0] ? 'Passed' : 'Failed') . PHP_EOL; +} +?> +--EXPECTF-- +Testing 'Idle' (-10): Passed +Testing 'Below normal' (-3): Passed +Testing 'Normal' (0): Passed +Testing 'Above normal' (4): Passed +Testing 'High priority' (5): Passed +Testing 'Real time' (8): Passed diff --git a/ext/standard/tests/general_functions/proc_nice_basic.phpt b/ext/standard/tests/general_functions/proc_nice_basic.phpt index 83b5165..12469bf 100644 --- a/ext/standard/tests/general_functions/proc_nice_basic.phpt +++ b/ext/standard/tests/general_functions/proc_nice_basic.phpt @@ -8,6 +8,7 @@ Simone Gentili (sensorario@gmail.com) --SKIPIF-- <?php if(!function_exists('proc_nice')) die("skip. proc_nice not available "); +if(substr(strtoupper(PHP_OS), 0, 3) == 'WIN') die('skip. not for Windows'); ?> --FILE-- <?php diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 96f801a..cc921d8 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -165,7 +165,7 @@ ADD_FLAG("CFLAGS_BD_MAIN_STREAMS", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); ADD_SOURCES("win32", "dllmain.c glob.c readdir.c \ registry.c select.c sendmail.c time.c winutil.c wsyslog.c globals.c \ - getrusage.c ftok.c ioutil.c codepage.c"); + getrusage.c ftok.c ioutil.c codepage.c nice.c"); ADD_FLAG("CFLAGS_BD_WIN32", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); diff --git a/win32/build/config.w32.h.in b/win32/build/config.w32.h.in index 2a8297a..e871088 100644 --- a/win32/build/config.w32.h.in +++ b/win32/build/config.w32.h.in @@ -175,3 +175,5 @@ #define HAVE_GETRUSAGE #define HAVE_FTOK 1 + +#define HAVE_NICE diff --git a/win32/nice.c b/win32/nice.c new file mode 100644 index 0000000..2b66a46 --- /dev/null +++ b/win32/nice.c @@ -0,0 +1,80 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2016 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. | + +----------------------------------------------------------------------+ + | Authors: Kalle Sommer Nielsen <kalle@php.net> | + +----------------------------------------------------------------------+ + */ + +#include <php.h> +#include "nice.h" + +/* + * Basic Windows implementation for the nice() function. + * + * This implementation uses SetPriorityClass() as a backend for defining + * a process priority. + * + * The following values of inc, defines the value sent to SetPriorityClass(): + * + * +-----------------------+-----------------------------+ + * | Expression | Priority type | + * +-----------------------+-----------------------------+ + * | priority > 5 | REALTIME_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority == 5 | HIGH_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority > 0 | ABOVE_NORMAL_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority == 0 | NORMAL_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority < -5 | BELOW_NORMAL_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority < -10 | IDLE_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * + * This is applied to the main process, not per thread, although this could + * be implemented using SetThreadPriority() at one point. + */ + +PHPAPI int nice(zend_long p) +{ + DWORD dwFlag = NORMAL_PRIORITY_CLASS; + + if (p > 5) { + dwFlag = REALTIME_PRIORITY_CLASS; + } else if (p == 5) { + dwFlag = HIGH_PRIORITY_CLASS; + } else if (p > 0) { + dwFlag = ABOVE_NORMAL_PRIORITY_CLASS; + } else if (p < 0 && p < -5) { + dwFlag = BELOW_NORMAL_PRIORITY_CLASS; + } else if (p < -10) { + dwFlag = IDLE_PRIORITY_CLASS; + } + + if (!SetPriorityClass(GetCurrentProcess(), dwFlag)) { + return -1; + } + + return 0; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/win32/nice.h b/win32/nice.h new file mode 100644 index 0000000..9cb77d0 --- /dev/null +++ b/win32/nice.h @@ -0,0 +1,25 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2016 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. | + +----------------------------------------------------------------------+ + | Authors: Kalle Sommer Nielsen <kalle@php.net> | + +----------------------------------------------------------------------+ + */ + +#ifndef HAVE_GETRUSAGE_H +# define HAVE_GETRUSAGE_H + +PHPAPI int nice(zend_long); + +#endif +
diff --git a/NEWS b/NEWS index df57efc..1add54a 100644 --- a/NEWS +++ b/NEWS @@ -5,8 +5,9 @@ PHP NEWS - Core: . Removed the sql.safe_mode directive. (Kalle) . Fixed bug #54535 (WSA cleanup executes before MSHUTDOWN). (Kalle) - . Implemented bug #69791 (Disallow mail header injections by extra headers) + . Implemented FR #69791 (Disallow mail header injections by extra headers) (Yasuo) + . Implemented FR #49806 (proc_nice() for Windows). (Kalle) - EXIF: . Added support for vendor specific tags for the following formats: diff --git a/UPGRADING b/UPGRADING index 38250ed..b874ad6 100644 --- a/UPGRADING +++ b/UPGRADING @@ -35,6 +35,7 @@ PHP 7.2 UPGRADE NOTES - Standard: . Simplified password hashing API updated to support Argon2i hashes when PHP is compiled with libargon2 (https://wiki.php.net/rfc/argon2_password_hash). + . proc_nice() is now supported on Windows platforms. ======================================== 3. Changes in SAPI modules diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 1444589..71ade7b 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -23,6 +23,10 @@ PHP 7.1 INTERNALS UPGRADE NOTES b. Windows build system changes + * nice() now have a Windows alternative that is implemented in win32/nice.c, using + SetPriorityClass(). See the implementation for more in-depth details. This also + defines HAVE_NICE. + ======================== 3. Module changes ======================== diff --git a/ext/standard/exec.c b/ext/standard/exec.c index bf9100b..0cf2b57 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -557,7 +557,11 @@ PHP_FUNCTION(proc_nice) errno = 0; php_ignore_value(nice(pri)); if (errno) { +#ifdef PHP_WIN32 + php_error_docref(NULL, E_WARNING, php_win_err()); +#else php_error_docref(NULL, E_WARNING, "Only a super user may attempt to increase the priority of a process"); +#endif RETURN_FALSE; } diff --git a/ext/standard/tests/general_functions/proc_nice_basic-win.phpt b/ext/standard/tests/general_functions/proc_nice_basic-win.phpt new file mode 100644 index 0000000..45d7c92 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_basic-win.phpt @@ -0,0 +1,96 @@ +--TEST-- +proc_nice() basic behaviour +--SKIPIF-- +<?php +/* No function_exists() check, proc_nice() is always available on Windows */ + +if (!defined('PHP_WINDOWS_VERSION_MAJOR')) { + die('skip: Only for Windows'); +} + +if (PHP_SAPI != 'cli') { + die('skip: Only for CLI'); +} + +if (getenv('SKIP_SLOW_TESTS')) { + doe('skip: Slow test'); +} +?> +--FILE-- +<?php +function get_priority_from_wmic() { + static $bin, $pid; + + if (!$bin) { + $t = explode('\\', PHP_BINARY); + + $bin = end($t); + $pid = getmypid(); + } + + $t = ''; + $p = popen('wmic process where name="' . $bin . '"', 'r'); + + if (!$p) { + return false; + } + + while(!feof($p)) { + $t .= fread($p, 1024); + } + + pclose($p); + + $t = explode(PHP_EOL, $t); + + $f = false; + $m = [ + strpos($t[0], ' ProcessId' ), + strpos($t[0], ' Priority ') + ]; + + foreach ($t as $n => $l) { + if (!$n || empty($l)) { + continue; + } + + $d = []; + + foreach ($m as $c) { + $d[] = (int) substr($l, $c + 1, strpos($l, ' ', $c + 2) - ($c + 1)); + } + + if ($d[0] === $pid) { + return $d[1]; + } + } + + return false; +} + +$p = [ + /* '<verbose name>' => ['<wmic value>', '<proc_nice value>'] */ + + 'Idle' => [6, -10], + 'Below normal' => [4, -3], + 'Normal' => [8, 0], + 'Above normal' => [10, 4], + 'High priority' => [13, 5], + 'Real time' => [24, 8] + ]; + +foreach ($p as $test => $data) { + printf('Testing \'%s\' (%d): ', $test, $data[1]); + + proc_nice($data[1]); + + print (get_priority_from_wmic() === $data[0] ? 'Passed' : 'Failed') . PHP_EOL; +} +?> +--EXPECTF-- +Testing 'Idle' (-10): Passed +Testing 'Below normal' (-3): Passed +Testing 'Normal' (0): Passed +Testing 'Above normal' (4): Passed +Testing 'High priority' (5): Passed +Testing 'Real time' (8): Passed diff --git a/ext/standard/tests/general_functions/proc_nice_basic.phpt b/ext/standard/tests/general_functions/proc_nice_basic.phpt index 83b5165..12469bf 100644 --- a/ext/standard/tests/general_functions/proc_nice_basic.phpt +++ b/ext/standard/tests/general_functions/proc_nice_basic.phpt @@ -8,6 +8,7 @@ Simone Gentili (sensorario@gmail.com) --SKIPIF-- <?php if(!function_exists('proc_nice')) die("skip. proc_nice not available "); +if(substr(strtoupper(PHP_OS), 0, 3) == 'WIN') die('skip. not for Windows'); ?> --FILE-- <?php diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 96f801a..cc921d8 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -165,7 +165,7 @@ ADD_FLAG("CFLAGS_BD_MAIN_STREAMS", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); ADD_SOURCES("win32", "dllmain.c glob.c readdir.c \ registry.c select.c sendmail.c time.c winutil.c wsyslog.c globals.c \ - getrusage.c ftok.c ioutil.c codepage.c"); + getrusage.c ftok.c ioutil.c codepage.c nice.c"); ADD_FLAG("CFLAGS_BD_WIN32", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); diff --git a/win32/build/config.w32.h.in b/win32/build/config.w32.h.in index 2a8297a..e871088 100644 --- a/win32/build/config.w32.h.in +++ b/win32/build/config.w32.h.in @@ -175,3 +175,5 @@ #define HAVE_GETRUSAGE #define HAVE_FTOK 1 + +#define HAVE_NICE diff --git a/win32/nice.c b/win32/nice.c new file mode 100644 index 0000000..2b66a46 --- /dev/null +++ b/win32/nice.c @@ -0,0 +1,80 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2016 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. | + +----------------------------------------------------------------------+ + | Authors: Kalle Sommer Nielsen <kalle@php.net> | + +----------------------------------------------------------------------+ + */ + +#include <php.h> +#include "nice.h" + +/* + * Basic Windows implementation for the nice() function. + * + * This implementation uses SetPriorityClass() as a backend for defining + * a process priority. + * + * The following values of inc, defines the value sent to SetPriorityClass(): + * + * +-----------------------+-----------------------------+ + * | Expression | Priority type | + * +-----------------------+-----------------------------+ + * | priority > 5 | REALTIME_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority == 5 | HIGH_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority > 0 | ABOVE_NORMAL_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority == 0 | NORMAL_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority < -5 | BELOW_NORMAL_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority < -10 | IDLE_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * + * This is applied to the main process, not per thread, although this could + * be implemented using SetThreadPriority() at one point. + */ + +PHPAPI int nice(zend_long p) +{ + DWORD dwFlag = NORMAL_PRIORITY_CLASS; + + if (p > 5) { + dwFlag = REALTIME_PRIORITY_CLASS; + } else if (p == 5) { + dwFlag = HIGH_PRIORITY_CLASS; + } else if (p > 0) { + dwFlag = ABOVE_NORMAL_PRIORITY_CLASS; + } else if (p < 0 && p < -5) { + dwFlag = BELOW_NORMAL_PRIORITY_CLASS; + } else if (p < -10) { + dwFlag = IDLE_PRIORITY_CLASS; + } + + if (!SetPriorityClass(GetCurrentProcess(), dwFlag)) { + return -1; + } + + return 0; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/win32/nice.h b/win32/nice.h new file mode 100644 index 0000000..9cb77d0 --- /dev/null +++ b/win32/nice.h @@ -0,0 +1,25 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2016 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. | + +----------------------------------------------------------------------+ + | Authors: Kalle Sommer Nielsen <kalle@php.net> | + +----------------------------------------------------------------------+ + */ + +#ifndef HAVE_GETRUSAGE_H +# define HAVE_GETRUSAGE_H + +PHPAPI int nice(zend_long); + +#endif +