From 7ecfc28d0faccbf044318582a2984ed6cf742872 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 24 Nov 2016 18:17:29 +0100 Subject: [PATCH] use plain libdbus instead of GDBus --- meson.build | 1 + pinos/client/meson.build | 2 +- pinos/client/rtkit.c | 402 +++++++++++++++++++++++++++++--------- pinos/modules/meson.build | 2 +- 4 files changed, 318 insertions(+), 89 deletions(-) diff --git a/meson.build b/meson.build index 6dabc1b8f..3f9957df3 100644 --- a/meson.build +++ b/meson.build @@ -127,6 +127,7 @@ mathlib = cc.find_library('m', required : false) rt_lib = cc.find_library('rt', required : false) # clock_gettime dl_lib = cc.find_library('dl', required : false) pthread_lib = cc.find_library('pthread', required : true) +dbus_dep = dependency('dbus-1') gst_dep = [dependency('gstreamer-1.0'), dependency('gstreamer-plugins-base-1.0'), dependency('gstreamer-video-1.0'), diff --git a/pinos/client/meson.build b/pinos/client/meson.build index 2bafd6c74..f19d07463 100644 --- a/pinos/client/meson.build +++ b/pinos/client/meson.build @@ -52,7 +52,7 @@ libpinos = shared_library('pinos', pinos_sources, include_directories : [configinc, spa_inc], link_with : spalib, install : true, - dependencies : [glib_dep, gio_dep, mathlib, pthread_lib], + dependencies : [glib_dep, dbus_dep, mathlib, pthread_lib], ) pinos_dep = declare_dependency(link_with : libpinos, diff --git a/pinos/client/rtkit.c b/pinos/client/rtkit.c index 1189ca788..36dd7492b 100644 --- a/pinos/client/rtkit.c +++ b/pinos/client/rtkit.c @@ -16,135 +16,363 @@ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ +/*** + Copyright 2009 Lennart Poettering + Copyright 2010 David Henningsson + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ -#include -#include #include +#include +#include + +#include + +#include #include "rtkit.h" -#include - struct _PinosRTKitBus { - GDBusConnection *bus; + DBusConnection *bus; }; -static pid_t _gettid(void) { - return (pid_t) syscall(SYS_gettid); -} - -static int -translate_error (GError *error) -{ - const gchar *name = g_dbus_error_get_remote_error (error); - - if (strcmp (name, "org.freedesktop.DBus.Error.NoMemory") == 0) - return -ENOMEM; - if (strcmp (name, "org.freedesktop.DBus.Error.ServiceUnknown") == 0 || - strcmp (name, "org.freedesktop.DBus.Error.NameHasNoOwner") == 0) - return -ENOENT; - if (strcmp (name, "org.freedesktop.DBus.Error.AccessDenied") == 0 || - strcmp (name, "org.freedesktop.DBus.Error.AuthFailed") == 0) - return -EACCES; - - return -EIO; -} - PinosRTKitBus * -pinos_rtkit_bus_get_system (void) +pinos_rtkit_bus_get_system (void) { PinosRTKitBus *bus; + DBusError error; - bus = g_slice_new (PinosRTKitBus); - bus->bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); + dbus_error_init(&error); + + bus = calloc (1, sizeof (PinosRTKitBus)); + bus->bus = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error); + if (bus->bus == NULL) + goto error; + + dbus_connection_set_exit_on_disconnect (bus->bus, false); return bus; + +error: + pinos_log_error ("Failed to connect to system bus: %s", error.message); + dbus_error_free (&error); + return NULL; } void pinos_rtkit_bus_free (PinosRTKitBus *system_bus) { - g_object_unref (system_bus->bus); - g_slice_free (PinosRTKitBus, system_bus); + dbus_connection_close (system_bus->bus); + dbus_connection_unref (system_bus->bus); + free (system_bus); +} + +#if defined(__linux__) && !defined(__ANDROID__) + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + + +static pid_t _gettid(void) { + return (pid_t) syscall(SYS_gettid); +} + +static int translate_error(const char *name) { + if (0 == strcmp (name, DBUS_ERROR_NO_MEMORY)) + return -ENOMEM; + if (0 == strcmp (name, DBUS_ERROR_SERVICE_UNKNOWN) || + 0 == strcmp (name, DBUS_ERROR_NAME_HAS_NO_OWNER)) + return -ENOENT; + if (0 == strcmp (name, DBUS_ERROR_ACCESS_DENIED) || + 0 == strcmp (name, DBUS_ERROR_AUTH_FAILED)) + return -EACCES; + + return -EIO; +} + +static long long rtkit_get_int_property(PinosRTKitBus *connection, const char* propname, long long* propval) { + DBusMessage *m = NULL, *r = NULL; + DBusMessageIter iter, subiter; + dbus_int64_t i64; + dbus_int32_t i32; + DBusError error; + int current_type; + long long ret; + const char * interfacestr = "org.freedesktop.RealtimeKit1"; + + dbus_error_init(&error); + + if (!(m = dbus_message_new_method_call( + RTKIT_SERVICE_NAME, + RTKIT_OBJECT_PATH, + "org.freedesktop.DBus.Properties", + "Get"))) { + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, &interfacestr, + DBUS_TYPE_STRING, &propname, + DBUS_TYPE_INVALID)) { + ret = -ENOMEM; + goto finish; + } + + if (!(r = dbus_connection_send_with_reply_and_block(connection->bus, m, -1, &error))) { + ret = translate_error(error.name); + goto finish; + } + + if (dbus_set_error_from_message(&error, r)) { + ret = translate_error(error.name); + goto finish; + } + + ret = -EBADMSG; + dbus_message_iter_init(r, &iter); + while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) { + + if (current_type == DBUS_TYPE_VARIANT) { + dbus_message_iter_recurse(&iter, &subiter); + + while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) { + + if (current_type == DBUS_TYPE_INT32) { + dbus_message_iter_get_basic(&subiter, &i32); + *propval = i32; + ret = 0; + } + + if (current_type == DBUS_TYPE_INT64) { + dbus_message_iter_get_basic(&subiter, &i64); + *propval = i64; + ret = 0; + } + + dbus_message_iter_next (&subiter); + } + } + dbus_message_iter_next (&iter); + } + +finish: + + if (m) + dbus_message_unref(m); + + if (r) + dbus_message_unref(r); + + dbus_error_free(&error); + + return ret; +} + +int pinos_rtkit_get_max_realtime_priority(PinosRTKitBus *connection) { + long long retval; + int err; + + err = rtkit_get_int_property(connection, "MaxRealtimePriority", &retval); + return err < 0 ? err : retval; +} + +int pinos_rtkit_get_min_nice_level(PinosRTKitBus *connection, int* min_nice_level) { + long long retval; + int err; + + err = rtkit_get_int_property(connection, "MinNiceLevel", &retval); + if (err >= 0) + *min_nice_level = retval; + return err; +} + +long long pinos_rtkit_get_rttime_usec_max(PinosRTKitBus *connection) { + long long retval; + int err; + + err = rtkit_get_int_property(connection, "RTTimeUSecMax", &retval); + return err < 0 ? err : retval; } int -pinos_rtkit_make_realtime (PinosRTKitBus *system_bus, +pinos_rtkit_make_realtime (PinosRTKitBus *connection, pid_t thread, int priority) { - GVariant *v; - GError *error = NULL; + DBusMessage *m = NULL, *r = NULL; + dbus_uint64_t u64; + dbus_uint32_t u32; + DBusError error; + int ret; - if (thread == 0) - thread = _gettid(); + dbus_error_init(&error); - v = g_dbus_connection_call_sync (system_bus->bus, - RTKIT_SERVICE_NAME, - RTKIT_OBJECT_PATH, - "org.freedesktop.RealtimeKit1", - "MakeThreadRealtime", - g_variant_new ("(tu)", - (guint64) thread, - (guint32) priority), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (v == NULL) - return translate_error (error); + if (thread == 0) + thread = _gettid(); - g_variant_unref (v); + if (!(m = dbus_message_new_method_call( + RTKIT_SERVICE_NAME, + RTKIT_OBJECT_PATH, + "org.freedesktop.RealtimeKit1", + "MakeThreadRealtime"))) { + ret = -ENOMEM; + goto finish; + } - return 0; + u64 = (dbus_uint64_t) thread; + u32 = (dbus_uint32_t) priority; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_UINT64, &u64, + DBUS_TYPE_UINT32, &u32, + DBUS_TYPE_INVALID)) { + ret = -ENOMEM; + goto finish; + } + + if (!(r = dbus_connection_send_with_reply_and_block(connection->bus, m, -1, &error))) { + ret = translate_error(error.name); + goto finish; + } + + + if (dbus_set_error_from_message(&error, r)) { + ret = translate_error(error.name); + goto finish; + } + + ret = 0; + +finish: + + if (m) + dbus_message_unref(m); + + if (r) + dbus_message_unref(r); + + dbus_error_free(&error); + + return ret; } int -pinos_rtkit_make_high_priority (PinosRTKitBus *system_bus, +pinos_rtkit_make_high_priority (PinosRTKitBus *connection, pid_t thread, int nice_level) { - GVariant *v; - GError *error = NULL; + DBusMessage *m = NULL, *r = NULL; + dbus_uint64_t u64; + dbus_int32_t s32; + DBusError error; + int ret; - if (thread == 0) - thread = _gettid(); + dbus_error_init(&error); - v = g_dbus_connection_call_sync (system_bus->bus, - RTKIT_SERVICE_NAME, - RTKIT_OBJECT_PATH, - "org.freedesktop.RealtimeKit1", - "MakeThreadHighPriority", - g_variant_new ("(tu)", - (guint64) thread, - (guint32) nice_level), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (v == NULL) - return translate_error (error); - g_variant_unref (v); + if (thread == 0) + thread = _gettid(); - return 0; + if (!(m = dbus_message_new_method_call( + RTKIT_SERVICE_NAME, + RTKIT_OBJECT_PATH, + "org.freedesktop.RealtimeKit1", + "MakeThreadHighPriority"))) { + ret = -ENOMEM; + goto finish; + } + + u64 = (dbus_uint64_t) thread; + s32 = (dbus_int32_t) nice_level; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_UINT64, &u64, + DBUS_TYPE_INT32, &s32, + DBUS_TYPE_INVALID)) { + ret = -ENOMEM; + goto finish; + } + + + + if (!(r = dbus_connection_send_with_reply_and_block(connection->bus, m, -1, &error))) { + ret = translate_error(error.name); + goto finish; + } + + + if (dbus_set_error_from_message(&error, r)) { + ret = translate_error(error.name); + goto finish; + } + + ret = 0; + +finish: + + if (m) + dbus_message_unref(m); + + if (r) + dbus_message_unref(r); + + dbus_error_free(&error); + + return ret; } -int pinos_rtkit_get_max_realtime_priority (PinosRTKitBus *system_bus) -{ - return 0; +#else + +int pinos_rtkit_make_realtime(PinosRTKitBus *connection, pid_t thread, int priority) { + return -ENOTSUP; } -int pinos_rtkit_get_min_nice_level (PinosRTKitBus *system_bus, int* min_nice_level) -{ - return 0; +int pinos_rtkit_make_high_priority(PinosRTKitBus *connection, pid_t thread, int nice_level) { + return -ENOTSUP; } -/* Return the maximum value of RLIMIT_RTTIME to set before attempting a - * realtime request. A negative value is an errno style error code. - */ -long long pinos_rtkit_get_rttime_usec_max (PinosRTKitBus *system_bus) -{ - return 0; +int pinos_rtkit_get_max_realtime_priority(PinosRTKitBus *connection) { + return -ENOTSUP; } + +int pinos_rtkit_get_min_nice_level(PinosRTKitBus *connection, int* min_nice_level) { + return -ENOTSUP; +} + +long long pinos_rtkit_get_rttime_usec_max(PinosRTKitBus *connection) { + return -ENOTSUP; +} + +#endif diff --git a/pinos/modules/meson.build b/pinos/modules/meson.build index 16c65e4b7..550433c4c 100644 --- a/pinos/modules/meson.build +++ b/pinos/modules/meson.build @@ -21,7 +21,7 @@ pinos_module_protocol_dbus = shared_library('pinos-module-protocol-dbus', [ 'mod link_with : spalib, install : true, install_dir : '@0@/pinos-0.1'.format(get_option('libdir')), - dependencies : [gobject_dep, gmodule_dep, glib_dep, gio_dep, mathlib, dl_lib, pinos_dep, pinoscore_dep], + dependencies : [glib_dep, gio_dep, mathlib, dl_lib, pinos_dep, pinoscore_dep], ) pinos_module_protocol_native = shared_library('pinos-module-protocol-native', [ 'module-protocol-native.c' ],