[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, ¶m ) == 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