Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
63 changes: 36 additions & 27 deletions audio_thread_priority.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,27 @@ extern "C" {
* or an upper bound.
* audio_samplerate_hz: sample-rate for this audio stream, in Hz
*
* On Linux built without D-Bus, the requested priority defaults to 10 and can be
* overridden with the AUDIO_RT_PRIORITY environment variable (an integer 1-99).
*
* Returns an opaque handle in case of success, NULL otherwise.
*/
atp_handle *atp_promote_current_thread_to_real_time(uint32_t audio_buffer_frames,
uint32_t audio_samplerate_hz);


/**
* 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 +58,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 +88,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 +140,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