mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
module-rt: Handle realtime sched check edge cases
The policy can of course be higher than zero if the current thread uses anything other than `SCHED_OTHER`, and `SCHED_RESET_ON_FORK` needs to be set according to the old policy or we'll either run into errors or cause unwanted side effects.
This commit is contained in:
parent
e60f62e69b
commit
5d890435b4
1 changed files with 17 additions and 6 deletions
|
|
@ -482,23 +482,34 @@ static const struct pw_impl_module_events module_events = {
|
||||||
*/
|
*/
|
||||||
static bool check_realtime_priviliges(rlim_t priority)
|
static bool check_realtime_priviliges(rlim_t priority)
|
||||||
{
|
{
|
||||||
|
int old_policy;
|
||||||
|
struct sched_param old_sched_params;
|
||||||
|
int new_policy = REALTIME_POLICY;
|
||||||
|
struct sched_param new_sched_params;
|
||||||
|
|
||||||
/* We could check `RLIMIT_RTPRIO`, but the BSDs generally don't have
|
/* We could check `RLIMIT_RTPRIO`, but the BSDs generally don't have
|
||||||
* that available, and there are also other ways to use realtime
|
* that available, and there are also other ways to use realtime
|
||||||
* scheduling without that rlimit being set such as `CAP_SYS_NICE` or
|
* scheduling without that rlimit being set such as `CAP_SYS_NICE` or
|
||||||
* running as root. Instead of checking a bunch of preconditions, we
|
* running as root. Instead of checking a bunch of preconditions, we
|
||||||
* just try if setting realtime scheduling works or not. */
|
* just try if setting realtime scheduling works or not. */
|
||||||
int old_scheduler;
|
if ((old_policy = sched_getscheduler(0)) < 0 ||
|
||||||
struct sched_param old_sched_params;
|
|
||||||
if ((old_scheduler = sched_getscheduler(0)) != 0 ||
|
|
||||||
sched_getparam(0, &old_sched_params) != 0) {
|
sched_getparam(0, &old_sched_params) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sched_param new_sched_params;
|
/* If the current scheduling policy has `SCHED_RESET_ON_FORK` set, then
|
||||||
|
* this also needs to be set here or `sched_setscheduler()` will return
|
||||||
|
* an error code. Similarly, if it is not set, then we don't want to set
|
||||||
|
* it here as it would irreversible change the current thread's
|
||||||
|
* scheduling policy. */
|
||||||
spa_zero(new_sched_params);
|
spa_zero(new_sched_params);
|
||||||
new_sched_params.sched_priority = priority;
|
new_sched_params.sched_priority = priority;
|
||||||
if (sched_setscheduler(0, REALTIME_POLICY, &new_sched_params) == 0) {
|
if ((old_policy & PW_SCHED_RESET_ON_FORK) != 0) {
|
||||||
sched_setscheduler(0, old_scheduler, &old_sched_params);
|
new_policy |= PW_SCHED_RESET_ON_FORK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sched_setscheduler(0, new_policy, &new_sched_params) == 0) {
|
||||||
|
sched_setscheduler(0, old_policy, &old_sched_params);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue