From 18e8bcb289dd5ea77c12668ea1e2904627fc8531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giampaolo=20Rodol=C3=A0?= Date: Fri, 25 Feb 2011 20:57:54 +0000 Subject: Issue 10784: adds os.getpriority() and os.setpriority() functions. --- Doc/library/os.rst | 44 ++++++++++++++++++++++++++++++++++++ Doc/whatsnew/3.3.rst | 26 ++++++++++++--------- Lib/test/test_os.py | 19 ++++++++++++++++ Modules/posixmodule.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ configure | 2 +- configure.in | 2 +- pyconfig.h.in | 3 +++ 7 files changed, 146 insertions(+), 12 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index a1aaf1e..cd8d45bd 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -286,6 +286,22 @@ process and user. .. versionchanged:: 3.2 Added support for Windows. +.. function:: getpriority(which, who) + + .. index:: single: process; scheduling priority + + Get program scheduling priority. The value *which* is one of + :const:`PRIO_PROCESS`, :const:`PRIO_PGRP`, or :const:`PRIO_USER`, and *who* + is interpreted relative to *which* (a process identifier for + :const:`PRIO_PROCESS`, process group identifier for :const:`PRIO_PGRP`, and a + user ID for :const:`PRIO_USER`). A zero value for *who* denotes + (respectively) the calling process, the process group of the calling process, + or the real user ID of the calling process. + + Availability: Unix + + .. versionadded:: 3.3 + .. function:: getresuid() Return a tuple (ruid, euid, suid) denoting the current process's @@ -336,6 +352,15 @@ process and user. .. versionadded:: 3.2 +.. data:: PRIO_PROCESS + PRIO_PGRP + PRIO_USER + + Parameters for :func:`getpriority` and :func:`setpriority` functions. + + Availability: Unix. + + .. versionadded:: 3.3 .. function:: putenv(key, value) @@ -405,6 +430,25 @@ process and user. Availability: Unix. +.. function:: setpriority(which, who, priority) + + .. index:: single: process; scheduling priority + + Set program scheduling priority. The value *which* is one of + :const:`PRIO_PROCESS`, :const:`PRIO_PGRP`, or :const:`PRIO_USER`, and *who* + is interpreted relative to *which* (a process identifier for + :const:`PRIO_PROCESS`, process group identifier for :const:`PRIO_PGRP`, and a + user ID for :const:`PRIO_USER`). A zero value for *who* denotes + (respectively) the calling process, the process group of the calling process, + or the real user ID of the calling process. + *priority* is a value in the range -20 to 19. The default priority is 0; + lower priorities cause more favorable scheduling. + + Availability: Unix + + .. versionadded:: 3.3 + + .. function:: setregid(rgid, egid) Set the current process's real and effective group ids. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 78d66fe..c0cb7cf 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -71,16 +71,22 @@ New, Improved, and Deprecated Modules os -- -The :mod:`os` module has a new :func:`~os.sendfile` function which provides an -efficent "zero-copy" way for copying data from one file (or socket) descriptor -to another. -The phrase "zero-copy" refers to the fact that all of the copying of data -between the two descriptors is done entirely by the kernel, with no copying of -data into userspace buffers. -:func:`~os.sendfile` can be used to efficiently copy data from a file on disk to -a network socket, e.g. for downloading a file. - -(Patch submitted by Ross Lagerwall and Giampaolo Rodolà in :issue:`10882`.) +* The :mod:`os` module has a new :func:`~os.sendfile` function which provides + an efficent "zero-copy" way for copying data from one file (or socket) + descriptor to another. The phrase "zero-copy" refers to the fact that all of + the copying of data between the two descriptors is done entirely by the + kernel, with no copying of data into userspace buffers. :func:`~os.sendfile` + can be used to efficiently copy data from a file on disk to a network socket, + e.g. for downloading a file. + + (Patch submitted by Ross Lagerwall and Giampaolo Rodolà in :issue:`10882`.) + +* The :mod:`os` module has two new functions: :func:`~os.getpriority` and + :func:`~os.setpriority`. They can be used to get or set process + niceness/priority in a fashion similar to :func:`os.nice` but extended to all + processes instead of just the current one. + + (Patch submitted by Giampaolo Rodolà in :issue:`10784`.) Optimizations ============= diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 4965786..29b6b9a 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1268,6 +1268,24 @@ class LoginTests(unittest.TestCase): self.assertNotEqual(len(user_name), 0) +@unittest.skipUnless(hasattr(os, 'getpriority') and hasattr(os, 'setpriority'), + "needs os.getpriority and os.setpriority") +class ProgramPriorityTests(unittest.TestCase): + """Tests for os.getpriority() and os.setpriority().""" + + def test_set_get_priority(self): + base = os.getpriority(os.PRIO_PROCESS, os.getpid()) + os.setpriority(os.PRIO_PROCESS, os.getpid(), base + 1) + try: + self.assertEqual(os.getpriority(os.PRIO_PROCESS, os.getpid()), base + 1) + finally: + try: + os.setpriority(os.PRIO_PROCESS, os.getpid(), base) + except OSError as err: + if err.errno != EACCESS: + raise + + class SendfileTestServer(asyncore.dispatcher, threading.Thread): class Handler(asynchat.async_chat): @@ -1535,6 +1553,7 @@ def test_main(): LoginTests, LinkTests, TestSendfile, + ProgramPriorityTests, ) if __name__ == "__main__": diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 56b2063..3226b32 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2958,6 +2958,52 @@ posix_nice(PyObject *self, PyObject *args) } #endif /* HAVE_NICE */ + +#ifdef HAVE_GETPRIORITY +PyDoc_STRVAR(posix_getpriority__doc__, +"getpriority(which, who) -> current_priority\n\n\ +Get program scheduling priority."); + +static PyObject * +posix_getpriority(PyObject *self, PyObject *args) +{ + int which, who, retval; + + if (!PyArg_ParseTuple(args, "ii", &which, &who)) + return NULL; + errno = 0; + Py_BEGIN_ALLOW_THREADS + retval = getpriority(which, who); + Py_END_ALLOW_THREADS + if (errno != 0) + return posix_error(); + return PyLong_FromLong((long)retval); +} +#endif /* HAVE_GETPRIORITY */ + + +#ifdef HAVE_SETPRIORITY +PyDoc_STRVAR(posix_setpriority__doc__, +"setpriority(which, who, prio) -> None\n\n\ +Set program scheduling priority."); + +static PyObject * +posix_setpriority(PyObject *self, PyObject *args) +{ + int which, who, prio, retval; + + if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio)) + return NULL; + Py_BEGIN_ALLOW_THREADS + retval = setpriority(which, who, prio); + Py_END_ALLOW_THREADS + if (retval == -1) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETPRIORITY */ + + PyDoc_STRVAR(posix_rename__doc__, "rename(old, new)\n\n\ Rename a file or directory."); @@ -8012,6 +8058,12 @@ static PyMethodDef posix_methods[] = { #ifdef HAVE_NICE {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, #endif /* HAVE_NICE */ +#ifdef HAVE_GETPRIORITY + {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__}, +#endif /* HAVE_GETPRIORITY */ +#ifdef HAVE_SETPRIORITY + {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__}, +#endif /* HAVE_SETPRIORITY */ #ifdef HAVE_READLINK {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__}, #endif /* HAVE_READLINK */ @@ -8459,6 +8511,16 @@ all_ins(PyObject *d) #ifdef O_EXLOCK if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1; #endif +#ifdef PRIO_PROCESS + if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1; +#endif +#ifdef PRIO_PGRP + if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1; +#endif +#ifdef PRIO_USER + if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1; +#endif + /* MS Windows */ #ifdef O_NOINHERIT diff --git a/configure b/configure index c775a85..cbc5293 100755 --- a/configure +++ b/configure @@ -9318,7 +9318,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \ setgid \ - setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \ + setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \ sigaction siginterrupt sigrelse snprintf strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 \ diff --git a/configure.in b/configure.in index 14b60ae..55cbd8f 100644 --- a/configure.in +++ b/configure.in @@ -2542,7 +2542,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \ setgid \ - setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \ + setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \ sigaction siginterrupt sigrelse snprintf strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 \ diff --git a/pyconfig.h.in b/pyconfig.h.in index d55c1cd..7236331 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -602,6 +602,9 @@ /* Define to 1 if you have the `setpgrp' function. */ #undef HAVE_SETPGRP +/* Define to 1 if you have the `setpriority' function. */ +#undef HAVE_SETPRIORITY + /* Define to 1 if you have the `setregid' function. */ #undef HAVE_SETREGID -- cgit v0.12