mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-10-04 23:20:46 +00: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
|
@ -482,23 +482,34 @@ static const struct pw_impl_module_events module_events = {
|
|||
*/
|
||||
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
|
||||
* that available, and there are also other ways to use realtime
|
||||
* scheduling without that rlimit being set such as `CAP_SYS_NICE` or
|
||||
* running as root. Instead of checking a bunch of preconditions, we
|
||||
* just try if setting realtime scheduling works or not. */
|
||||
int old_scheduler;
|
||||
struct sched_param old_sched_params;
|
||||
if ((old_scheduler = sched_getscheduler(0)) != 0 ||
|
||||
if ((old_policy = sched_getscheduler(0)) < 0 ||
|
||||
sched_getparam(0, &old_sched_params) != 0) {
|
||||
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);
|
||||
new_sched_params.sched_priority = priority;
|
||||
if (sched_setscheduler(0, REALTIME_POLICY, &new_sched_params) == 0) {
|
||||
sched_setscheduler(0, old_scheduler, &old_sched_params);
|
||||
if ((old_policy & PW_SCHED_RESET_ON_FORK) != 0) {
|
||||
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;
|
||||
} else {
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue