[PATCH 2/2] wineserver: Fallback to RTKIT if direct modification of thread priority failed

Rémi Bernon rbernon at codeweavers.com
Wed Jul 3 04:41:19 CDT 2019


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 configure           |  10 +++-
 configure.ac        |   2 +-
 include/config.h.in |   3 +
 server/Makefile.in  |   3 +-
 server/thread.c     | 135 +++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 148 insertions(+), 5 deletions(-)

diff --git a/configure b/configure
index e89be467e2e..f9df2f55c69 100755
--- a/configure
+++ b/configure
@@ -13172,9 +13172,14 @@ $as_echo "$as_me:${as_lineno-$LINENO}: dbus-1 cflags: $DBUS_CFLAGS" >&5
 $as_echo "$as_me:${as_lineno-$LINENO}: dbus-1 libs: $DBUS_LIBS" >&5
 ac_save_CPPFLAGS=$CPPFLAGS
 CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS"
-ac_fn_c_check_header_mongrel "$LINENO" "dbus/dbus.h" "ac_cv_header_dbus_dbus_h" "$ac_includes_default"
+for ac_header in dbus/dbus.h
+do :
+  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" = xyes; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -ldbus-1" >&5
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DBUS_DBUS_H 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -ldbus-1" >&5
 $as_echo_n "checking for -ldbus-1... " >&6; }
 if ${ac_cv_lib_soname_dbus_1+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -13233,6 +13238,7 @@ else
   DBUS_CFLAGS=""
 fi
 
+done
 
 CPPFLAGS=$ac_save_CPPFLAGS
 test -z "$DBUS_CFLAGS" || DBUS_CFLAGS=`echo " $DBUS_CFLAGS" | sed 's/ -I\([^/]\)/ -I\$(top_builddir)\/\1/g'`
diff --git a/configure.ac b/configure.ac
index 4a3ff36e6b7..71d6da3537d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1386,7 +1386,7 @@ dnl **** Check for libdbus ****
 if test "x$with_dbus" != "xno"
 then
     WINE_PACKAGE_FLAGS(DBUS,[dbus-1],,,,
-        [AC_CHECK_HEADER([dbus/dbus.h],
+        [AC_CHECK_HEADERS([dbus/dbus.h],
             [WINE_CHECK_SONAME(dbus-1, dbus_connection_close,,[DBUS_CFLAGS=""],[$DBUS_LIBS])],
             [DBUS_CFLAGS=""])])
 fi
diff --git a/include/config.h.in b/include/config.h.in
index 1acc02b7173..6c279f932cf 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -97,6 +97,9 @@
 /* Define to 1 if you have the <curses.h> header file. */
 #undef HAVE_CURSES_H
 
+/* Define to 1 if you have the <dbus/dbus.h> header file. */
+#undef HAVE_DBUS_DBUS_H
+
 /* Define to 1 if you have the <dirent.h> header file. */
 #undef HAVE_DIRENT_H
 
diff --git a/server/Makefile.in b/server/Makefile.in
index b39bd30305b..114df2a8de3 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -50,4 +50,5 @@ MANPAGES = \
 	wineserver.fr.UTF-8.man.in \
 	wineserver.man.in
 
-EXTRALIBS = $(LDEXECFLAGS) -lwine $(POLL_LIBS) $(RT_LIBS) $(INOTIFY_LIBS)
+EXTRAINCL = $(DBUS_CFLAGS)
+EXTRALIBS = $(LDEXECFLAGS) -lwine $(POLL_LIBS) $(RT_LIBS) $(INOTIFY_LIBS) $(DBUS_LIBS)
diff --git a/server/thread.c b/server/thread.c
index 5b5f3cde617..77a01b1e693 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -58,6 +58,128 @@
 #include "user.h"
 #include "security.h"
 
+#ifdef HAVE_DBUS_DBUS_H
+#include <dbus/dbus.h>
+
+static int dbus_error_to_errno( DBusError* err )
+{
+    if (!err)
+        return EINVAL;
+    if (strcmp(err->name, DBUS_ERROR_NO_MEMORY) == 0)
+        return ENOMEM;
+    if (strcmp(err->name, DBUS_ERROR_SERVICE_UNKNOWN) == 0 ||
+        strcmp(err->name, DBUS_ERROR_NAME_HAS_NO_OWNER) == 0)
+        return ENOENT;
+    if (strcmp(err->name, DBUS_ERROR_ACCESS_DENIED) == 0 ||
+        strcmp(err->name, DBUS_ERROR_AUTH_FAILED) == 0)
+        return EACCES;
+    return EIO;
+}
+
+static int rtkit_set_realtime( dbus_uint64_t process, dbus_uint64_t thread, dbus_uint32_t priority )
+{
+    DBusConnection* dbus = NULL;
+    DBusMessage *msg = NULL, *rep = NULL;
+    DBusError err;
+    int ret = -1;
+
+    dbus_error_init(&err);
+
+    dbus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
+    if (dbus_error_is_set(&err))
+        goto error;
+
+    dbus_connection_set_exit_on_disconnect(dbus, 0);
+
+    if (!(msg = dbus_message_new_method_call("org.freedesktop.RealtimeKit1",
+                                            "/org/freedesktop/RealtimeKit1",
+                                            "org.freedesktop.RealtimeKit1",
+                                            "MakeThreadRealtimeWithPID")))
+        goto error;
+
+    if (!dbus_message_append_args(msg,
+                                  DBUS_TYPE_UINT64, &process,
+                                  DBUS_TYPE_UINT64, &thread,
+                                  DBUS_TYPE_UINT32, &priority,
+                                  DBUS_TYPE_INVALID))
+        goto error;
+
+    if (!(rep = dbus_connection_send_with_reply_and_block(dbus, msg, -1, &err)))
+        goto error;
+
+    if (dbus_error_is_set(&err))
+        goto error;
+
+    if (dbus_set_error_from_message(&err, rep))
+        goto error;
+
+    ret = 0;
+
+error:
+    if (ret) errno = dbus_error_to_errno(&err);
+    if (rep) dbus_message_unref(rep);
+    if (msg) dbus_message_unref(msg);
+    if (dbus)
+    {
+        dbus_connection_close(dbus);
+        dbus_connection_unref(dbus);
+    }
+    dbus_error_free(&err);
+    return ret;
+}
+
+static int rtkit_set_niceness( dbus_uint64_t process, dbus_uint64_t thread, dbus_int32_t niceness )
+{
+    DBusConnection* dbus = NULL;
+    DBusMessage *msg = NULL, *rep = NULL;
+    DBusError err;
+    int ret = -1;
+
+    dbus_error_init(&err);
+
+    dbus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
+    if (dbus_error_is_set(&err))
+        goto error;
+
+    dbus_connection_set_exit_on_disconnect(dbus, 0);
+
+    if (!(msg = dbus_message_new_method_call("org.freedesktop.RealtimeKit1",
+                                            "/org/freedesktop/RealtimeKit1",
+                                            "org.freedesktop.RealtimeKit1",
+                                            "MakeThreadHighPriorityWithPID")))
+        goto error;
+
+    if (!dbus_message_append_args(msg,
+                                  DBUS_TYPE_UINT64, &process,
+                                  DBUS_TYPE_UINT64, &thread,
+                                  DBUS_TYPE_INT32, &niceness,
+                                  DBUS_TYPE_INVALID))
+        goto error;
+
+    if (!(rep = dbus_connection_send_with_reply_and_block(dbus, msg, -1, &err)))
+        goto error;
+
+    if (dbus_error_is_set(&err))
+        goto error;
+
+    if (dbus_set_error_from_message(&err, rep))
+        goto error;
+
+    ret = 0;
+
+error:
+    if (ret) errno = dbus_error_to_errno(&err);
+    if (rep) dbus_message_unref(rep);
+    if (msg) dbus_message_unref(msg);
+    if (dbus)
+    {
+        dbus_connection_close(dbus);
+        dbus_connection_unref(dbus);
+    }
+    dbus_error_free(&err);
+    return ret;
+}
+#endif
 
 #ifdef __i386__
 static const unsigned int supported_cpus = CPU_FLAG(CPU_x86);
@@ -523,7 +645,8 @@ affinity_t get_thread_affinity( struct thread *thread )
     return mask;
 }
 
-#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SETPRIORITY)
+#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SETPRIORITY) || \
+    defined(HAVE_DBUS_DBUS_H)
 static int get_unix_priority( int priority_class, int priority )
 {
     switch (priority_class) {
@@ -638,6 +761,11 @@ int set_thread_priority( struct thread* thread, int priority )
         param.sched_priority = get_unix_priority( thread->process->priority, priority );
         if (sched_setscheduler( thread->unix_tid, SCHED_RR|SCHED_RESET_ON_FORK, &param ) == 0)
             return 0;
+#endif
+#ifdef HAVE_DBUS_DBUS_H
+        if (rtkit_set_realtime( thread->unix_pid, thread->unix_tid,
+                                get_unix_priority( thread->process->priority, priority ) ) == 0)
+            return 0;
 #endif
     }
     else
@@ -646,6 +774,11 @@ int set_thread_priority( struct thread* thread, int priority )
         if (setpriority( PRIO_PROCESS, thread->unix_tid,
                          get_unix_priority( thread->process->priority, priority ) ) == 0)
             return 0;
+#endif
+#ifdef HAVE_DBUS_DBUS_H
+        if (rtkit_set_niceness( thread->unix_pid, thread->unix_tid,
+                                get_unix_priority( thread->process->priority, priority ) ) == 0)
+            return 0;
 #endif
     }
 
-- 
2.20.1




More information about the wine-devel mailing list