mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-23 06:59:58 -05:00
thread: add thread.reset-on-fork
Add a new thread.reset-on-fork property for the thread creator. when set to false, it will clear the default SCHED_RESET_ON_FORK flag and new RT threads will be able to fork and inherit the rt policy and priority. When creating a thread make sure we set SCHED_RESET_ON_FORK when the thread.reset-on-fork property is not explicitly false; module-rt needs to preserve the SCHED_RESET_ON_FORK flag when changing the policy. Set thread.reset-on-fork=false explicitly for JACK clients to restore the JACK behaviour where implementations can fork and inherit the RT policy and priority by default. Fixes #4966
This commit is contained in:
parent
1f3bc6eff5
commit
1191c18641
6 changed files with 48 additions and 11 deletions
|
|
@ -4299,6 +4299,7 @@ jack_client_t * jack_client_open (const char *client_name,
|
|||
|
||||
client->props = pw_properties_new(
|
||||
PW_KEY_LOOP_CANCEL, "true",
|
||||
SPA_KEY_THREAD_RESET_ON_FORK, "false",
|
||||
PW_KEY_REMOTE_NAME, client->server_name,
|
||||
PW_KEY_CLIENT_NAME, client_name,
|
||||
PW_KEY_CLIENT_API, "jack",
|
||||
|
|
|
|||
|
|
@ -117,6 +117,8 @@ SPA_API_THREAD int spa_thread_utils_drop_rt(struct spa_thread_utils *o,
|
|||
#define SPA_KEY_THREAD_STACK_SIZE "thread.stack-size" /* the stack size of the thread */
|
||||
#define SPA_KEY_THREAD_AFFINITY "thread.affinity" /* array of CPUs for this thread */
|
||||
#define SPA_KEY_THREAD_CREATOR "thread.creator" /* platform specific thread creator function */
|
||||
#define SPA_KEY_THREAD_RESET_ON_FORK "thread.reset-on-fork" /* reset priority and policy for real-time threads
|
||||
on fork. Default true */
|
||||
|
||||
/**
|
||||
* \}
|
||||
|
|
|
|||
|
|
@ -650,8 +650,8 @@ static int set_rlimit(struct rlimit *rlim)
|
|||
|
||||
static int acquire_rt_sched(struct spa_thread *thread, int priority)
|
||||
{
|
||||
int err, min, max;
|
||||
struct sched_param sp;
|
||||
int err, min, max, new_policy, old_policy;
|
||||
struct sched_param new_sched_params, old_sched_params;
|
||||
pthread_t pt = (pthread_t)thread;
|
||||
|
||||
min = max = 0;
|
||||
|
|
@ -663,10 +663,18 @@ static int acquire_rt_sched(struct spa_thread *thread, int priority)
|
|||
priority, min, max, REALTIME_POLICY);
|
||||
priority = SPA_CLAMP(priority, min, max);
|
||||
}
|
||||
if ((err = pthread_getschedparam(pt, &old_policy, &old_sched_params)) != 0) {
|
||||
pw_log_warn("Failed to get scheduling params: %s", strerror(err));
|
||||
old_policy = SCHED_RESET_ON_FORK;
|
||||
}
|
||||
|
||||
spa_zero(sp);
|
||||
sp.sched_priority = priority;
|
||||
if ((err = pthread_setschedparam(pt, REALTIME_POLICY | SCHED_RESET_ON_FORK, &sp)) != 0) {
|
||||
spa_zero(new_sched_params);
|
||||
new_sched_params.sched_priority = priority;
|
||||
new_policy = REALTIME_POLICY;
|
||||
if ((old_policy & SCHED_RESET_ON_FORK) != 0)
|
||||
new_policy |= SCHED_RESET_ON_FORK;
|
||||
|
||||
if ((err = pthread_setschedparam(pt, new_policy, &new_sched_params)) != 0) {
|
||||
pw_log_warn("could not make thread %p realtime: %s", thread, strerror(err));
|
||||
return -err;
|
||||
}
|
||||
|
|
@ -677,12 +685,21 @@ static int acquire_rt_sched(struct spa_thread *thread, int priority)
|
|||
|
||||
static int impl_drop_rt_generic(void *object, struct spa_thread *thread)
|
||||
{
|
||||
struct sched_param sp;
|
||||
struct sched_param new_sched_params, old_sched_params;
|
||||
pthread_t pt = (pthread_t)thread;
|
||||
int err;
|
||||
int err, new_policy, old_policy;
|
||||
|
||||
spa_zero(sp);
|
||||
if ((err = pthread_setschedparam(pt, SCHED_OTHER | SCHED_RESET_ON_FORK, &sp)) != 0) {
|
||||
if ((err = pthread_getschedparam(pt, &old_policy, &old_sched_params)) != 0) {
|
||||
pw_log_warn("Failed to get scheduling params: %s", strerror(err));
|
||||
old_policy = SCHED_RESET_ON_FORK;
|
||||
}
|
||||
|
||||
spa_zero(new_sched_params);
|
||||
new_policy = SCHED_OTHER;
|
||||
if (SPA_FLAG_IS_SET(old_policy, SCHED_RESET_ON_FORK))
|
||||
new_policy |= SCHED_RESET_ON_FORK;
|
||||
|
||||
if ((err = pthread_setschedparam(pt, new_policy, &new_sched_params)) != 0) {
|
||||
pw_log_debug("thread %p: SCHED_OTHER|SCHED_RESET_ON_FORK failed: %s",
|
||||
thread, strerror(err));
|
||||
return -err;
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ static struct pw_data_loop *loop_new(struct pw_loop *loop, const struct spa_dict
|
|||
}
|
||||
this->loop = loop;
|
||||
this->rt_prio = -1;
|
||||
this->reset_on_fork = true;
|
||||
|
||||
if (props != NULL) {
|
||||
if ((str = spa_dict_lookup(props, PW_KEY_LOOP_CANCEL)) != NULL)
|
||||
|
|
@ -122,6 +123,8 @@ static struct pw_data_loop *loop_new(struct pw_loop *loop, const struct spa_dict
|
|||
name = str;
|
||||
if ((str = spa_dict_lookup(props, SPA_KEY_THREAD_AFFINITY)) != NULL)
|
||||
this->affinity = strdup(str);
|
||||
if ((str = spa_dict_lookup(props, SPA_KEY_THREAD_RESET_ON_FORK)) != NULL)
|
||||
this->reset_on_fork = spa_atob(str);
|
||||
}
|
||||
if (class == NULL)
|
||||
class = this->rt_prio != 0 ? "data.rt" : "data";
|
||||
|
|
@ -236,7 +239,7 @@ int pw_data_loop_start(struct pw_data_loop *loop)
|
|||
if (!loop->running) {
|
||||
struct spa_thread_utils *utils;
|
||||
struct spa_thread *thr;
|
||||
struct spa_dict_item items[2];
|
||||
struct spa_dict_item items[3];
|
||||
uint32_t n_items = 0;
|
||||
|
||||
loop->running = true;
|
||||
|
|
@ -248,6 +251,8 @@ int pw_data_loop_start(struct pw_data_loop *loop)
|
|||
if (loop->affinity)
|
||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_THREAD_AFFINITY,
|
||||
loop->affinity);
|
||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_THREAD_RESET_ON_FORK,
|
||||
loop->reset_on_fork ? "true" : "false");
|
||||
|
||||
thr = spa_thread_utils_create(utils, &SPA_DICT_INIT(items, n_items), do_loop, loop);
|
||||
loop->thread = (pthread_t)thr;
|
||||
|
|
|
|||
|
|
@ -431,6 +431,7 @@ struct pw_data_loop {
|
|||
char *class;
|
||||
char **classes;
|
||||
int rt_prio;
|
||||
bool reset_on_fork;
|
||||
struct spa_hook_list listener_list;
|
||||
|
||||
struct spa_thread_utils *thread_utils;
|
||||
|
|
|
|||
|
|
@ -92,8 +92,10 @@ static struct spa_thread *impl_create(void *object,
|
|||
pthread_t pt;
|
||||
pthread_attr_t *attr = NULL, attributes;
|
||||
const char *str;
|
||||
int err;
|
||||
int err, old_policy, new_policy;
|
||||
int (*create_func)(pthread_t *, const pthread_attr_t *attr, void *(*start)(void*), void *) = NULL;
|
||||
struct sched_param sp;
|
||||
bool reset_on_fork = true;
|
||||
|
||||
attr = pw_thread_fill_attr(props, &attributes);
|
||||
|
||||
|
|
@ -118,7 +120,16 @@ static struct spa_thread *impl_create(void *object,
|
|||
if ((str = spa_dict_lookup(props, SPA_KEY_THREAD_AFFINITY)) != NULL &&
|
||||
(err = thread_setaffinity(pt, str)) != 0)
|
||||
pw_log_warn("pthread_setaffinity error: %s", strerror(-err));
|
||||
if ((str = spa_dict_lookup(props, SPA_KEY_THREAD_RESET_ON_FORK)) != NULL)
|
||||
reset_on_fork = spa_atob(str);
|
||||
}
|
||||
|
||||
pthread_getschedparam(pt, &old_policy, &sp);
|
||||
new_policy = old_policy;
|
||||
SPA_FLAG_UPDATE(new_policy, SCHED_RESET_ON_FORK, reset_on_fork);
|
||||
if (old_policy != new_policy)
|
||||
pthread_setschedparam(pt, new_policy, &sp);
|
||||
|
||||
return (struct spa_thread*)pt;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue