]> git.saurik.com Git - wxWidgets.git/commitdiff
Add wxProcess::SetPriority() to allow setting the priority of child processes.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 20 Jan 2013 02:10:12 +0000 (02:10 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 20 Jan 2013 02:10:12 +0000 (02:10 +0000)
This uses the same conventions as wxThread::SetPriority() but works on the
entire process.

Closes #14931.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73406 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

configure
configure.in
docs/changes.txt
include/wx/process.h
interface/wx/process.h
setup.h.in
src/common/process.cpp
src/msw/utilsexc.cpp
src/unix/threadpsx.cpp
src/unix/utilsunx.cpp

index 435cefc3c4c4e739323d87b6615c090a65450e26..7feb68bd408e557b33fd2133161127781a042233 100755 (executable)
--- a/configure
+++ b/configure
@@ -35173,6 +35173,19 @@ $as_echo "$wx_cv_struct_tm_has_gmtoff" >&6; }
 fi
 
 
+for ac_func in setpriority
+do :
+  ac_fn_c_check_func "$LINENO" "setpriority" "ac_cv_func_setpriority"
+if test "x$ac_cv_func_setpriority" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SETPRIORITY 1
+_ACEOF
+
+fi
+done
+
+
+
 if test "$wxUSE_SOCKETS" = "yes"; then
         if test "$TOOLKIT" != "MSW"; then
                 ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket"
index 20a45a24d460f622ae9875f1b37328ea17bad05d..9e60cef94820cf253fad128e14b63586a270c798 100644 (file)
@@ -6147,6 +6147,12 @@ if test "$wxUSE_DATETIME" = "yes"; then
     SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS typetest"
 fi
 
+dnl ------------------------------------------------------------------------
+dnl wxProcess
+dnl ------------------------------------------------------------------------
+
+AC_CHECK_FUNCS(setpriority)
+
 dnl ------------------------------------------------------------------------
 dnl wxSocket
 dnl ------------------------------------------------------------------------
index 606d65d40d4fa9c4228b6eca7b8a068bbad5b356..08b630feda5fc8aee21989c7b869a23d6fde1011 100644 (file)
@@ -546,6 +546,7 @@ All:
 - Add new wxFSW_EVENT_ATTRIB and wxFSW_EVENT_UNMOUNT flags (David Hart).
 - Add separate read/written bytes counters and per-direction NOWAIT and WAITALL
   flags to wxSocket (Rob Bresalier).
+- Add wxProcess::SetPriority() (Marian Meravy).
 - Add wxDir::Close() method (Silverstorm82).
 - Fix wxDateTime::GetWeekOfYear() for the last week of year (aimo).
 - Fix compilation of wxHash{Map,Set} with g++ 4.7 (Nathan Ridge).
index 2f1027ae64d76cd3999892e66d4a53b7c97f4014..5a893a7ed5d486cffe42dd1ab9de3652f824ad34 100644 (file)
@@ -104,6 +104,15 @@ public:
                         wxInputStream *errStream);
 #endif // wxUSE_STREAMS
 
+    // priority
+        // Sets the priority to the given value: see wxPRIORITY_XXX constants.
+        //
+        // NB: the priority can only be set before the process is created
+    void SetPriority(unsigned priority);
+
+        // Get the current priority.
+    unsigned GetPriority() const { return m_priority; }
+
     // implementation only - don't use!
     // --------------------------------
 
@@ -116,6 +125,8 @@ protected:
     int m_id;
     long m_pid;
 
+    unsigned m_priority;
+
 #if wxUSE_STREAMS
     // these streams are connected to stdout, stderr and stdin of the child
     // process respectively (yes, m_inputStream corresponds to stdout -- very
index b47276ebc4c61982e4592545a5cafa2158b5dd1a..d7ab0baff0f02f74cb1e0605c5214ec96eadd7ee 100644 (file)
@@ -243,6 +243,20 @@ public:
         The caught output stream is returned by GetInputStream() as a non-seekable stream.
     */
     void Redirect();
+
+    /**
+        Sets the priority of the process, between 0 (lowest) and 100 (highest).
+        It can only be set before the process is created.
+
+        The following symbolic constants can be used in addition to raw
+        values in 0..100 range:
+          - @b wxPRIORITY_MIN: 0
+          - @b wxPRIORITY_DEFAULT: 50
+          - @b wxPRIORITY_MAX: 100
+
+        @since 2.9.5
+    */
+    void SetPriority(unsigned priority);
 };
 
 
index 4f6412de9e40a803e3c1d97765da41c41693ff4d..9f3391f000f463640fd8ed96f45f3b640c7def52 100644 (file)
 /* Define if getgrgid_r is available. */
 #undef HAVE_GETGRGID_R
 
