Bug 1633266 - mach vendor rust r=kinetik

Depends on D72636

Differential Revision: https://phabricator.services.mozilla.com/D72637
This commit is contained in:
Paul Adenot 2020-04-27 22:42:43 +00:00
Родитель 58207a1a00
Коммит f0c2c239ef
6 изменённых файлов: 203 добавлений и 117 удалений

4
Cargo.lock сгенерированный
Просмотреть файл

@ -110,9 +110,9 @@ dependencies = [
[[package]]
name = "audio_thread_priority"
version = "0.22.0"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "407b1b70ad4072a4ff430679b331450166b56631091d6ba46a885cf427392055"
checksum = "f8fba1500e466a39dd3faa5aed20a50dfe0aa1b905264a453bbe9f49508994cc"
dependencies = [
"cfg-if",
"dbus",

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"a052ce27f486df5cdd0cb1324e2f79546637d70dba561bf0bc882c0c7c81390b","Makefile":"0f9a771cfb30c7c4b9961d82fdca4e9e229a955bb2e636474a4101389e18e938","README.md":"bcfa4948edf52fdacd485200a0c1c886a92232cc1931eeb4e1044050f46ec253","atp_test.cpp":"8075a040941a65fb9e3f7cbf0535853ca6661c3ac442ec35569b42b24bbec797","audio_thread_priority.h":"f0ecaf1b674f794cde0dc834028e074d4e4675d22ae96acf08b2ae1dceb3474e","generate_osx_bindings.sh":"06e4e03450f788ced18d31fff5660919e6f6ec1119ddace363ffeb82f0518a71","src/lib.rs":"bf13cd15ac452f11ff367b86693b5cd6f57f8b9a8524e8ab0777af1c84905dc4","src/mach_sys.rs":"352560fcb9b41d877cff92e5b3b04d6dc68b1f30508ce4b9aed78940120a883e","src/rt_linux.rs":"87468ace38db310cb4ea9b87dd4be25b9f1d3cea08978bc9aba504f1fa3ba689","src/rt_mach.rs":"3f864805297b1172ed39b0ffe8888d21ec51cdc6183b31273f3f915473e31234","src/rt_win.rs":"3aabdcf6db810e23086c8710f55027f322e721b43a28dc7c544ca32a6d7964a5"},"package":"407b1b70ad4072a4ff430679b331450166b56631091d6ba46a885cf427392055"}
{"files":{"Cargo.toml":"ae2be582a99b1543db352c63c02a739dceb0c99ec3f632284d01f8504645c1e8","Makefile":"0f9a771cfb30c7c4b9961d82fdca4e9e229a955bb2e636474a4101389e18e938","README.md":"bcfa4948edf52fdacd485200a0c1c886a92232cc1931eeb4e1044050f46ec253","atp_test.cpp":"8075a040941a65fb9e3f7cbf0535853ca6661c3ac442ec35569b42b24bbec797","audio_thread_priority.h":"f0ecaf1b674f794cde0dc834028e074d4e4675d22ae96acf08b2ae1dceb3474e","generate_osx_bindings.sh":"06e4e03450f788ced18d31fff5660919e6f6ec1119ddace363ffeb82f0518a71","src/lib.rs":"bf13cd15ac452f11ff367b86693b5cd6f57f8b9a8524e8ab0777af1c84905dc4","src/mach_sys.rs":"352560fcb9b41d877cff92e5b3b04d6dc68b1f30508ce4b9aed78940120a883e","src/rt_linux.rs":"33f982272dd53b5e60f93ca7803c7fe3d6e615edd122bcc60cb5482e34cf8a35","src/rt_mach.rs":"a7b4deef4bebcdaa6ca6156fe5de5456bc8a61143d6764d1e3f54e639c9653da","src/rt_win.rs":"347e3ae753cefa38cf913f55f84a63a36d97f6be5f6e3c41e9da0c3ffa71ac17"},"package":"f8fba1500e466a39dd3faa5aed20a50dfe0aa1b905264a453bbe9f49508994cc"}

Просмотреть файл

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "audio_thread_priority"
version = "0.22.0"
version = "0.22.1"
authors = ["Paul Adenot <paul@paul.cx>"]
description = "Bump a thread to real-time priority, for audio work, on Linux, Windows and macOS"
license = "MPL-2.0"

Просмотреть файл

