]> granicus.if.org Git - php/commitdiff
Implemented proc_nice() for Windows (FR #49806)
authorKalle Sommer Nielsen <kalle@php.net>
Sun, 16 Oct 2016 02:17:35 +0000 (04:17 +0200)
committerKalle Sommer Nielsen <kalle@php.net>
Sun, 16 Oct 2016 02:17:35 +0000 (04:17 +0200)
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).

NEWS
UPGRADING
UPGRADING.INTERNALS
ext/standard/exec.c
ext/standard/tests/general_functions/proc_nice_basic-win.phpt [new file with mode: 0644]
ext/standard/tests/general_functions/proc_nice_basic.phpt
win32/build/config.w32
win32/build/config.w32.h.in
win32/nice.c [new file with mode: 0644]
win32/nice.h [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index df57efc45561a78e3d55eecef30ddaf4bbb7feef..1add54a85bf9d78b36bf794ae6f788a181881730 100644 (file)
--- 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:
index 38250ed303a1bd140072bee74b92b5bfe5276f8d..b874ad6777ad1c2f9fa03a48cf963a631c3459ff 100644 (file)
--- 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
index 1444589a50da758b04b69a291d762a5df8fe0a02..71ade7becc00f2e6a88de8b64386cfc806f032eb 100644 (file)
@@ -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
 ========================
index bf9100b0d2c0b9d12b0a4cf40cf9734c75781443..0cf2b57191dc65b3304244ec18bd29de3e267d44 100644 (file)
@@ -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 (file)
index 0000000..45d7c92
--- /dev/null
@@ -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
index 83b5165679fe43ffc3ef5e9326a7ced5e7c834f1..12469bf4ebbb442140e2d72b3f6d98d90bb29109 100644 (file)
@@ -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
index 96f801ab3873c971b6ac2523bceb0b5185924472..cc921d81a6314c4840f2fca89c549784f08ece33 100644 (file)
@@ -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");
 
index 2a8297a14450802186e878d70b1622c137f1b8d3..e871088f15a208e455e3cf082a91c48e4e56ea8c 100644 (file)
 #define HAVE_GETRUSAGE
 
 #define HAVE_FTOK 1
+
+#define HAVE_NICE
diff --git a/win32/nice.c b/win32/nice.c
new file mode 100644 (file)
index 0000000..2b66a46
--- /dev/null
@@ -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 (file)
index 0000000..9cb77d0
--- /dev/null
@@ -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
+