+/* Define if setpriority() is available. */
+#undef HAVE_SETPRIORITY
+
 /* Define if locale_t is available */
 #undef HAVE_LOCALE_T
 
index 210068e955d73170945b274bd0f47e3f63d5af8d..2a4f5f5416027d67a79df6b8edc5475fe1156b3b 100644 (file)
@@ -50,6 +50,7 @@ void wxProcess::Init(wxEvtHandler *parent, int id, int flags)
 
     m_id         = id;
     m_pid        = 0;
+    m_priority   = wxPRIORITY_DEFAULT;
     m_redirect   = (flags & wxPROCESS_REDIRECT) != 0;
 
 #if wxUSE_STREAMS
@@ -176,3 +177,10 @@ bool wxProcess::Exists(int pid)
     }
 }
 
+void wxProcess::SetPriority(unsigned priority)
+{
+    wxCHECK_RET( priority >= wxPRIORITY_MIN && priority <= wxPRIORITY_MAX,
+                 wxS("Invalid process priority value.") );
+
+    m_priority = priority;
+}
index cd3572e44d108d3be17a1ea90d9f019825130a47..e9f7ae28b532195bb51cea206ef1757066870c97 100644 (file)
@@ -852,6 +852,26 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
         }
     }
 
+    // Translate wxWidgets priority to Windows conventions.
+    unsigned prio = handler->GetPriority();
+    if ( prio <= 20 )
+        dwFlags |= IDLE_PRIORITY_CLASS;
+    else if ( prio <= 40 )
+        dwFlags |= BELOW_NORMAL_PRIORITY_CLASS;
+    else if ( prio <= 60 )
+        dwFlags |= NORMAL_PRIORITY_CLASS;
+    else if ( prio <= 80 )
+        dwFlags |= ABOVE_NORMAL_PRIORITY_CLASS;
+    else if ( prio <= 99 )
+        dwFlags |= HIGH_PRIORITY_CLASS;
+    else if ( prio <= 100 )
+        dwFlags |= REALTIME_PRIORITY_CLASS;
+    else
+    {
+        wxFAIL_MSG(wxT("invalid value of thread priority parameter"));
+        dwFlags |= THREAD_PRIORITY_NORMAL;
+    }
+
     bool ok = ::CreateProcess
                 (
                     // WinCE requires appname to be non null
index b04eb1d60d28460048a5285734417ab58270f46b..952c77c9c76e0250c9e70105ba399f411f8b8bbb 100644 (file)
     #include <cxxabi.h>
 #endif
 
+#ifdef HAVE_SETPRIORITY
+    #include <sys/resource.h>   // for setpriority()
+#endif
+
 // we use wxFFile under Linux in GetCPUCount()
 #ifdef __LINUX__
     #include "wx/ffile.h"
-    #include <sys/resource.h>   // for setpriority()
 #endif
 
 #define THR_ID_CAST(id)  (reinterpret_cast<void*>(id))
index a09fb424df8fca1bcc043df3dba4d49dff65dad3..eb01ae41c535d720a755536bcaf6c6ddb800f83a 100644 (file)
     #include <sys/sysinfo.h>   // for SAGET and MINFO structures
 #endif
 
+#ifdef HAVE_SETPRIORITY
+    #include <sys/resource.h>   // for setpriority()
+#endif
+
 // ----------------------------------------------------------------------------
 // conditional compilation
 // ----------------------------------------------------------------------------
@@ -545,6 +549,21 @@ long wxExecute(char **argv, int flags, wxProcess *process,
         }
     }
 
+    // priority: we need to map wxWidgets priority which is in the range 0..100
+    // to Unix nice value which is in the range -20..19. As there is an odd
+    // number of elements in our range and an even number in the Unix one, we
+    // have to do it in this rather ugly way to guarantee that:
+    //  1. wxPRIORITY_{MIN,DEFAULT,MAX} map to -20, 0 and 19 respectively.
+    //  2. The mapping is monotonously increasing.
+    //  3. The mapping is onto the target range.
+    int prio = process->GetPriority();
+    if ( prio <= 50 )
+        prio = (2*prio)/5 - 20;
+    else if ( prio < 55 )
+        prio = 1;
+    else
+        prio = (2*prio)/5 - 21;
+
     // fork the process
     //
     // NB: do *not* use vfork() here, it completely breaks this code for some
@@ -578,6 +597,13 @@ long wxExecute(char **argv, int flags, wxProcess *process,
         }
 #endif // !__VMS
 
+#if defined(HAVE_SETPRIORITY)
+        if ( setpriority(PRIO_PROCESS, 0, prio) != 0 )
+        {
+            wxLogSysError(_("Failed to set process priority"));
+        }
+#endif // HAVE_SETPRIORITY
+
         // redirect stdin, stdout and stderr
         if ( pipeIn.IsOk() )
         {