~binli/ubuntu/vivid/pulseaudio/support-android-60

« back to all changes in this revision

Viewing changes to src/pulsecore/rtkit.c

  • Committer: Bin Li
  • Date: 2016-06-06 09:29:54 UTC
  • Revision ID: bin.li@canonical.com-20160606092954-izj1ciiqcuje82fy
init the 1:6.0-0ubuntu9.25 from overlay in vivid

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-*- Mode: C; c-basic-offset: 8 -*-*/
 
2
 
 
3
/***
 
4
  Copyright 2009 Lennart Poettering
 
5
  Copyright 2010 David Henningsson <diwic@ubuntu.com>
 
6
 
 
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:
 
14
 
 
15
  The above copyright notice and this permission notice shall be
 
16
  included in all copies or substantial portions of the Software.
 
17
 
 
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
 
25
  SOFTWARE.
 
26
***/
 
27
 
 
28
#include <errno.h>
 
29
 
 
30
#include "rtkit.h"
 
31
 
 
32
#if defined(__linux__) && !defined(__ANDROID__)
 
33
 
 
34
#ifndef _GNU_SOURCE
 
35
#define _GNU_SOURCE
 
36
#endif
 
37
 
 
38
#ifdef HAVE_CONFIG_H
 
39
#include <config.h>
 
40
#endif
 
41
 
 
42
#include <string.h>
 
43
#include <unistd.h>
 
44
#include <sys/types.h>
 
45
#include <sys/syscall.h>
 
46
#include <pulsecore/core-util.h>
 
47
 
 
48
static pid_t _gettid(void) {
 
49
        return (pid_t) syscall(SYS_gettid);
 
50
}
 
51
 
 
52
static int translate_error(const char *name) {
 
53
        if (pa_streq(name, DBUS_ERROR_NO_MEMORY))
 
54
                return -ENOMEM;
 
55
        if (pa_streq(name, DBUS_ERROR_SERVICE_UNKNOWN) ||
 
56
            pa_streq(name, DBUS_ERROR_NAME_HAS_NO_OWNER))
 
57
                return -ENOENT;
 
58
        if (pa_streq(name, DBUS_ERROR_ACCESS_DENIED) ||
 
59
            pa_streq(name, DBUS_ERROR_AUTH_FAILED))
 
60
                return -EACCES;
 
61
 
 
62
        return -EIO;
 
63
}
 
64
 
 
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;
 
68
        dbus_int64_t i64;
 
69
        dbus_int32_t i32;
 
70
        DBusError error;
 
71
        int current_type;
 
72
        long long ret;
 
73
        const char * interfacestr = "org.freedesktop.RealtimeKit1";
 
74
 
 
75
        dbus_error_init(&error);
 
76
 
 
77
        if (!(m = dbus_message_new_method_call(
 
78
                              RTKIT_SERVICE_NAME,
 
79
                              RTKIT_OBJECT_PATH,
 
80
                              "org.freedesktop.DBus.Properties",
 
81
                              "Get"))) {
 
82
                ret = -ENOMEM;
 
83
                goto finish;
 
84
        }
 
85
 
 
86
        if (!dbus_message_append_args(
 
87
                            m,
 
88
                            DBUS_TYPE_STRING, &interfacestr,
 
89
                            DBUS_TYPE_STRING, &propname,
 
90
                            DBUS_TYPE_INVALID)) {
 
91
                ret = -ENOMEM;
 
92
                goto finish;
 
93
        }
 
94
 
 
95
        if (!(r = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) {
 
96
                ret = translate_error(error.name);
 
97
                goto finish;
 
98
        }
 
99
 
 
100
        if (dbus_set_error_from_message(&error, r)) {
 
101
                ret = translate_error(error.name);
 
102
                goto finish;
 
103
        }
 
104
 
 
105
        ret = -EBADMSG;
 
106
        dbus_message_iter_init(r, &iter);
 
107
        while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) {
 
108
 
 
109
                if (current_type == DBUS_TYPE_VARIANT) {
 
110
                        dbus_message_iter_recurse(&iter, &subiter);
 
111
 
 
112
                        while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) {
 
113
 
 
114
                                if (current_type == DBUS_TYPE_INT32) {
 
115
                                        dbus_message_iter_get_basic(&subiter, &i32);
 
116
                                        *propval = i32;
 
117
                                        ret = 0;
 
118
                                }
 
119
 
 
120
                                if (current_type == DBUS_TYPE_INT64) {
 
121
                                        dbus_message_iter_get_basic(&subiter, &i64);
 
122
                                        *propval = i64;
 
123
                                        ret = 0;
 
124
                                }
 
125
 
 
126
                                dbus_message_iter_next (&subiter);
 
127
                         }
 
128
                }
 
129
                dbus_message_iter_next (&iter);
 
130
        }
 
131
 
 
132
finish:
 
133
 
 
134
        if (m)
 
135
                dbus_message_unref(m);
 
136
 
 
137
        if (r)
 
138
                dbus_message_unref(r);
 
139
 
 
140
        dbus_error_free(&error);
 
141
 
 
142
        return ret;
 
143
}
 
144
 
 
145
int rtkit_get_max_realtime_priority(DBusConnection *connection) {
 
146
        long long retval;
 
147
        int err;
 
148
 
 
149
        err = rtkit_get_int_property(connection, "MaxRealtimePriority", &retval);
 
150
        return err < 0 ? err : retval;
 
151
}
 
