From: Kalle Sommer Nielsen Date: Sun, 16 Oct 2016 02:17:35 +0000 (+0200) Subject: Implemented proc_nice() for Windows (FR #49806) X-Git-Tag: php-7.2.0alpha1~1121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=64945e9387e415fe38c05d7e483ad2d075567336;p=php 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). --- diff --git a/NEWS b/NEWS index df57efc455..1add54a85b 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 38250ed303..b874ad6777 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 1444589a50..71ade7becc 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 bf9100b0d2..0cf2b57191 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 0000000000..45d7c9245e --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_basic-win.phpt @@ -0,0 +1,96 @@ +--TEST-- +proc_nice() basic behaviour +--SKIPIF-- + +--FILE-- + $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 = [ + /* '' => ['', ''] */ + + '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 83b5165679..12469bf4eb 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-- --FILE-- | + +----------------------------------------------------------------------+ + */ + +#include +#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 0000000000..9cb77d0e4f --- /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 | + +----------------------------------------------------------------------+ + */ + +#ifndef HAVE_GETRUSAGE_H +# define HAVE_GETRUSAGE_H + +PHPAPI int nice(zend_long); + +#endif +