Signed-off-by: Rémi Bernon rbernon@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 f7b85e27f7d..3ccd67585d0 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 3e10d352856..451a24c6eeb 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 a807f19a42b..b0d4bddeef1 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) { @@ -640,6 +746,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, ¶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 @@ -648,6 +759,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 }