[PATCH 02/15] server: Use rtkit to set realtime priority, try 4

Maarten Lankhorst m.b.lankhorst at gmail.com
Fri Apr 23 16:21:37 CDT 2010


---
 configure           |  117 ++++++++++++++++++++++++---------
 configure.ac        |   41 +++++++++---
 include/config.h.in |    3 +
 libs/wine/loader.c  |   27 ++++++++
 server/Makefile.in  |    2 +
 server/rtkit.c      |  181 +++++++++++++++++++++++++++++++++++++++++++++++++++
 server/thread.c     |   16 +++++
 7 files changed, 348 insertions(+), 39 deletions(-)
 create mode 100644 server/rtkit.c

diff --git a/configure b/configure
index 9de0946..2c9c5b7 100755
--- a/configure
+++ b/configure
@@ -634,6 +634,7 @@ gphoto2_devel
 SANEINCL
 sane_devel
 GNUTLSINCL
+DBUSINCL
 HALINCL
 XSLTINCL
 XML2INCL
@@ -772,6 +773,7 @@ with_cms
 with_coreaudio
 with_cups
 with_curses
+with_dbus
 with_esd
 with_fontconfig
 with_freetype
@@ -1459,6 +1461,7 @@ Optional Packages:
   --without-coreaudio     do not use the CoreAudio sound support
   --without-cups          do not use CUPS
   --without-curses        do not use (n)curses
+  --without-dbus          do not use dbus (will also disable HAL support)
   --without-esd           do not use the EsounD sound support
   --without-fontconfig    do not use fontconfig
   --without-freetype      do not use the FreeType library
@@ -2539,6 +2542,12 @@ if test "${with_curses+set}" = set; then :
 fi
 
 
+# Check whether --with-dbus was given.
+if test "${with_dbus+set}" = set; then :
+  withval=$with_dbus;
+fi
+
+
 # Check whether --with-esd was given.
 if test "${with_esd+set}" = set; then :
   withval=$with_esd;
@@ -9286,39 +9295,40 @@ fi
 
 HALINCL=""
 
-if test "x$with_hal" != "xno"
+DBUSINCL=""
+
+
+if test "x$with_dbus" != "xno"
 then
     ac_save_CPPFLAGS="$CPPFLAGS"
     if test "$PKG_CONFIG" != "false"
     then
-        ac_hal_libs="`$PKG_CONFIG --libs hal 2>/dev/null`"
-        ac_hal_cflags="`$PKG_CONFIG --cflags hal 2>/dev/null`"
-        CPPFLAGS="$CPPFLAGS $ac_hal_cflags"
+        ac_dbus_libs="`$PKG_CONFIG --libs dbus-1 2>/dev/null`"
+        ac_dbus_cflags="`$PKG_CONFIG --cflags dbus-1 2>/dev/null`"
+        CPPFLAGS="$CPPFLAGS $ac_dbus_cflags"
     fi
-    for ac_header in dbus/dbus.h hal/libhal.h
+    for ac_header in dbus/dbus.h
 do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-eval as_val=\$$as_ac_Header
-   if test "x$as_val" = x""yes; then :
+  ac_fn_c_check_header_mongrel "$LINENO" "dbus/dbus.h" "ac_cv_header_dbus_dbus_h" "$ac_includes_default"
+if test "x$ac_cv_header_dbus_dbus_h" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_DBUS_DBUS_H 1
 _ACEOF
 
 fi
 
 done
 
-    if test "$ac_cv_header_dbus_dbus_h" = "yes" -a "$ac_cv_header_hal_libhal_h" = "yes"
+    if test "$ac_cv_header_dbus_dbus_h" = "yes"
     then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbus_connection_close in -ldbus-1" >&5
