1
/*-*- Mode: C; c-basic-offset: 8 -*-*/
4
Copyright 2009 Lennart Poettering
5
Copyright 2010 David Henningsson <diwic@ubuntu.com>
7
Permission is hereby granted, free of charge, to any person
8
obtaining a copy of this software and associated documentation files
9
(the "Software"), to deal in the Software without restriction,
10
including without limitation the rights to use, copy, modify, merge,
11
publish, distribute, sublicense, and/or sell copies of the Software,
12
and to permit persons to whom the Software is furnished to do so,
13
subject to the following conditions:
15
The above copyright notice and this permission notice shall be
16
included in all copies or substantial portions of the Software.
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
#if defined(__linux__) && !defined(__ANDROID__)
44
#include <sys/types.h>
45
#include <sys/syscall.h>
46
#include <pulsecore/core-util.h>
48
static pid_t _gettid(void) {
49
return (pid_t) syscall(SYS_gettid);
52
static int translate_error(const char *name) {
53
if (pa_streq(name, DBUS_ERROR_NO_MEMORY))
55
if (pa_streq(name, DBUS_ERROR_SERVICE_UNKNOWN) ||
56
pa_streq(name, DBUS_ERROR_NAME_HAS_NO_OWNER))
58
if (pa_streq(name, DBUS_ERROR_ACCESS_DENIED) ||
59
pa_streq(name, DBUS_ERROR_AUTH_FAILED))
65
static long long rtkit_get_int_property(DBusConnection *connection, const char* propname, long long* propval) {
66
DBusMessage *m = NULL, *r = NULL;
67
DBusMessageIter iter, subiter;
73
const char * interfacestr = "org.freedesktop.RealtimeKit1";
75
dbus_error_init(&error);
77
if (!(m = dbus_message_new_method_call(
80
"org.freedesktop.DBus.Properties",
86
if (!dbus_message_append_args(
88
DBUS_TYPE_STRING, &interfacestr,
89
DBUS_TYPE_STRING, &propname,
95
if (!(r = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) {
96
ret = translate_error(error.name);
100
if (dbus_set_error_from_message(&error, r)) {
101
ret = translate_error(error.name);
106
dbus_message_iter_init(r, &iter);
107
while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) {
109
if (current_type == DBUS_TYPE_VARIANT) {
110
dbus_message_iter_recurse(&iter, &subiter);
112
while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) {
114
if (current_type == DBUS_TYPE_INT32) {
115
dbus_message_iter_get_basic(&subiter, &i32);
120
if (current_type == DBUS_TYPE_INT64) {
121
dbus_message_iter_get_basic(&subiter, &i64);
126
dbus_message_iter_next (&subiter);
129
dbus_message_iter_next (&iter);
135
dbus_message_unref(m);
138
dbus_message_unref(r);
140
dbus_error_free(&error);
145
int rtkit_get_max_realtime_priority(DBusConnection *connection) {
149
err = rtkit_get_int_property(connection, "MaxRealtimePriority", &retval);
150
return err < 0 ? err : retval;
153
int rtkit_get_min_nice_level(DBusConnection *connection, int* min_nice_level) {
157
err = rtkit_get_int_property(connection, "MinNiceLevel", &retval);
159
*min_nice_level = retval;
163
long long rtkit_get_rttime_usec_max(DBusConnection *connection) {
167
err = rtkit_get_int_property(connection, "RTTimeUSecMax", &retval);
168
return err < 0 ? err : retval;
171
int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) {
172
DBusMessage *m = NULL, *r = NULL;
178
dbus_error_init(&error);
183
if (!(m = dbus_message_new_method_call(
186
"org.freedesktop.RealtimeKit1",
187
"MakeThreadRealtime"))) {
192
u64 = (dbus_uint64_t) thread;
193
u32 = (dbus_uint32_t) priority;
195
if (!dbus_message_append_args(
197
DBUS_TYPE_UINT64, &u64,
198
DBUS_TYPE_UINT32, &u32,
199
DBUS_TYPE_INVALID)) {
204
if (!(r = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) {
205
ret = translate_error(error.name);
210
if (dbus_set_error_from_message(&error, r)) {
211
ret = translate_error(error.name);
220
dbus_message_unref(m);
223
dbus_message_unref(r);
225
dbus_error_free(&error);
230
int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_level) {
231
DBusMessage *m = NULL, *r = NULL;
237
dbus_error_init(&error);
242
if (!(m = dbus_message_new_method_call(
245
"org.freedesktop.RealtimeKit1",
246
"MakeThreadHighPriority"))) {
251
u64 = (dbus_uint64_t) thread;
252
s32 = (dbus_int32_t) nice_level;
254
if (!dbus_message_append_args(
256
DBUS_TYPE_UINT64, &u64,
257
DBUS_TYPE_INT32, &s32,
258
DBUS_TYPE_INVALID)) {
265
if (!(r = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) {
266
ret = translate_error(error.name);
271
if (dbus_set_error_from_message(&error, r)) {
272
ret = translate_error(error.name);
281
dbus_message_unref(m);
284
dbus_message_unref(r);
286
dbus_error_free(&error);
293
int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) {
297
int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_level) {
301
int rtkit_get_max_realtime_priority(DBusConnection *connection) {
305
int rtkit_get_min_nice_level(DBusConnection *connection, int* min_nice_level) {
309
long long rtkit_get_rttime_usec_max(DBusConnection *connection) {