Add wxProcess::SetPriority() to allow setting the priority of child processes.

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
This commit is contained in:
Vadim Zeitlin
2013-01-20 02:10:12 +00:00
parent 90e95e6117
commit eaf4bde6e6
10 changed files with 106 additions and 1 deletions

13
configure vendored
View File

@@ -35173,6 +35173,19 @@ $as_echo "$wx_cv_struct_tm_has_gmtoff" >&6; }
fi 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 "$wxUSE_SOCKETS" = "yes"; then
if test "$TOOLKIT" != "MSW"; then if test "$TOOLKIT" != "MSW"; then
ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket"

View File

@@ -6147,6 +6147,12 @@ if test "$wxUSE_DATETIME" = "yes"; then
SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS typetest" SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS typetest"
fi fi
dnl ------------------------------------------------------------------------
dnl wxProcess
dnl ------------------------------------------------------------------------
AC_CHECK_FUNCS(setpriority)
dnl ------------------------------------------------------------------------ dnl ------------------------------------------------------------------------
dnl wxSocket dnl wxSocket
dnl ------------------------------------------------------------------------ dnl ------------------------------------------------------------------------

View File

@@ -546,6 +546,7 @@ All:
- Add new wxFSW_EVENT_ATTRIB and wxFSW_EVENT_UNMOUNT flags (David Hart). - Add new wxFSW_EVENT_ATTRIB and wxFSW_EVENT_UNMOUNT flags (David Hart).
- Add separate read/written bytes counters and per-direction NOWAIT and WAITALL - Add separate read/written bytes counters and per-direction NOWAIT and WAITALL
flags to wxSocket (Rob Bresalier). flags to wxSocket (Rob Bresalier).
- Add wxProcess::SetPriority() (Marian Meravy).
- Add wxDir::Close() method (Silverstorm82). - Add wxDir::Close() method (Silverstorm82).
- Fix wxDateTime::GetWeekOfYear() for the last week of year (aimo). - Fix wxDateTime::GetWeekOfYear() for the last week of year (aimo).
- Fix compilation of wxHash{Map,Set} with g++ 4.7 (Nathan Ridge). - Fix compilation of wxHash{Map,Set} with g++ 4.7 (Nathan Ridge).

View File

@@ -104,6 +104,15 @@ public:
wxInputStream *errStream); wxInputStream *errStream);
#endif // wxUSE_STREAMS #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! // implementation only - don't use!
// -------------------------------- // --------------------------------
@@ -116,6 +125,8 @@ protected:
int m_id; int m_id;
long m_pid; long m_pid;
unsigned m_priority;
#if wxUSE_STREAMS #if wxUSE_STREAMS
// these streams are connected to stdout, stderr and stdin of the child // these streams are connected to stdout, stderr and stdin of the child
// process respectively (yes, m_inputStream corresponds to stdout -- very // process respectively (yes, m_inputStream corresponds to stdout -- very

View File

@@ -243,6 +243,20 @@ public:
The caught output stream is returned by GetInputStream() as a non-seekable stream. The caught output stream is returned by GetInputStream() as a non-seekable stream.
*/ */
void Redirect(); 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);
}; };

View File

@@ -1240,6 +1240,9 @@
/* Define if getgrgid_r is available. */ /* Define if getgrgid_r is available. */
#undef HAVE_GETGRGID_R #undef HAVE_GETGRGID_R
/* Define if setpriority() is available. */
#undef HAVE_SETPRIORITY
/* Define if locale_t is available */ /* Define if locale_t is available */
#undef HAVE_LOCALE_T #undef HAVE_LOCALE_T

View File

@@ -50,6 +50,7 @@ void wxProcess::Init(wxEvtHandler *parent, int id, int flags)
m_id = id; m_id = id;
m_pid = 0; m_pid = 0;
m_priority = wxPRIORITY_DEFAULT;
m_redirect = (flags & wxPROCESS_REDIRECT) != 0; m_redirect = (flags & wxPROCESS_REDIRECT) != 0;
#if wxUSE_STREAMS #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;
}

View 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 bool ok = ::CreateProcess
( (
// WinCE requires appname to be non null // WinCE requires appname to be non null

View File

@@ -58,10 +58,13 @@
#include <cxxabi.h> #include <cxxabi.h>
#endif #endif
#ifdef HAVE_SETPRIORITY
#include <sys/resource.h> // for setpriority()
#endif
// we use wxFFile under Linux in GetCPUCount() // we use wxFFile under Linux in GetCPUCount()
#ifdef __LINUX__ #ifdef __LINUX__
#include "wx/ffile.h" #include "wx/ffile.h"
#include <sys/resource.h> // for setpriority()
#endif #endif
#define THR_ID_CAST(id) (reinterpret_cast<void*>(id)) #define THR_ID_CAST(id) (reinterpret_cast<void*>(id))

View File

@@ -132,6 +132,10 @@
#include <sys/sysinfo.h> // for SAGET and MINFO structures #include <sys/sysinfo.h> // for SAGET and MINFO structures
#endif #endif
#ifdef HAVE_SETPRIORITY
#include <sys/resource.h> // for setpriority()
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// conditional compilation // 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 // fork the process
// //
// NB: do *not* use vfork() here, it completely breaks this code for some // 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 #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 // redirect stdin, stdout and stderr
if ( pipeIn.IsOk() ) if ( pipeIn.IsOk() )
{ {