-$as_echo_n "checking for dbus_connection_close in -ldbus-1... " >&6; }
-if test "${ac_cv_lib_dbus_1_dbus_connection_close+set}" = set; then :
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -ldbus-1" >&5
+$as_echo_n "checking for -ldbus-1... " >&6; }
+if test "${ac_cv_lib_soname_dbus_1+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldbus-1 $ac_hal_libs $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  ac_check_soname_save_LIBS=$LIBS
+LIBS="-ldbus-1 $ac_dbus_libs $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -9337,18 +9347,67 @@ return dbus_connection_close ();
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_dbus_1_dbus_connection_close=yes
-else
-  ac_cv_lib_dbus_1_dbus_connection_close=no
+  case "$LIBEXT" in
+    dll) ac_cv_lib_soname_dbus_1=`$ac_cv_path_LDD conftest.exe | grep "dbus-1" | sed -e "s/dll.*/dll/"';2,$d'` ;;
+    dylib) ac_cv_lib_soname_dbus_1=`otool -L conftest$ac_exeext | grep "libdbus-1\\.[0-9A-Za-z.]*dylib" | sed -e "s/^.*\/\(libdbus-1\.[0-9A-Za-z.]*dylib\).*$/\1/"';2,$d'` ;;
+    *) ac_cv_lib_soname_dbus_1=`$ac_cv_path_LDD conftest$ac_exeext | grep "libdbus-1\\.$LIBEXT" | sed -e "s/^.*\(libdbus-1\.$LIBEXT[^	 ]*\).*$/\1/"';2,$d'` ;;
+  esac
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+  LIBS=$ac_check_soname_save_LIBS
+fi
+if test "x$ac_cv_lib_soname_dbus_1" = "x"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_soname_dbus_1" >&5
+$as_echo "$ac_cv_lib_soname_dbus_1" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define SONAME_LIBDBUS_1 "$ac_cv_lib_soname_dbus_1"
+_ACEOF
+
+       DBUSINCL="$ac_dbus_cflags"
+fi
+    fi
+
+    CPPFLAGS="$ac_save_CPPFLAGS"
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dbus_1_dbus_connection_close" >&5
-$as_echo "$ac_cv_lib_dbus_1_dbus_connection_close" >&6; }
-if test "x$ac_cv_lib_dbus_1_dbus_connection_close" = x""yes; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -lhal" >&5
+if test "x$ac_cv_lib_soname_dbus_1" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"; then :
+  case "x$with_dbus" in
+  x)   as_fn_append wine_notices "|libdbus and libhal ${notice_platform}development files not found, HAL and rtkit support disabled" ;;
+  xno) ;;
+  *)   as_fn_error "libdbus and libhal ${notice_platform}development files not found, HAL and rtkit support disabled
+This is an error since --with-dbus was requested." "$LINENO" 5 ;;
+esac
+fi
+
+if test "x$with_hal" != "xno" -a "x$ac_cv_lib_soname_dbus_1" != "x"
+then
+    ac_save_CPPFLAGS="$CPPFLAGS"
+    if test "$PKG_CONFIG" != "false"
+    then
+        ac_hal_libs="`$PKG_CONFIG --libs hal 2>/dev/null`"
+        ac_hal_cflags="`$PKG_CONFIG --cflags hal 2>/dev/null`"
+        CPPFLAGS="$CPPFLAGS $ac_hal_cflags"
+    fi
+    for ac_header in hal/libhal.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "hal/libhal.h" "ac_cv_header_hal_libhal_h" "$ac_includes_default"
+if test "x$ac_cv_header_hal_libhal_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_HAL_LIBHAL_H 1
+_ACEOF
+
+fi
+
+done
+
+    if test "$ac_cv_header_hal_libhal_h" = "yes"
+    then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -lhal" >&5
 $as_echo_n "checking for -lhal... " >&6; }
 if test "${ac_cv_lib_soname_hal+set}" = set; then :
   $as_echo_n "(cached) " >&6
@@ -9398,16 +9457,14 @@ _ACEOF
 
        HALINCL="$ac_hal_cflags"
 fi
