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

Rémi Bernon rbernon at codeweavers.com
Thu Oct 3 03:46:18 CDT 2019


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

diff --git a/configure.ac b/configure.ac
index 47c1f7c5315..4d83d54823d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1403,7 +1403,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 929b11a8754..559bd57d1c2 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 36bd41e977f..74c466b2a14 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -58,6 +58,111 @@
 #include "user.h"
 #include "security.h"

+#ifdef HAVE_DBUS_DBUS_H
+#include <dbus/dbus.h>
+
+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 (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 (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);
@@ -521,7 +626,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) {
@@ -641,6 +747,11 @@ int set_thread_priority( struct thread* thread, int priority_class, int priority
         param.sched_priority = get_unix_priority( priority_class, 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( priority_class, priority ) ) == 0)
+            return 0;
 #endif
     }
     else
@@ -649,6 +760,11 @@ int set_thread_priority( struct thread* thread, int priority_class, int priority
         if (setpriority( PRIO_PROCESS, thread->unix_tid,
                          get_unix_priority( priority_class, priority ) ) == 0)
             return 0;
+#endif
+#ifdef HAVE_DBUS_DBUS_H
+        if (rtkit_set_niceness( thread->unix_pid, thread->unix_tid,
+                                get_unix_priority( priority_class, priority ) ) == 0)
+            return 0;
 #endif
     }
 #endif
--
2.23.0




More information about the wine-devel mailing list