@ -11,7 +11,7 @@ use std::cmp;
use std::error::Error;
use std::io::Error as OSError;
use dbus::{Connection, BusType, Props, MessageItem, Message};
use dbus::{BusType, Connection, Message, MessageItem, Props};
use crate::AudioThreadPriorityError;
@ -23,7 +23,11 @@ type kernel_pid_t = libc::c_long;
impl From<dbus::Error> for AudioThreadPriorityError {
fn from(error: dbus::Error) -> Self {
AudioThreadPriorityError::new(&format!("{}:{}", error.name().unwrap(), error.message().unwrap()))
AudioThreadPriorityError::new(&format!(
"{}:{}",
error.name().unwrap_or("?"),
error.message().unwrap_or("?")
))
}
}
@ -45,7 +49,7 @@ pub struct RtPriorityThreadInfoInternal {
/// The PID of the process containing `thread_id` below.
pid: libc::pid_t,
/// ...
policy: libc::c_int
policy: libc::c_int,
}
impl RtPriorityThreadInfoInternal {
@ -61,8 +65,7 @@ impl RtPriorityThreadInfoInternal {
impl PartialEq for RtPriorityThreadInfoInternal {
fn eq(&self, other: &Self) -> bool {
self.thread_id == other.thread_id &&
self.pthread_id == other.pthread_id
self.thread_id == other.thread_id && self.pthread_id == other.pthread_id
}
}
@ -75,23 +78,30 @@ fn item_as_i64(i: MessageItem) -> Result<i64, AudioThreadPriorityError> {
match i {
MessageItem::Int32(i) => Ok(i as i64),
MessageItem::Int64(i) => Ok(i),
_ => Err(AudioThreadPriorityError::new(&format!("Property is not integer ({:?})", i)))
_ => Err(AudioThreadPriorityError::new(&format!(
"Property is not integer ({:?})",
i
))),
}
}
fn rtkit_set_realtime(thread: u64, pid: u64, prio: u32) -> Result<(), Box<dyn Error>> {
let m = if unsafe { libc::getpid() as u64 } == pid {
let mut m = Message::new_method_call("org.freedesktop.RealtimeKit1",
"/org/freedesktop/RealtimeKit1",
"org.freedesktop.RealtimeKit1",
"MakeThreadRealtime")?;
let mut m = Message::new_method_call(
"org.freedesktop.RealtimeKit1",
"/org/freedesktop/RealtimeKit1",
"org.freedesktop.RealtimeKit1",
"MakeThreadRealtime",
)?;
m.append_items(&[thread.into(), prio.into()]);
m
} else {
let mut m = Message::new_method_call("org.freedesktop.RealtimeKit1",
"/org/freedesktop/RealtimeKit1",
"org.freedesktop.RealtimeKit1",
"MakeThreadRealtimeWithPID")?;
let mut m = Message::new_method_call(
"org.freedesktop.RealtimeKit1",
"/org/freedesktop/RealtimeKit1",
"org.freedesktop.RealtimeKit1",
"MakeThreadRealtimeWithPID",
)?;
m.append_items(&[pid.into(), thread.into(), prio.into()]);
m
};
@ -105,25 +115,37 @@ fn rtkit_set_realtime(thread: u64, pid: u64, prio: u32) -> Result<(), Box<dyn Er
fn get_limits() -> Result<(i64, u64, libc::rlimit64), AudioThreadPriorityError> {
let c = Connection::get_private(BusType::System)?;
let p = Props::new(&c, "org.freedesktop.RealtimeKit1", "/org/freedesktop/RealtimeKit1",
"org.freedesktop.RealtimeKit1", DBUS_SOCKET_TIMEOUT);
let p = Props::new(
&c,
"org.freedesktop.RealtimeKit1",
"/org/freedesktop/RealtimeKit1",
"org.freedesktop.RealtimeKit1",
DBUS_SOCKET_TIMEOUT,
);
let mut current_limit = libc::rlimit64 {
rlim_cur: 0,
rlim_max: 0
rlim_max: 0,
};
let max_prio = item_as_i64(p.get("MaxRealtimePriority")?)?;
if max_prio < 0 {
return Err(AudioThreadPriorityError::new("invalid negative MaxRealtimePriority"));
return Err(AudioThreadPriorityError::new(
"invalid negative MaxRealtimePriority",
));
}
let max_rttime = item_as_i64(p.get("RTTimeUSecMax")?)?;
if max_rttime < 0 {
return Err(AudioThreadPriorityError::new("invalid negative RTTimeUSecMax"));
return Err(AudioThreadPriorityError::new(
"invalid negative RTTimeUSecMax",
));
}
if unsafe { libc::getrlimit64(libc::RLIMIT_RTTIME, &mut current_limit) } < 0 {
return Err(AudioThreadPriorityError::new_with_inner(&"getrlimit64", Box::new(OSError::last_os_error())));
return Err(AudioThreadPriorityError::new_with_inner(
&"getrlimit64",
Box::new(OSError::last_os_error()),
));
}
Ok((max_prio, (max_rttime as u64), current_limit))
@ -132,48 +154,72 @@ fn get_limits() -> Result<(i64, u64, libc::rlimit64), AudioThreadPriorityError>
fn set_limits(request: u64, max: u64) -> Result<(), AudioThreadPriorityError> {
// Set a soft limit to the limit requested, to be able to handle going over the limit using
// SIGXCPU. Set the hard limit to the maxium slice to prevent getting SIGKILL.
let new_limit = libc::rlimit64 { rlim_cur: request,
rlim_max: max };
let new_limit = libc::rlimit64 {
rlim_cur: request,
rlim_max: max,
};
if unsafe { libc::setrlimit64(libc::RLIMIT_RTTIME, &new_limit) } < 0 {
return Err(AudioThreadPriorityError::new_with_inner("setrlimit64", Box::new(OSError::last_os_error())));
return Err(AudioThreadPriorityError::new_with_inner(
"setrlimit64",
Box::new(OSError::last_os_error()),
));
}
Ok(())
}
pub fn promote_current_thread_to_real_time_internal(audio_buffer_frames: u32,
audio_samplerate_hz: u32)
-> Result<RtPriorityHandleInternal, AudioThreadPriorityError> {
pub fn promote_current_thread_to_real_time_internal(
audio_buffer_frames: u32,
audio_samplerate_hz: u32,
) -> Result<RtPriorityHandleInternal, AudioThreadPriorityError> {
let thread_info = get_current_thread_info_internal()?;
promote_thread_to_real_time_internal(thread_info, audio_buffer_frames, audio_samplerate_hz)
}
pub fn demote_current_thread_from_real_time_internal(rt_priority_handle: RtPriorityHandleInternal)
-> Result<(), AudioThreadPriorityError> {
pub fn demote_current_thread_from_real_time_internal(
rt_priority_handle: RtPriorityHandleInternal,
) -> Result<(), AudioThreadPriorityError> {
assert!(unsafe { libc::pthread_self() } == rt_priority_handle.thread_info.pthread_id);
let param = unsafe { std::mem::zeroed::<libc::sched_param>() };
if unsafe { libc::pthread_setschedparam(rt_priority_handle.thread_info.pthread_id,
rt_priority_handle.thread_info.policy,
&param) } < 0 {
return Err(AudioThreadPriorityError::new_with_inner(&"could not demote thread", Box::new(OSError::last_os_error())));
if unsafe {
libc::pthread_setschedparam(
rt_priority_handle.thread_info.pthread_id,
rt_priority_handle.thread_info.policy,
&param,
)
} < 0
{
return Err(AudioThreadPriorityError::new_with_inner(
&"could not demote thread",
Box::new(OSError::last_os_error()),
));
}
return Ok(());
}
/// This can be called by sandboxed code, it only restores priority to what they were.
pub fn demote_thread_from_real_time_internal(thread_info: RtPriorityThreadInfoInternal)
-> Result<(), AudioThreadPriorityError> {
pub fn demote_thread_from_real_time_internal(
thread_info: RtPriorityThreadInfoInternal,
) -> Result<(), AudioThreadPriorityError> {
let param = unsafe { std::mem::zeroed::<libc::sched_param>() };
// https://github.com/rust-lang/libc/issues/1511
const SCHED_RESET_ON_FORK: libc::c_int = 0x40000000;
if unsafe { libc::pthread_setschedparam(thread_info.pthread_id,
libc::SCHED_OTHER|SCHED_RESET_ON_FORK,
&param) } < 0 {
return Err(AudioThreadPriorityError::new_with_inner(&"could not demote thread", Box::new(OSError::last_os_error())));
if unsafe {
libc::pthread_setschedparam(
thread_info.pthread_id,
libc::SCHED_OTHER | SCHED_RESET_ON_FORK,
&param,
)
} < 0
{
return Err(AudioThreadPriorityError::new_with_inner(
&"could not demote thread",
Box::new(OSError::last_os_error()),
));
}
return Ok(());
}
@ -181,14 +227,18 @@ pub fn demote_thread_from_real_time_internal(thread_info: RtPriorityThreadInfoIn
/// Get the current thread information, as an opaque struct, that can be serialized and sent
/// accross processes. This is enough to capture the current state of the scheduling policy, and
/// an identifier to have another thread promoted to real-time.
pub fn get_current_thread_info_internal() -> Result<RtPriorityThreadInfoInternal, AudioThreadPriorityError> {
pub fn get_current_thread_info_internal(
) -> Result<RtPriorityThreadInfoInternal, AudioThreadPriorityError> {
let thread_id = unsafe { libc::syscall(libc::SYS_gettid) };
let pthread_id = unsafe { libc::pthread_self() };
let mut param = unsafe { std::mem::zeroed::<libc::sched_param>() };
let mut policy = 0;
if unsafe { libc::pthread_getschedparam(pthread_id, &mut policy, &mut param) } < 0 {
return Err(AudioThreadPriorityError::new_with_inner(&"pthread_getschedparam", Box::new(OSError::last_os_error())));
return Err(AudioThreadPriorityError::new_with_inner(
&"pthread_getschedparam",
Box::new(OSError::last_os_error()),
));
}
let pid = unsafe { libc::getpid() };
@ -197,7 +247,7 @@ pub fn get_current_thread_info_internal() -> Result<RtPriorityThreadInfoInternal
pid,
thread_id,
pthread_id,
policy
policy,
})
}
@ -205,8 +255,10 @@ pub fn get_current_thread_info_internal() -> Result<RtPriorityThreadInfoInternal
/// rtkit request to succeed, and needs to hapen in the child. We can't get the real limit here,
/// because we don't have access to DBUS, so it is hardcoded to 200ms, which is the default in the
/// rtkit package.
pub fn set_real_time_hard_limit_internal(audio_buffer_frames: u32,
audio_samplerate_hz: u32) -> Result<(), AudioThreadPriorityError> {
pub fn set_real_time_hard_limit_internal(
audio_buffer_frames: u32,
audio_samplerate_hz: u32,
) -> Result<(), AudioThreadPriorityError> {
let buffer_frames = if audio_buffer_frames > 0 {
audio_buffer_frames
} else {
@ -227,10 +279,11 @@ pub fn set_real_time_hard_limit_internal(audio_buffer_frames: u32,
}
/// Promote a thread (possibly in another process) identified by its tid, to real-time.
pub fn promote_thread_to_real_time_internal(thread_info: RtPriorityThreadInfoInternal,
audio_buffer_frames: u32,
audio_samplerate_hz: u32) -> Result<RtPriorityHandleInternal, AudioThreadPriorityError>
{
pub fn promote_thread_to_real_time_internal(
thread_info: RtPriorityThreadInfoInternal,
audio_buffer_frames: u32,
audio_samplerate_hz: u32,
) -> Result<RtPriorityHandleInternal, AudioThreadPriorityError> {
let RtPriorityThreadInfoInternal { pid, thread_id, .. } = thread_info;
let handle = RtPriorityHandleInternal { thread_info };
@ -246,10 +299,15 @@ pub fn promote_thread_to_real_time_internal(thread_info: RtPriorityThreadInfoInt
}
Err(e) => {
if unsafe { libc::setrlimit64(libc::RLIMIT_RTTIME, &limits) } < 0 {
return Err(AudioThreadPriorityError::new_with_inner(&"setrlimit64", Box::new(OSError::last_os_error())));
return Err(AudioThreadPriorityError::new_with_inner(
&"setrlimit64",
Box::new(OSError::last_os_error()),
));
}
return Err(AudioThreadPriorityError::new_with_inner(&"Thread promotion error", e));
return Err(AudioThreadPriorityError::new_with_inner(
&"Thread promotion error",
e,
));
}
}
}

Просмотреть файл

@ -2,37 +2,39 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
use mach::kern_return::{kern_return_t, KERN_SUCCESS};
use mach::port::mach_port_t;
use mach::message::mach_msg_type_number_t;
use crate::mach_sys::*;
use std::mem::size_of;
use mach::mach_time::{mach_timebase_info_data_t, mach_timebase_info};
use libc::{pthread_t, pthread_self};
use crate::AudioThreadPriorityError;
use libc::{pthread_self, pthread_t};
use log::info;
use mach::kern_return::{kern_return_t, KERN_SUCCESS};
use mach::mach_time::{mach_timebase_info, mach_timebase_info_data_t};
use mach::message::mach_msg_type_number_t;
use mach::port::mach_port_t;
use std::mem::size_of;
extern "C" {
fn pthread_mach_thread_np(tid: pthread_t) -> mach_port_t;
// Those functions are commented out in thread_policy.h but somehow it works just fine !?
fn thread_policy_set(thread: thread_t,
flavor: thread_policy_flavor_t,
policy_info: thread_policy_t,
count: mach_msg_type_number_t)
-> kern_return_t;
fn thread_policy_get(thread: thread_t,
flavor: thread_policy_flavor_t,
policy_info: thread_policy_t,
count: &mut mach_msg_type_number_t,
get_default: &mut boolean_t)
-> kern_return_t;
fn thread_policy_set(
thread: thread_t,
flavor: thread_policy_flavor_t,
policy_info: thread_policy_t,
count: mach_msg_type_number_t,
) -> kern_return_t;
fn thread_policy_get(
thread: thread_t,
flavor: thread_policy_flavor_t,
policy_info: thread_policy_t,
count: &mut mach_msg_type_number_t,
get_default: &mut boolean_t,
) -> kern_return_t;
}
// can't use size_of in const fn just now in stable, use a macro for now.
macro_rules! THREAD_TIME_CONSTRAINT_POLICY_COUNT {
() => {
(size_of::<thread_time_constraint_policy_data_t>() / size_of::<integer_t>()) as u32;
}
};
}
#[derive(Debug)]
@ -49,24 +51,28 @@ impl RtPriorityHandleInternal {
period: 0,
computation: 0,
constraint: 0,
preemptible: 0
}
}
preemptible: 0,
},
};
}
}
pub fn demote_current_thread_from_real_time_internal(rt_priority_handle: RtPriorityHandleInternal)
-> Result<(), AudioThreadPriorityError> {
pub fn demote_current_thread_from_real_time_internal(
rt_priority_handle: RtPriorityHandleInternal,
) -> Result<(), AudioThreadPriorityError> {
unsafe {
let rv: kern_return_t;
let mut h = rt_priority_handle;
rv = thread_policy_set(h.tid,
THREAD_TIME_CONSTRAINT_POLICY,
(&mut h.previous_time_constraint_policy) as *mut _ as
thread_policy_t,
THREAD_TIME_CONSTRAINT_POLICY_COUNT!());
rv = thread_policy_set(
h.tid,
THREAD_TIME_CONSTRAINT_POLICY,
(&mut h.previous_time_constraint_policy) as *mut _ as thread_policy_t,
THREAD_TIME_CONSTRAINT_POLICY_COUNT!(),
);
if rv != KERN_SUCCESS as i32 {
return Err(AudioThreadPriorityError::new("thread demotion error: thread_policy_get: RT"));
return Err(AudioThreadPriorityError::new(
"thread demotion error: thread_policy_get: RT",
));
}
info!("thread {} priority restored.", h.tid);
@ -75,10 +81,10 @@ pub fn demote_current_thread_from_real_time_internal(rt_priority_handle: RtPrior
return Ok(());
}
pub fn promote_current_thread_to_real_time_internal(audio_buffer_frames: u32,
audio_samplerate_hz: u32)
-> Result<RtPriorityHandleInternal, AudioThreadPriorityError> {
pub fn promote_current_thread_to_real_time_internal(
audio_buffer_frames: u32,
audio_samplerate_hz: u32,
) -> Result<RtPriorityHandleInternal, AudioThreadPriorityError> {
let mut rt_priority_handle = RtPriorityHandleInternal::new();
let buffer_frames = if audio_buffer_frames > 0 {
@ -98,7 +104,6 @@ pub fn promote_current_thread_to_real_time_internal(audio_buffer_frames: u32,
};
let mut count: mach_msg_type_number_t;
// Get current thread attributes, to revert back to the correct setting later if needed.
rt_priority_handle.tid = tid;
@ -107,14 +112,18 @@ pub fn promote_current_thread_to_real_time_internal(audio_buffer_frames: u32,
// default was returned instead.
let mut get_default: boolean_t = 0;
count = THREAD_TIME_CONSTRAINT_POLICY_COUNT!();
rv = thread_policy_get(tid,
THREAD_TIME_CONSTRAINT_POLICY,
(&mut time_constraints) as *mut _ as thread_policy_t,
&mut count,
&mut get_default);
rv = thread_policy_get(
tid,
THREAD_TIME_CONSTRAINT_POLICY,
(&mut time_constraints) as *mut _ as thread_policy_t,
&mut count,
&mut get_default,
);
if rv != KERN_SUCCESS as i32 {
return Err(AudioThreadPriorityError::new("thread promotion error: thread_policy_get: time_constraint"));
return Err(AudioThreadPriorityError::new(
"thread promotion error: thread_policy_get: time_constraint",
));
}
rt_priority_handle.previous_time_constraint_policy = time_constraints;
@ -134,12 +143,16 @@ pub fn promote_current_thread_to_real_time_internal(audio_buffer_frames: u32,
preemptible: 1, // true
};
rv = thread_policy_set(tid,
THREAD_TIME_CONSTRAINT_POLICY,
(&mut time_constraints) as *mut _ as thread_policy_t,
THREAD_TIME_CONSTRAINT_POLICY_COUNT!());
rv = thread_policy_set(
tid,
THREAD_TIME_CONSTRAINT_POLICY,
(&mut time_constraints) as *mut _ as thread_policy_t,
THREAD_TIME_CONSTRAINT_POLICY_COUNT!(),
);
if rv != KERN_SUCCESS as i32 {
return Err(AudioThreadPriorityError::new("thread promotion error: thread_policy_set: time_constraint"));
return Err(AudioThreadPriorityError::new(
"thread promotion error: thread_policy_set: time_constraint",
));
}
info!("thread {} bumped to real time priority.", tid);

Просмотреть файл

@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
use winapi::um::avrt::*;
use winapi::shared::ntdef::HANDLE;
use winapi::shared::minwindef::DWORD;
use winapi::shared::ntdef::HANDLE;
use winapi::um::avrt::*;
use winapi::um::errhandlingapi::GetLastError;
use crate::AudioThreadPriorityError;
@ -13,47 +13,62 @@ use log::info;
#[derive(Debug)]
pub struct RtPriorityHandleInternal {
mmcss_task_index: DWORD,
task_handle: HANDLE
mmcss_task_index: DWORD,
task_handle: HANDLE,
}
impl RtPriorityHandleInternal {
pub fn new() -> RtPriorityHandleInternal {
return RtPriorityHandleInternal {
mmcss_task_index: 0 as DWORD,
task_handle: 0 as HANDLE
}
mmcss_task_index: 0 as DWORD,
task_handle: 0 as HANDLE,
};
}
}
pub fn demote_current_thread_from_real_time_internal(rt_priority_handle: RtPriorityHandleInternal)
-> Result<(), AudioThreadPriorityError> {
pub fn demote_current_thread_from_real_time_internal(
rt_priority_handle: RtPriorityHandleInternal,
) -> Result<(), AudioThreadPriorityError> {
unsafe {
let rv = AvRevertMmThreadCharacteristics(rt_priority_handle.task_handle);
if rv == 0 {
return Err(AudioThreadPriorityError::new(&format!("Unable to restore the thread priority ({})", GetLastError())));
return Err(AudioThreadPriorityError::new(&format!(
"Unable to restore the thread priority ({})",
GetLastError()
)));
}
}
info!("task {} priority restored.", rt_priority_handle.mmcss_task_index);
info!(
"task {} priority restored.",
rt_priority_handle.mmcss_task_index
);
return Ok(())
return Ok(());
}
pub fn promote_current_thread_to_real_time_internal(_audio_buffer_frames: u32,
_audio_samplerate_hz: u32)
-> Result<RtPriorityHandleInternal, AudioThreadPriorityError> {
pub fn promote_current_thread_to_real_time_internal(
_audio_buffer_frames: u32,
_audio_samplerate_hz: u32,
) -> Result<RtPriorityHandleInternal, AudioThreadPriorityError> {
let mut handle = RtPriorityHandleInternal::new();
unsafe {
handle.task_handle = AvSetMmThreadCharacteristicsA("Audio\0".as_ptr() as _, &mut handle.mmcss_task_index);
handle.task_handle =
AvSetMmThreadCharacteristicsA("Audio\0".as_ptr() as _, &mut handle.mmcss_task_index);
if handle.task_handle.is_null() {
return Err(AudioThreadPriorityError::new(&format!("Unable to restore the thread priority ({})", GetLastError())));
return Err(AudioThreadPriorityError::new(&format!(
"Unable to restore the thread priority ({})",
GetLastError()
)));
}
}
info!("task {} bumped to real time priority.", handle.mmcss_task_index);
info!(
"task {} bumped to real time priority.",
handle.mmcss_task_index
);
Ok(handle)
}