mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-10-29 05:40:27 -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) | ||||
| { | ||||
| 	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Robbert van der Helm
						Robbert van der Helm