server: Use rtkit to set realtime priority, try 4
[wine/multimedia.git] / server / rtkit.c
bloba2121068b883c92dbede0b97dd03404b1c4ce0a7
1 /*
2 * Rtkit dbus calls
3 * Copyright 2010 Maarten Lankhorst for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "config.h"
21 #include "wine/port.h"
22 #include "wine/library.h"
24 #include <errno.h>
25 #include <sys/types.h>
26 #ifdef HAVE_SYS_SCHED_H
27 #include <sys/sched.h>
28 #endif
29 #include <sys/resource.h>
31 #if defined(HAVE_SETRLIMIT) && defined(__linux__) && defined(SONAME_LIBDBUS_1) && defined(HAVE_SCHED_H)
33 #include <sched.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <dbus/dbus.h>
37 #include <stdio.h>
38 #include "object.h"
40 #ifndef RLIMIT_RTTIME
41 #define RLIMIT_RTTIME 15
42 #endif
44 #define FUNCPTR(fn) static typeof(fn) *p ##fn
46 FUNCPTR(dbus_error_init);
47 FUNCPTR(dbus_error_free);
48 FUNCPTR(dbus_bus_get);
49 FUNCPTR(dbus_message_new_method_call);
50 FUNCPTR(dbus_message_append_args);
51 FUNCPTR(dbus_connection_send_with_reply_and_block);
52 FUNCPTR(dbus_message_unref);
53 FUNCPTR(dbus_set_error_from_message);
54 #undef FUNCPTR
56 static int translate_error( unsigned tid, const char *name )
58 if (!strcmp( name, DBUS_ERROR_NO_MEMORY ))
59 return -ENOMEM;
60 if (!strcmp( name, DBUS_ERROR_SERVICE_UNKNOWN ) ||
61 !strcmp( name, DBUS_ERROR_NAME_HAS_NO_OWNER ))
62 return -ENOENT;
63 if (!strcmp( name, DBUS_ERROR_ACCESS_DENIED ) ||
64 !strcmp( name, DBUS_ERROR_AUTH_FAILED ))
65 return -EACCES;
67 if (debug_level)
68 fprintf( stderr, "%04x: Could not map error \"%s\"\n", tid, name );
69 return -EIO;
72 static void init_dbus(void)
74 #define FUNCPTR(fn) p ##fn = wine_dlsym( libdbus, #fn, NULL, 0 );
75 char error[512];
76 void *libdbus = wine_dlopen( SONAME_LIBDBUS_1, RTLD_NOW, error, sizeof( error ) );
77 FUNCPTR(dbus_error_init);
78 FUNCPTR(dbus_error_free);
79 FUNCPTR(dbus_bus_get);
80 FUNCPTR(dbus_message_new_method_call);
81 FUNCPTR(dbus_message_append_args);
82 FUNCPTR(dbus_connection_send_with_reply_and_block);
83 FUNCPTR(dbus_message_unref);
84 FUNCPTR(dbus_set_error_from_message);
85 #undef FUNCPTR
88 static DBusConnection *get_dbus(void)
90 static DBusConnection *bus;
91 DBusError error;
93 if (bus)
94 return bus;
95 init_dbus();
96 pdbus_error_init( &error );
98 bus = pdbus_bus_get( DBUS_BUS_SYSTEM, &error );
99 return bus;
102 int rtkit_make_realtime( pid_t process, pid_t thread, int priority )
104 DBusConnection *bus;
105 DBusMessage *m = NULL, *r = NULL;
106 dbus_uint64_t pid = process;
107 dbus_uint64_t tid = thread;
108 dbus_uint32_t rtprio = priority;
109 DBusError error;
110 int ret;
112 bus = get_dbus();
113 if (!bus)
114 return -ENOTSUP;
116 pdbus_error_init( &error );
117 m = pdbus_message_new_method_call( "org.freedesktop.RealtimeKit1",
118 "/org/freedesktop/RealtimeKit1",
119 "org.freedesktop.RealtimeKit1",
120 "MakeThreadRealtimeWithPID" );
121 if (!m)
123 ret = -ENOMEM;
124 goto out;
127 ret = pdbus_message_append_args( m, DBUS_TYPE_UINT64, &pid,
128 DBUS_TYPE_UINT64, &tid,
129 DBUS_TYPE_UINT32, &rtprio,
130 DBUS_TYPE_INVALID );
131 if (!ret)
133 ret = -ENOMEM;
134 goto out;
136 r = pdbus_connection_send_with_reply_and_block( bus, m, -1, &error );
137 if (!r)
139 ret = translate_error( tid, error.name );
140 goto out;
142 if (pdbus_set_error_from_message( &error, r ))
143 ret = translate_error( tid, error.name );
144 else
145 ret = 0;
146 out:
147 if (m)
148 pdbus_message_unref( m );
149 if (r)
150 pdbus_message_unref( r );
151 pdbus_error_free( &error );
152 if (debug_level)
153 fprintf( stderr, "%04x: Setting realtime priority of %u returns %i\n", (int)tid, rtprio, ret );
154 return ret;
157 int rtkit_undo_realtime( pid_t thread )
159 struct sched_param parm;
160 int ret;
161 memset( &parm, 0, sizeof( parm ) );
162 ret = sched_setscheduler( thread, SCHED_OTHER, &parm );
163 if (ret < 0)
164 return -errno;
165 return ret;
168 #else
170 int rtkit_make_realtime( pid_t process, pid_t thread, int priority )
172 return -ENOTSUP;
175 int rtkit_undo_realtime( pid_t thread )
177 return -ENOTSUP;
180 #endif