152
 
 
153
int rtkit_get_min_nice_level(DBusConnection *connection, int* min_nice_level) {
 
154
        long long retval;
 
155
        int err;
 
156
 
 
157
        err = rtkit_get_int_property(connection, "MinNiceLevel", &retval);
 
158
        if (err >= 0)
 
159
                *min_nice_level = retval;
 
160
        return err;
 
161
}
 
162
 
 
163
long long rtkit_get_rttime_usec_max(DBusConnection *connection) {
 
164
        long long retval;
 
165
        int err;
 
166
 
 
167
        err = rtkit_get_int_property(connection, "RTTimeUSecMax", &retval);
 
168
        return err < 0 ? err : retval;
 
169
}
 
170
 
 
171
int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) {
 
172
        DBusMessage *m = NULL, *r = NULL;
 
173
        dbus_uint64_t u64;
 
174
        dbus_uint32_t u32;
 
175
        DBusError error;
 
176
        int ret;
 
177
 
 
178
        dbus_error_init(&error);
 
179
 
 
180
        if (thread == 0)
 
181
                thread = _gettid();
 
182
 
 
183
        if (!(m = dbus_message_new_method_call(
 
184
                              RTKIT_SERVICE_NAME,
 
185
                              RTKIT_OBJECT_PATH,
 
186
                              "org.freedesktop.RealtimeKit1",
 
187
                              "MakeThreadRealtime"))) {
 
188
                ret = -ENOMEM;
 
189
                goto finish;
 
190
        }
 
191
 
 
192
        u64 = (dbus_uint64_t) thread;
 
193
        u32 = (dbus_uint32_t) priority;
 
194
 
 
195
        if (!dbus_message_append_args(
 
196
                            m,
 
197
                            DBUS_TYPE_UINT64, &u64,
 
198
                            DBUS_TYPE_UINT32, &u32,
 
199
                            DBUS_TYPE_INVALID)) {
 
200
                ret = -ENOMEM;
 
201
                goto finish;
 
202
        }
 
203
 
 
204
        if (!(r = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) {
 
205
                ret = translate_error(error.name);
 
206
                goto finish;
 
207
        }
 
208
 
 
209
 
 
210
        if (dbus_set_error_from_message(&error, r)) {
 
211
                ret = translate_error(error.name);
 
212
                goto finish;
 
213
        }
 
214
 
 
215
        ret = 0;
 
216
 
 
217
finish:
 
218
 
 
219
        if (m)
 
220
                dbus_message_unref(m);
 
221
 
 
222
        if (r)
 
223
                dbus_message_unref(r);
 
224
 
 
225
        dbus_error_free(&error);
 
226
 
 
227
        return ret;
 
228
}
 
229
 
 
230
int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_level) {
 
231
        DBusMessage *m = NULL, *r = NULL;
 
232
        dbus_uint64_t u64;
 
233
        dbus_int32_t s32;
 
234
        DBusError error;
 
235
        int ret;
 
236
 
 
237
        dbus_error_init(&error);
 
238
 
 
239
        if (thread == 0)
 
240
                thread = _gettid();
 
241
 
 
242
        if (!(m = dbus_message_new_method_call(
 
243
                              RTKIT_SERVICE_NAME,
 
244
                              RTKIT_OBJECT_PATH,
 
245
                              "org.freedesktop.RealtimeKit1",
 
246
                              "MakeThreadHighPriority"))) {
 
247
                ret = -ENOMEM;
 
248
                goto finish;
 
249
        }
 
250
 
 
251
        u64 = (dbus_uint64_t) thread;
 
252
        s32 = (dbus_int32_t) nice_level;
 
253
 
 
254
        if (!dbus_message_append_args(
 
255
                            m,
 
256
                            DBUS_TYPE_UINT64, &u64,
 
257
                            DBUS_TYPE_INT32, &s32,
 
258
                            DBUS_TYPE_INVALID)) {
 
259
                ret = -ENOMEM;
 
260
                goto finish;
 
261
        }
 
262
 
 
263
 
 
264
 
 
265
        if (!(r = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) {
 
266
                ret = translate_error(error.name);
 
267
                goto finish;
 
268
        }
 
269
 
 
270
 
 
271
        if (dbus_set_error_from_message(&error, r)) {
 
272
                ret = translate_error(error.name);
 
273
                goto finish;
 
274
        }
 
275
 
 
276
        ret = 0;
 
277
 
 
278
finish:
 
279
 
 
280
        if (m)
 
281
                dbus_message_unref(m);
 
282
 
 
283
        if (r)
 
284
                dbus_message_unref(r);
 
285
 
 
286
        dbus_error_free(&error);
 
287
 
 
288
        return ret;
 
289
}
 
290
 
 
291
#else
 
292
 
 
293
int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) {
 
294
        return -ENOTSUP;
 
295
}
 
296
 
 
297
int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_level) {
 
298
        return -ENOTSUP;
 
299
}
 
300
 
 
301
int rtkit_get_max_realtime_priority(DBusConnection *connection) {
 
302
        return -ENOTSUP;
 
303
}
 
304
 
 
305
int rtkit_get_min_nice_level(DBusConnection *connection, int* min_nice_level) {
 
306
        return -ENOTSUP;
 
307
}
 
308
 
 
309
long long rtkit_get_rttime_usec_max(DBusConnection *connection) {
 
310
        return -ENOTSUP;
 
311
}
 
312
 
 
313
#endif