Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,11 @@ jobs:

- name: Test fallback (Linux without dbus)
shell: bash
run: rustup run ${{ matrix.rust }} cargo test --no-default-features
# The native (no-dbus) path really promotes threads, so the tests need permission to request
# real-time scheduling. Raise RLIMIT_RTPRIO for this shell, as an admin would via systemd
# LimitRTPRIO or /etc/security/limits.conf; the unprivileged test process and its children
# inherit it. This mirrors a real deployment rather than running the tests as root.
run: |
sudo prlimit --pid $$ --rtprio=10:10
echo "RLIMIT_RTPRIO soft=$(ulimit -Sr) hard=$(ulimit -Hr)"
rustup run ${{ matrix.rust }} cargo test --no-default-features
60 changes: 33 additions & 27 deletions audio_thread_priority.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ atp_handle *atp_promote_current_thread_to_real_time(uint32_t audio_buffer_frames


/**
* Demotes the current thread promoted to real-time priority via
* `atp_demote_current_thread_from_real_time` to its previous priority.
* Demotes the current thread, promoted to real-time priority via
* `atp_promote_current_thread_to_real_time`, back to its previous priority.
*
* Returns 0 in case of success, non-zero otherwise.
*/
int32_t atp_demote_current_thread_from_real_time(atp_handle *handle);

/**
* Frees an atp_handle. This is useful when it impractical to call
*`atp_demote_current_thread_from_real_time` on the right thread. Access to the
* handle must be synchronized externaly (or the related thread must have
* Frees an atp_handle. This is useful when it is impractical to call
* `atp_demote_current_thread_from_real_time` on the right thread. Access to the
* handle must be synchronized externally (or the related thread must have
* exited).
*
* Returns 0 in case of success, non-zero otherwise.
Expand All @@ -55,19 +55,21 @@ int32_t atp_free_handle(atp_handle *handle);
/*
* Linux-only API.
*
* The Linux backend uses DBUS to promote a thread to real-time priority. In
* environment where this is not possible (due to sandboxing), this set of
* functions allow remoting the call to a process that can make DBUS calls.
* This set of functions promotes a thread from another process or thread, for
* cases where the thread to promote cannot do so itself (for example because it
* is sandboxed). With the default build the actual promotion goes through the
* rtkit D-Bus service; when the library is built without the `dbus` feature it
* is done directly, and requires the promoting process to be privileged.
*
* To do so:
* - Set the real-time limit from within the process where a
* thread will be promoted. This is a `setrlimit` call, that can be done
* before the sandbox lockdown.
* - Then, gather information on the thread that will be promoted.
* - Serialize this info.
* - Send over the serialized data via an IPC mechanism
* - Deserialize the inf
* - Call `atp_promote_thread_to_real_time`
* - Send over the serialized data via an IPC mechanism.
* - Deserialize the info.
* - Call `atp_promote_thread_to_real_time`.
*/

#ifdef __linux__
Expand All @@ -83,31 +85,34 @@ int32_t atp_free_handle(atp_handle *handle);
*
* Returns an opaque handle in case of success, NULL otherwise.
*
* This call is useful on Linux desktop only, when the process is sandboxed and
* cannot promote itself directly.
* This is useful on Linux only, to promote a thread from another process or
* thread when the thread to promote cannot do so itself (for example because it
* is sandboxed).
*/
atp_handle *atp_promote_thread_to_real_time(atp_thread_info *thread_info);

/**
* Demotes a thread promoted to real-time priority via
* `atp_demote_thread_from_real_time` to its previous priority.
* Demotes a thread, promoted to real-time priority via
* `atp_promote_thread_to_real_time`, back to its previous priority.
*
* Returns 0 in case of success, non-zero otherwise.
*
* This call is useful on Linux desktop only, when the process is sandboxed and
* cannot promote itself directly.
* This is useful on Linux only, to promote a thread from another process or
* thread when the thread to promote cannot do so itself (for example because it
* is sandboxed).
*/
int32_t atp_demote_thread_from_real_time(atp_thread_info* thread_info);

/**
* Gather informations from the calling thread, to be able to promote it from
* Gather information from the calling thread, to be able to promote it from
* another thread and/or process.
*
* Returns a non-null pointer to an `atp_thread_info` structure in case of
* sucess, to be freed later with `atp_free_thread_info`, and NULL otherwise.
* success, to be freed later with `atp_free_thread_info`, and NULL otherwise.
*
* This call is useful on Linux desktop only, when the process is sandboxed and
* cannot promote itself directly.
* This is useful on Linux only, to promote a thread from another process or
* thread when the thread to promote cannot do so itself (for example because it
* is sandboxed).
*/
atp_thread_info *atp_get_current_thread_info();

Expand All @@ -132,14 +137,15 @@ void atp_serialize_thread_info(atp_thread_info *thread_info, uint8_t *bytes);
atp_thread_info* atp_deserialize_thread_info(uint8_t *bytes);

/**
* Set real-time limit for the calling process.
* Set the real-time computation limit (RLIMIT_RTTIME) for the calling process.
*
* This is useful only on Linux desktop, and allows remoting the rtkit DBUS call
* to a process that has access to DBUS. This function has to be called before
* attempting to promote threads from another process.
* This is needed by the rtkit/D-Bus backend before a thread can be promoted
* from another process, and must be called from within that process (it can be
* done before a sandbox lockdown). Without the `dbus` feature no such limit is
* required and this is a no-op.
*
* This sets the real-time computation limit. For actually promoting the thread
* to a real-time scheduling class, see `atp_promote_thread_to_real_time`.
* This only sets the limit. For actually promoting the thread to a real-time
* scheduling class, see `atp_promote_thread_to_real_time`.
*/
int32_t atp_set_real_time_limit(uint32_t audio_buffer_frames,
uint32_t audio_samplerate_hz);
Expand Down
Loading