From bfa3c6c13793e4dbc8a9d2342f68b99d10b0c7d2 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 5 Jul 2021 10:05:37 +0200 Subject: [PATCH] thread: add interface to manage threads Add an interface to create and join threads as well as change the priority on the threads. --- src/pipewire/meson.build | 2 + src/pipewire/thread.c | 118 +++++++++++++++++++++++++++++++++++++++ src/pipewire/thread.h | 76 +++++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 src/pipewire/thread.c create mode 100644 src/pipewire/thread.h diff --git a/src/pipewire/meson.build b/src/pipewire/meson.build index d49677350..f66ce8746 100644 --- a/src/pipewire/meson.build +++ b/src/pipewire/meson.build @@ -39,6 +39,7 @@ pipewire_headers = [ 'proxy.h', 'resource.h', 'stream.h', + 'thread.h', 'thread-loop.h', 'type.h', 'utils.h', @@ -75,6 +76,7 @@ pipewire_sources = [ 'resource.c', 'settings.c', 'stream.c', + 'thread.c', 'thread-loop.c', 'utils.c', 'work-queue.c', diff --git a/src/pipewire/thread.c b/src/pipewire/thread.c new file mode 100644 index 000000000..549b63a60 --- /dev/null +++ b/src/pipewire/thread.c @@ -0,0 +1,118 @@ +/* PipeWire + * + * Copyright © 2021 Wim Taymans + * + * 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 (including the next + * paragraph) 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 "thread.h" + + +static struct pw_thread *impl_create(void *data, + const struct spa_dict *props, + void *(*start)(void*), void *arg) +{ + pthread_t pt; + int err; + if ((err = pthread_create(&pt, NULL, start, arg)) != 0) { + errno = err; + return NULL; + } + return (struct pw_thread*)pt; +} + +static int impl_join(void *data, struct pw_thread *thread, void **retval) +{ + pthread_t pt = (pthread_t)thread; + return pthread_join(pt, retval); +} + +static struct { + struct pw_thread_utils utils; + struct pw_thread_utils_methods methods; +} default_impl = { + { { PW_TYPE_INTERFACE_ThreadUtils, + PW_VERSION_THREAD_UTILS, + SPA_CALLBACKS_INIT(&default_impl.methods, + &default_impl) } }, + { PW_VERSION_THREAD_UTILS_METHODS, + .create = impl_create, + .join = impl_join, } +}; + +static struct pw_thread_utils *global_impl = &default_impl.utils; + +SPA_EXPORT +void pw_thread_utils_set_impl(struct pw_thread_utils *impl) +{ + if (impl == NULL) + impl = &default_impl.utils; + global_impl = impl; +} + +SPA_EXPORT +struct pw_thread *pw_thread_utils_create(const struct spa_dict *props, + void *(*start_routine)(void*), void *arg) +{ + struct pw_thread *res = NULL; + spa_interface_call_res(&global_impl->iface, + struct pw_thread_utils_methods, res, create, 0, + props, start_routine, arg); + return res; +} + +SPA_EXPORT +int pw_thread_utils_join(struct pw_thread *thread, void **retval) +{ + int res = -ENOTSUP; + spa_interface_call_res(&global_impl->iface, + struct pw_thread_utils_methods, res, join, 0, + thread, retval); + return res; +} + +SPA_EXPORT +int pw_thread_utils_acquire_rt(struct pw_thread *thread, int priority) +{ + int res = -ENOTSUP; + spa_interface_call_res(&global_impl->iface, + struct pw_thread_utils_methods, res, acquire_rt, 0, + thread, priority); + return res; +} + +SPA_EXPORT +int pw_thread_utils_drop_rt(struct pw_thread *thread) +{ + int res = -ENOTSUP; + spa_interface_call_res(&global_impl->iface, + struct pw_thread_utils_methods, res, drop_rt, 0, thread); + return res; +} diff --git a/src/pipewire/thread.h b/src/pipewire/thread.h new file mode 100644 index 000000000..58ecafb89 --- /dev/null +++ b/src/pipewire/thread.h @@ -0,0 +1,76 @@ +/* PipeWire + * + * Copyright © 2021 Wim Taymans + * + * 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 (including the next + * paragraph) 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. + */ + +#ifndef PIPEWIRE_THREAD_H +#define PIPEWIRE_THREAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include + +/** \defgroup pw_thread Thread related functions + * + * \brief functions to manipulate threads + */ + +#define PW_TYPE_INTERFACE_ThreadUtils PW_TYPE_INFO_INTERFACE_BASE "ThreadUtils" + +struct pw_thread; + +#define PW_VERSION_THREAD_UTILS 0 +struct pw_thread_utils { struct spa_interface iface; }; + +/** thread utils */ +struct pw_thread_utils_methods { +#define PW_VERSION_THREAD_UTILS_METHODS 0 + uint32_t version; + + struct pw_thread * (*create) (void *data, const struct spa_dict *props, + void *(*start)(void*), void *arg); + int (*join)(void *data, struct pw_thread *thread, void **retval); + + int (*acquire_rt) (void *data, struct pw_thread *thread, int priority); + int (*drop_rt) (void *data, struct pw_thread *thread); +}; + +void pw_thread_utils_set_impl(struct pw_thread_utils *impl); + +struct pw_thread *pw_thread_utils_create(const struct spa_dict *props, + void *(*start)(void*), void *arg); +int pw_thread_utils_join(struct pw_thread *thread, void **retval); + +int pw_thread_utils_acquire_rt(struct pw_thread *thread, int priority); +int pw_thread_utils_drop_rt(struct pw_thread *thread); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PIPEWIRE_THREAD_H */