commit ebf411c1e5f20c6db7962cea587d6169246078e0 Author: RĂ©mi Bernon Date: Wed Jul 3 10:54:06 2019 +0200 Subject: [PATCH 2/3] server: Fallback to RTKIT for thread priorities. sched_setscheduler and setpriority usually require elevated privileges to succeed and most Linux distributions ship rtkit daemon with a dbus interface to enable unprivileged control of some scheduling parameters. --- a/configure.ac +++ b/configure.ac @@ -1416,7 +1416,7 @@ 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 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -50,6 +50,7 @@ wineserver.man.in \ winstation.c -UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) +UNIX_CFLAGS = $(DBUS_CFLAGS) +UNIX_LIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) $(DBUS_LIBS) unicode_EXTRADEFS = -DNLSDIR="\"${nlsdir}\"" -DBIN_TO_NLSDIR=\"`${MAKEDEP} -R ${bindir} ${nlsdir}`\" --- a/server/thread.c +++ b/server/thread.c @@ -59,6 +59,77 @@ #include "esync.h" #include "fsync.h" +#ifdef HAVE_DBUS_DBUS_H +#include + +static int rtkit_set_realtime( dbus_uint64_t process, dbus_uint64_t thread, dbus_uint32_t priority ) +{ + DBusConnection* dbus; + DBusMessage *msg; + int ret = -1; + + if ((dbus = dbus_bus_get(DBUS_BUS_SYSTEM, NULL))) + { + 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"))) + { + dbus_message_set_no_reply(msg, 1); + + if (dbus_message_append_args(msg, + DBUS_TYPE_UINT64, &process, + DBUS_TYPE_UINT64, &thread, + DBUS_TYPE_UINT32, &priority, + DBUS_TYPE_INVALID) && + dbus_connection_send(dbus, msg, NULL)) + ret = 0; + + dbus_message_unref(msg); + } + + dbus_connection_unref(dbus); + } + + return ret; +} + +static int rtkit_set_niceness( dbus_uint64_t process, dbus_uint64_t thread, dbus_int32_t niceness ) +{ + DBusConnection* dbus; + DBusMessage *msg; + int ret = -1; + + if ((dbus = dbus_bus_get(DBUS_BUS_SYSTEM, NULL))) + { + 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"))) + { + dbus_message_set_no_reply(msg, 1); + + if (dbus_message_append_args(msg, + DBUS_TYPE_UINT64, &process, + DBUS_TYPE_UINT64, &thread, + DBUS_TYPE_INT32, &niceness, + DBUS_TYPE_INVALID) && + dbus_connection_send(dbus, msg, NULL)) + ret = 0; + + dbus_message_unref(msg); + } + + dbus_connection_unref(dbus); + } + + return ret; +} +#endif /* thread queues */ @@ -655,7 +726,8 @@ 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) { @@ -778,6 +850,11 @@ 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( priority_class, priority ) ) == 0) + return 0; +#endif } else { @@ -786,6 +863,11 @@ 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