rtkit_client_rs/
lib.rs

1mod low_level_zbus_api;
2
3#[derive(thiserror::Error, Debug)]
4pub enum Error {
5    #[error("Permission denied")]
6    PermissionDenied,
7
8    #[error(transparent)]
9    ZbusError(#[from] zbus::Error),
10
11    #[error(transparent)]
12    ZbusMethodError(#[from] zbus::fdo::Error),
13}
14
15/// Helper for [make_thread_realtime], uses the current thread's tid.
16pub fn make_current_thread_realtime(priority: Option<u32>) -> Result<u32, Error> {
17    let thread_id = nix::unistd::gettid().as_raw().try_into().unwrap();
18    make_thread_realtime(thread_id, priority)
19}
20
21/// Elevates the realtime priority of a thread as close as possible to the requested priority.
22///
23/// If no priority is specified, the maximum priority allowed by the system will be used.
24///
25/// Returns the actual priority that was set.
26pub fn make_thread_realtime(tid: u64, priority: Option<u32>) -> Result<u32, Error> {
27    debug_assert!(
28        priority.is_some_and(|p| p <= 99),
29        "priority must be between 0 and 99"
30    );
31
32    let connection = zbus::blocking::Connection::system()?;
33    let proxy = low_level_zbus_api::RTKitProxyBlocking::builder(&connection)
34        .cache_properties(zbus::proxy::CacheProperties::No)
35        .build()?;
36
37    let max_realtime_priority = proxy.max_realtime_priority()?;
38    debug_assert!(
39        (0..=99).contains(&max_realtime_priority),
40        "max_realtime_priority must be between 0 and 99"
41    );
42    let priority = priority.unwrap_or(max_realtime_priority as u32);
43
44    proxy
45        .make_thread_realtime(tid, priority)
46        .map(|_| priority)
47        .map_err(|e| match e {
48            zbus::fdo::Error::AccessDenied(_) => Error::PermissionDenied,
49            e => Error::ZbusMethodError(e),
50        })
51}
52
53/// Elevates the realtime priority of a specified processes thread as close as possible to the requested priority.
54///
55/// If no priority is specified, the maximum priority allowed by the system will be used.
56///
57/// Returns the actual priority that was set.
58pub fn make_process_thread_realtime(
59    pid: u64,
60    tid: u64,
61    priority: Option<u32>,
62) -> Result<u32, Error> {
63    debug_assert!(
64        priority.is_some_and(|p| p <= 99),
65        "priority must be between 0 and 99"
66    );
67
68    let connection = zbus::blocking::Connection::system()?;
69    let proxy = low_level_zbus_api::RTKitProxyBlocking::builder(&connection)
70        .cache_properties(zbus::proxy::CacheProperties::No)
71        .build()?;
72
73    let max_realtime_priority = proxy.max_realtime_priority()?;
74    debug_assert!(
75        (0..=99).contains(&max_realtime_priority),
76        "max_realtime_priority must be between 0 and 99"
77    );
78    let priority = priority.unwrap_or(max_realtime_priority as u32);
79
80    proxy
81        .make_thread_realtime_with_pid(pid, tid, priority)
82        .map(|_| priority)
83        .map_err(|e| match e {
84            zbus::fdo::Error::AccessDenied(_) => Error::PermissionDenied,
85            e => Error::ZbusMethodError(e),
86        })
87}