-fi
-
     fi
     CPPFLAGS="$ac_save_CPPFLAGS"
 fi
-if test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"; then :
+if test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes" -a "x$ac_cv_lib_soname_dbus_1" != "x"; then :
   case "x$with_hal" in
-  x)   as_fn_append wine_notices "|libhal/libdbus ${notice_platform}development files not found, no dynamic device support." ;;
+  x)   as_fn_append wine_notices "|libhal ${notice_platform}development files not found, no dynamic device support." ;;
   xno) ;;
-  *)   as_fn_error "libhal/libdbus ${notice_platform}development files not found, no dynamic device support.
+  *)   as_fn_error "libhal ${notice_platform}development files not found, no dynamic device support.
 This is an error since --with-hal was requested." "$LINENO" 5 ;;
 esac
 fi
diff --git a/configure.ac b/configure.ac
index 46dca8e..71c4537 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,6 +36,7 @@ AC_ARG_WITH(coreaudio, AS_HELP_STRING([--without-coreaudio],[do not use the Core
 AC_ARG_WITH(cups,      AS_HELP_STRING([--without-cups],[do not use CUPS]))
 AC_ARG_WITH(curses,    AS_HELP_STRING([--without-curses],[do not use (n)curses]),
             [if test "x$withval" = "xno"; then ac_cv_header_ncurses_h=no; ac_cv_header_curses_h=no; fi])
+AC_ARG_WITH(dbus,      AS_HELP_STRING([--without-dbus],[do not use dbus (will also disable HAL support)]))
 AC_ARG_WITH(esd,       AS_HELP_STRING([--without-esd],[do not use the EsounD sound support]))
 AC_ARG_WITH(fontconfig,AS_HELP_STRING([--without-fontconfig],[do not use fontconfig]),
             [if test "x$withval" = "xno"; then ac_cv_header_fontconfig_fontconfig_h=no; fi])
@@ -1137,9 +1138,32 @@ fi
 WINE_WARNING_WITH(xslt,[test "x$ac_cv_lib_soname_xslt" = "x"],
                  [libxslt ${notice_platform}development files not found, xslt won't be supported.])
 
-dnl **** Check for libhal ****
+dnl **** Check for libdbus-1 and libhal ****
 AC_SUBST(HALINCL,"")
-if test "x$with_hal" != "xno"
+AC_SUBST(DBUSINCL,"")
+
+if test "x$with_dbus" != "xno"
+then
+    ac_save_CPPFLAGS="$CPPFLAGS"
+    if test "$PKG_CONFIG" != "false"
+    then
+        ac_dbus_libs="`$PKG_CONFIG --libs dbus-1 2>/dev/null`"
+        ac_dbus_cflags="`$PKG_CONFIG --cflags dbus-1 2>/dev/null`"
+        CPPFLAGS="$CPPFLAGS $ac_dbus_cflags"
+    fi
+    AC_CHECK_HEADERS([dbus/dbus.h])
+    if test "$ac_cv_header_dbus_dbus_h" = "yes"
+    then
+        WINE_CHECK_SONAME(dbus-1, dbus_connection_close,
+            [DBUSINCL="$ac_dbus_cflags"],,[$ac_dbus_libs])
+    fi
+
+    CPPFLAGS="$ac_save_CPPFLAGS"
+fi
+WINE_NOTICE_WITH(dbus,[test "x$ac_cv_lib_soname_dbus_1" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"],
+                 [libdbus and libhal ${notice_platform}development files not found, HAL and rtkit support disabled])
+
+if test "x$with_hal" != "xno" -a "x$ac_cv_lib_soname_dbus_1" != "x"
 then
     ac_save_CPPFLAGS="$CPPFLAGS"
     if test "$PKG_CONFIG" != "false"
@@ -1148,17 +1172,16 @@ then
         ac_hal_cflags="`$PKG_CONFIG --cflags hal 2>/dev/null`"
         CPPFLAGS="$CPPFLAGS $ac_hal_cflags"
     fi
-    AC_CHECK_HEADERS([dbus/dbus.h hal/libhal.h])
-    if test "$ac_cv_header_dbus_dbus_h" = "yes" -a "$ac_cv_header_hal_libhal_h" = "yes"
+    AC_CHECK_HEADERS([hal/libhal.h])
+    if test "$ac_cv_header_hal_libhal_h" = "yes"
     then
-        AC_CHECK_LIB(dbus-1, dbus_connection_close,
-          [WINE_CHECK_SONAME(hal, libhal_ctx_new,
-            [HALINCL="$ac_hal_cflags"],,[$ac_hal_libs])],,[$ac_hal_libs])
+        WINE_CHECK_SONAME(hal, libhal_ctx_new,
+            [HALINCL="$ac_hal_cflags"],,[$ac_hal_libs])
     fi
     CPPFLAGS="$ac_save_CPPFLAGS"
 fi
-WINE_NOTICE_WITH(hal,[test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"],
-                 [libhal/libdbus ${notice_platform}development files not found, no dynamic device support.])
+WINE_NOTICE_WITH(hal,[test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes" -a "x$ac_cv_lib_soname_dbus_1" != "x"],
+                 [libhal ${notice_platform}development files not found, no dynamic device support.])
 
 dnl **** Check for libgnutls ****
 if test "x$with_gnutls" != "xno"
diff --git a/include/config.h.in b/include/config.h.in
index 0faf127..60e12a4 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -1181,6 +1181,9 @@
 /* Define to the soname of the libcurses library. */
 #undef SONAME_LIBCURSES
 
+/* Define to the soname of the libdbus-1 library. */
+#undef SONAME_LIBDBUS_1
+
 /* Define to the soname of the libfontconfig library. */
 #undef SONAME_LIBFONTCONFIG
 
diff --git a/libs/wine/loader.c b/libs/wine/loader.c
index 37c603e..69a9292 100644
--- a/libs/wine/loader.c
+++ b/libs/wine/loader.c
@@ -669,6 +669,32 @@ static void set_max_limit( int limit )
 
 
 /***********************************************************************
+ *           set_rttime_limit
+ *
+ * set a limit on the cpu time used
+ */
+static void set_rttime_limit(void)
+{
+#if defined(HAVE_SETRLIMIT) && defined(__linux__)
+#ifndef RLIMIT_RTTIME
+#define RLIMIT_RTTIME 15
+#endif
+    struct rlimit rlimit;
+
+    if (!getrlimit( RLIMIT_RTTIME, &rlimit ))
+    {
+        /* 50 ms realtime, then 10 ms to undo realtime */
+        if (rlimit.rlim_max > 60000000ULL)
+            rlimit.rlim_max = 60000000ULL;
+        rlimit.rlim_cur = rlimit.rlim_max - 10000000ULL;
+
+        setrlimit( RLIMIT_RTTIME, &rlimit );
+    }
+#endif
+}
+
+
+/***********************************************************************
  *           wine_init
  *
  * Main Wine initialisation.
@@ -687,6 +713,7 @@ void wine_init( int argc, char *argv[], char *error, int error_size )
 #ifdef RLIMIT_AS
     set_max_limit( RLIMIT_AS );
 #endif
+    set_rttime_limit();
 
     wine_init_argv0_path( argv[0] );
     build_dll_path();
diff --git a/server/Makefile.in b/server/Makefile.in
index 7a67707..1197066 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -5,6 +5,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = none
 EXTRALIBS = @LIBPOLL@
+MODCFLAGS = @DBUSINCL@
 
 C_SRCS = \
 	async.c \
@@ -36,6 +37,7 @@ C_SRCS = \
 	region.c \
 	registry.c \
 	request.c \
+	rtkit.c \
 	semaphore.c \
 	serial.c \
 	signal.c \
diff --git a/server/rtkit.c b/server/rtkit.c
new file mode 100644
index 0000000..4837c13
--- /dev/null
+++ b/server/rtkit.c
@@ -0,0 +1,181 @@
+/*
+ * Rtkit dbus calls
+ * Copyright 2010 Maarten Lankhorst for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wine/library.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SCHED_H
+#include <sys/sched.h>
+#endif
+#include <sys/resource.h>
+
+#if defined(HAVE_SETRLIMIT) && defined(__linux__) && defined(SONAME_LIBDBUS_1) && defined(HAVE_SCHED_H)
+
+#include <sched.h>
+#include <string.h>
+#include <unistd.h>
+#include <dbus/dbus.h>
+#include <stdio.h>
+#include "object.h"
+
+#ifndef RLIMIT_RTTIME
+#define RLIMIT_RTTIME 15
+#endif
+
+#define FUNCPTR(fn) static typeof(fn) *p ##fn
+
+FUNCPTR(dbus_error_init);
+FUNCPTR(dbus_error_free);
+FUNCPTR(dbus_bus_get);
+FUNCPTR(dbus_message_new_method_call);
+FUNCPTR(dbus_message_append_args);
+FUNCPTR(dbus_connection_send_with_reply_and_block);
+FUNCPTR(dbus_message_unref);
+FUNCPTR(dbus_set_error_from_message);
+#undef FUNCPTR
+
+static int translate_error( unsigned tid, const char *name )
+{
+    if (!strcmp( name, DBUS_ERROR_NO_MEMORY ))
+        return -ENOMEM;
+    if (!strcmp( name, DBUS_ERROR_SERVICE_UNKNOWN ) ||
+        !strcmp( name, DBUS_ERROR_NAME_HAS_NO_OWNER ))
+        return -ENOENT;
+    if (!strcmp( name, DBUS_ERROR_ACCESS_DENIED ) ||
+        !strcmp( name, DBUS_ERROR_AUTH_FAILED ))
+        return -EACCES;
+
+    if (debug_level)
+        fprintf( stderr, "%04x: Could not map error \"%s\"\n", tid, name );
+    return -EIO;
+}
+
+static void init_dbus(void)
+{
+#define FUNCPTR(fn) p ##fn = wine_dlsym( libdbus, #fn, NULL, 0 );
+    char error[512];
+    void *libdbus = wine_dlopen( SONAME_LIBDBUS_1, RTLD_NOW, error, sizeof( error ) );
+    FUNCPTR(dbus_error_init);
+    FUNCPTR(dbus_error_free);
+    FUNCPTR(dbus_bus_get);
+    FUNCPTR(dbus_message_new_method_call);
+    FUNCPTR(dbus_message_append_args);
+    FUNCPTR(dbus_connection_send_with_reply_and_block);
+    FUNCPTR(dbus_message_unref);
+    FUNCPTR(dbus_set_error_from_message);
+#undef FUNCPTR
+}
+
+static DBusConnection *get_dbus(void)
+{
+    static DBusConnection *bus;
+    DBusError error;
+
+    if (bus)
+        return bus;
+    init_dbus();
+    pdbus_error_init( &error );
+
+    bus = pdbus_bus_get( DBUS_BUS_SYSTEM, &error );
+    return bus;
+}
+
+int rtkit_make_realtime( pid_t process, pid_t thread, int priority )
+{
+    DBusConnection *bus;
+    DBusMessage *m = NULL, *r = NULL;
+    dbus_uint64_t pid = process;
+    dbus_uint64_t tid = thread;
+    dbus_uint32_t rtprio = priority;
+    DBusError error;
+    int ret;
+
+    bus = get_dbus();
+    if (!bus)
+        return -ENOTSUP;
+
+    pdbus_error_init( &error );
+    m = pdbus_message_new_method_call( "org.freedesktop.RealtimeKit1",
+                                       "/org/freedesktop/RealtimeKit1",
+                                       "org.freedesktop.RealtimeKit1",
+                                       "MakeThreadRealtimeWithPID" );
+    if (!m)
+    {
+        ret = -ENOMEM;
+        goto out;
+    }
+
+    ret = pdbus_message_append_args( m, DBUS_TYPE_UINT64, &pid,
+                                     DBUS_TYPE_UINT64, &tid,
+                                     DBUS_TYPE_UINT32, &rtprio,
+                                     DBUS_TYPE_INVALID );
+    if (!ret)
+    {
+        ret = -ENOMEM;
+        goto out;
+    }
+    r = pdbus_connection_send_with_reply_and_block( bus, m, -1, &error );
+    if (!r)
+    {
+        ret = translate_error( tid, error.name );
+        goto out;
+    }
+    if (pdbus_set_error_from_message( &error, r ))
+        ret = translate_error( tid, error.name );
+    else
+        ret = 0;
+out:
+    if (m)
+        pdbus_message_unref( m );
+    if (r)
+        pdbus_message_unref( r );
+    pdbus_error_free( &error );
+    if (debug_level)
+        fprintf( stderr, "%04x: Setting realtime priority of %u returns %i\n", (int)tid, rtprio, ret );
+    return ret;
+}
+
+int rtkit_undo_realtime( pid_t thread )
+{
+    struct sched_param parm;
+    int ret;
+    memset( &parm, 0, sizeof( parm ) );
+    ret = sched_setscheduler( thread, SCHED_OTHER, &parm );
+    if (ret < 0)
+        return -errno;
+    return ret;
+}
+
+#else
+
+int rtkit_make_realtime( pid_t process, pid_t thread, int priority )
+{
+    return -ENOTSUP;
+}
+
+int rtkit_undo_realtime( pid_t thread )
+{
+    return -ENOTSUP;
+}
+
+#endif
+
diff --git a/server/thread.c b/server/thread.c
index 67ef6cf..01bd919 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -52,6 +52,8 @@
 #include "user.h"
 #include "security.h"
 
+extern int rtkit_make_realtime(pid_t process, pid_t thread, int priority);
+extern int rtkit_undo_realtime(pid_t thread);
 
 #ifdef __i386__
 static const unsigned int supported_cpus = CPU_FLAG(CPU_x86);
@@ -449,7 +451,17 @@ static void set_thread_info( struct thread *thread,
         if ((req->priority >= min && req->priority <= max) ||
             req->priority == THREAD_PRIORITY_IDLE ||
             req->priority == THREAD_PRIORITY_TIME_CRITICAL)
+        {
+            if (thread->unix_tid == -1)
+                {}
+            else if (thread->priority == THREAD_PRIORITY_TIME_CRITICAL &&
+                     req->priority != THREAD_PRIORITY_TIME_CRITICAL)
+                rtkit_undo_realtime(thread->unix_tid);
+            else if (thread->priority != THREAD_PRIORITY_TIME_CRITICAL &&
+                     req->priority == THREAD_PRIORITY_TIME_CRITICAL)
+                rtkit_make_realtime(thread->unix_pid, thread->unix_tid, 1);
             thread->priority = req->priority;
+        }
         else
             set_error( STATUS_INVALID_PARAMETER );
     }
@@ -1165,6 +1177,10 @@ DECL_HANDLER(init_thread)
     debug_level = max( debug_level, req->debug_level );
     set_thread_affinity( current, current->affinity );
 
+    /* Raced with SetThreadPriority */
+    if (current->priority == THREAD_PRIORITY_TIME_CRITICAL)
+        rtkit_make_realtime(current->unix_pid, current->unix_tid, 1);
+
     reply->pid     = get_process_id( process );
     reply->tid     = get_thread_id( current );
     reply->version = SERVER_PROTOCOL_VERSION;
-- 
1.7.0.4


--------------060700080503000207060509--



More information about the wine-patches mailing list