Backed out 5 changesets (bug 1590249) for Build bustage in AudioThreadPriorityError. CLOSED TREE

Backed out changeset 301b1a49db9b (bug 1590249)
Backed out changeset c675b890508d (bug 1590249)
Backed out changeset ed1cd65eedae (bug 1590249)
Backed out changeset 0a7873a6b522 (bug 1590249)
Backed out changeset 36f6505b50c9 (bug 1590249)
This commit is contained in:
Dorel Luca 2020-01-26 00:18:35 +02:00
Родитель 13cc7e6129
Коммит 3025fdd0aa
37 изменённых файлов: 547 добавлений и 312 удалений

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

@ -67,6 +67,11 @@ git = "https://github.com/PLSysSec/lucet_sandbox_compiler"
replace-with = "vendored-sources"
rev = "58498599272e23ef797bb4304d0f181d7455ca57"
[source."https://github.com/NikVolf/tokio-named-pipes"]
branch = "stable"
git = "https://github.com/NikVolf/tokio-named-pipes"
replace-with = "vendored-sources"
[source."https://github.com/ChunMinChang/cubeb-coreaudio-rs"]
git = "https://github.com/ChunMinChang/cubeb-coreaudio-rs"
replace-with = "vendored-sources"

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

@ -92,7 +92,7 @@ dependencies = [
[[package]]
name = "audio_thread_priority"
version = "0.21.0"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -107,7 +107,7 @@ dependencies = [
name = "audioipc"
version = "0.2.4"
dependencies = [
"audio_thread_priority 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"audio_thread_priority 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)",
@ -126,6 +126,7 @@ dependencies = [
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-named-pipes 0.2.0 (git+https://github.com/NikVolf/tokio-named-pipes?branch=stable)",
"tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -134,7 +135,7 @@ dependencies = [
name = "audioipc-client"
version = "0.4.0"
dependencies = [
"audio_thread_priority 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"audio_thread_priority 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)",
"audioipc 0.2.4",
"cubeb-backend 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
@ -147,7 +148,7 @@ dependencies = [
name = "audioipc-server"
version = "0.2.3"
dependencies = [
"audio_thread_priority 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"audio_thread_priority 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)",
"audioipc 0.2.4",
"cubeb-core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1463,7 +1464,7 @@ dependencies = [
name = "gkrust-shared"
version = "0.1.0"
dependencies = [
"audio_thread_priority 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"audio_thread_priority 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)",
"audioipc-client 0.4.0",
"audioipc-server 0.2.3",
"authenticator 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3964,6 +3965,18 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-named-pipes"
version = "0.2.0"
source = "git+https://github.com/NikVolf/tokio-named-pipes?branch=stable#0afa6247222a7aa6e8b370e949a0f4007f0018b6"
dependencies = [
"bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-named-pipes 0.1.6 (git+https://github.com/alexcrichton/mio-named-pipes)",
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-reactor"
version = "0.1.3"
@ -4598,7 +4611,7 @@ dependencies = [
"checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum audio-mixer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cd92208b8b0c2477d1123f9fa898e35d9f7d9340e3f26ddda27bf37a608eff99"
"checksum audio_thread_priority 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8391466145513620b0423a4e2f477686aed475f8e3c992cbfd876ffb33f4120"
"checksum audio_thread_priority 0.20.2 (registry+https://github.com/rust-lang/crates.io-index)" = "197b2d259505d11c92d266e1784f01cc935eb764d2f54e16aedf4e5085197871"
"checksum authenticator 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9b93efb62fd39d28cf78aa7ae459dc312f39c287086ae7a5c379e1bf075a9ad"
"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
@ -4931,6 +4944,7 @@ dependencies = [
"checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab"
"checksum tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5cbe4ca6e71cb0b62a66e4e6f53a8c06a6eefe46cc5f665ad6f274c9906f135"
"checksum tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a5c9635ee806f26d302b8baa1e145689a280d8f5aa8d0552e7344808da54cc21"
"checksum tokio-named-pipes 0.2.0 (git+https://github.com/NikVolf/tokio-named-pipes?branch=stable)" = "<none>"
"checksum tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8703a5762ff6913510dc64272c714c4389ffd8c4b3cf602879b8bd14ff06b604"
"checksum tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4c329b47f071eb8a746040465fa751bd95e4716e98daef6a9b4e434c17d565"
"checksum tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c"

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

@ -36,7 +36,7 @@
# include "mozilla/mscom/EnsureMTA.h"
#endif
#define AUDIOIPC_POOL_SIZE_DEFAULT 1
#define AUDIOIPC_POOL_SIZE_DEFAULT 2
#define AUDIOIPC_STACK_SIZE_DEFAULT (64 * 4096)
#define PREF_VOLUME_SCALE "media.volume_scale"

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

@ -1 +1 @@
# Cubeb Audio Remoting Prototype
# Cubeb Audio Remoting Prototype

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

@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
The audioipc-2 git repository is: https://github.com/djg/audioipc-2.git
The git commit ID used was 86d49ddfca8b016a4b60b0b3fef76052194b8aa3 (2020-01-25 20:43:03 +1300)
The git commit ID used was 8af8083a9a6179bc9fe041c9e5059cea0a0e6fe0 (2019-10-22 14:11:23 +1300)

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

@ -19,7 +19,7 @@ serde = "1.*.*"
serde_derive = "1.*.*"
tokio = "0.1"
tokio-io = "0.1"
audio_thread_priority = "0.21"
audio_thread_priority = "0.20.2"
[target.'cfg(unix)'.dependencies]
iovec = "0.1"
@ -29,9 +29,9 @@ mio-uds = "0.6.7"
tokio-reactor = "0.1"
[target.'cfg(windows)'.dependencies]
mio = "0.6.19"
miow = "0.3.3"
mio-named-pipes = { git = "https://github.com/alexcrichton/mio-named-pipes" }
tokio-named-pipes = { git = "https://github.com/NikVolf/tokio-named-pipes", branch = "stable" }
winapi = { version = "0.3.6", features = ["combaseapi", "objbase"] }
[dependencies.error-chain]

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

@ -5,7 +5,6 @@
use bytes::{BufMut, Bytes, BytesMut};
use libc::{self, cmsghdr};
use std::convert::TryInto;
use std::os::unix::io::RawFd;
use std::{convert, mem, ops, slice};
@ -41,10 +40,12 @@ pub fn iterator(c: Bytes) -> ControlMsgIter {
impl Iterator for ControlMsgIter {
type Item = Fds;
// This follows the logic in __cmsg_nxthdr from glibc
// /usr/include/bits/socket.h
fn next(&mut self) -> Option<Self::Item> {
loop {
let control = self.control.clone();
let cmsghdr_len = len(0);
let cmsghdr_len = align(mem::size_of::<cmsghdr>());
if control.len() < cmsghdr_len {
// No more entries---not enough data in `control` for a
@ -56,14 +57,14 @@ impl Iterator for ControlMsgIter {
// The offset to the next cmsghdr in control. This must be
// aligned to a boundary that matches the type used to
// represent the length of the message.
let cmsg_len = cmsg.cmsg_len as usize;
let cmsg_space = space(cmsg_len - cmsghdr_len);
self.control = if cmsg_space > control.len() {
let cmsg_len = cmsg.cmsg_len;
let next_cmsghdr = align(cmsg_len as _);
self.control = if next_cmsghdr > control.len() {
// No more entries---not enough data in `control` for a
// complete message.
Bytes::new()
} else {
control.slice_from(cmsg_space)
control.slice_from(next_cmsghdr)
};
match (cmsg.cmsg_level, cmsg.cmsg_type) {
@ -99,9 +100,9 @@ pub fn builder(buf: &mut BytesMut) -> ControlMsgBuilder {
impl ControlMsgBuilder {
fn msg(mut self, level: libc::c_int, kind: libc::c_int, msg: &[u8]) -> Self {
self.result = self.result.and_then(|mut cmsg| {
let cmsg_space = space(msg.len());
if cmsg.remaining_mut() < cmsg_space {
self.result = self.result.and_then(align_buf).and_then(|mut cmsg| {
let cmsg_len = len(msg.len());
if cmsg.remaining_mut() < cmsg_len {
return Err(Error::NoSpace);
}
@ -112,19 +113,18 @@ impl ControlMsgBuilder {
let zeroed = unsafe { mem::zeroed() };
#[allow(clippy::needless_update)]
let cmsghdr = cmsghdr {
cmsg_len: len(msg.len()).try_into().unwrap(),
cmsg_len: cmsg_len as _,
cmsg_level: level,
cmsg_type: kind,
..zeroed
};
unsafe {
let cmsghdr_ptr = cmsg.bytes_mut().as_mut_ptr();
std::ptr::copy_nonoverlapping(&cmsghdr as *const _ as *const _, cmsghdr_ptr, mem::size_of::<cmsghdr>());
let cmsg_data_ptr = libc::CMSG_DATA(cmsghdr_ptr as _);
std::ptr::copy_nonoverlapping(msg.as_ptr(), cmsg_data_ptr, msg.len());
cmsg.advance_mut(cmsg_space);
}
let cmsghdr = unsafe {
slice::from_raw_parts(&cmsghdr as *const _ as *const _, mem::size_of::<cmsghdr>())
};
cmsg.put_slice(cmsghdr);
let mut cmsg = align_buf(cmsg)?;
cmsg.put_slice(msg);
Ok(cmsg)
});
@ -141,7 +141,7 @@ impl ControlMsgBuilder {
}
}
trait AsBytes {
pub trait AsBytes {
fn as_bytes(&self) -> &[u8];
}
@ -165,14 +165,28 @@ fn aligned(buf: &BytesMut) -> BytesMut {
aligned_buf
}
fn len(len: usize) -> usize {
unsafe {
libc::CMSG_LEN(len.try_into().unwrap()) as usize
fn align_buf(mut cmsg: BytesMut) -> Result<BytesMut, Error> {
let offset = unsafe { cmsg.bytes_mut().as_ptr() } as usize;
let adjust = align(offset) - offset;
if cmsg.remaining_mut() < adjust {
return Err(Error::NoSpace);
}
for _ in 0..adjust {
cmsg.put_u8(0);
}
Ok(cmsg)
}
fn align(len: usize) -> usize {
let cmsghdr_align = mem::align_of::<cmsghdr>();
(len + cmsghdr_align - 1) & !(cmsghdr_align - 1)
}
pub fn len(len: usize) -> usize {
align(mem::size_of::<cmsghdr>()) + len
}
pub fn space(len: usize) -> usize {
unsafe {
libc::CMSG_SPACE(len.try_into().unwrap()) as usize
}
align(mem::size_of::<cmsghdr>()) + align(len)
}

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

@ -41,9 +41,6 @@ pub mod shm;
#[cfg(unix)]
mod tokio_uds_stream;
#[cfg(windows)]
mod tokio_named_pipes;
pub use crate::messages::{ClientMessage, ServerMessage};
use std::env::temp_dir;
use std::path::PathBuf;
@ -56,8 +53,6 @@ use std::os::unix::io::{FromRawFd, IntoRawFd};
#[cfg(windows)]
use std::os::windows::io::{FromRawHandle, IntoRawHandle};
use std::cell::RefCell;
// This must match the definition of
// ipc::FileDescriptor::PlatformHandleType in Gecko.
#[cfg(windows)]
@ -66,19 +61,11 @@ pub type PlatformHandleType = std::os::windows::raw::HANDLE;
pub type PlatformHandleType = libc::c_int;
// This stands in for RawFd/RawHandle.
#[derive(Clone, Debug)]
pub struct PlatformHandle(RefCell<Inner>);
#[derive(Clone, Debug)]
struct Inner {
handle: PlatformHandleType,
owned: bool,
}
#[derive(Copy, Clone, Debug)]
pub struct PlatformHandle(PlatformHandleType);
unsafe impl Send for PlatformHandle {}
pub const INVALID_HANDLE_VALUE: PlatformHandleType = -1isize as PlatformHandleType;
// Custom serialization to treat HANDLEs as i64. This is not valid in
// general, but after sending the HANDLE value to a remote process we
// use it to create a valid HANDLE via DuplicateHandle.
@ -89,8 +76,7 @@ impl serde::Serialize for PlatformHandle {
where
S: serde::Serializer,
{
let h = self.0.borrow();
serializer.serialize_i64(h.handle as i64)
serializer.serialize_i64(self.0 as i64)
}
}
@ -106,8 +92,7 @@ impl<'de> serde::de::Visitor<'de> for PlatformHandleVisitor {
where
E: serde::de::Error,
{
let owned = cfg!(windows);
Ok(PlatformHandle::new(value as PlatformHandleType, owned))
Ok(PlatformHandle::new(value as PlatformHandleType))
}
}
@ -127,54 +112,49 @@ fn valid_handle(handle: PlatformHandleType) -> bool {
#[cfg(windows)]
fn valid_handle(handle: PlatformHandleType) -> bool {
const INVALID_HANDLE_VALUE: PlatformHandleType = -1isize as PlatformHandleType;
const NULL_HANDLE_VALUE: PlatformHandleType = 0isize as PlatformHandleType;
handle != INVALID_HANDLE_VALUE && handle != NULL_HANDLE_VALUE
}
impl PlatformHandle {
pub fn new(raw: PlatformHandleType, owned: bool) -> PlatformHandle {
assert!(valid_handle(raw));
let inner = Inner {
handle: raw,
owned: owned,
};
PlatformHandle(RefCell::new(inner))
pub fn new(raw: PlatformHandleType) -> PlatformHandle {
PlatformHandle(raw)
}
pub fn try_new(raw: PlatformHandleType) -> Option<PlatformHandle> {
if !valid_handle(raw) {
return None;
}
Some(PlatformHandle::new(raw))
}
#[cfg(windows)]
pub fn from<T: IntoRawHandle>(from: T) -> PlatformHandle {
PlatformHandle::new(from.into_raw_handle(), true)
PlatformHandle::new(from.into_raw_handle())
}
#[cfg(unix)]
pub fn from<T: IntoRawFd>(from: T) -> PlatformHandle {
PlatformHandle::new(from.into_raw_fd(), true)
PlatformHandle::new(from.into_raw_fd())
}
#[cfg(windows)]
pub unsafe fn into_file(&self) -> std::fs::File {
std::fs::File::from_raw_handle(self.into_raw())
pub unsafe fn into_file(self) -> std::fs::File {
std::fs::File::from_raw_handle(self.0)
}
#[cfg(unix)]
pub unsafe fn into_file(&self) -> std::fs::File {
std::fs::File::from_raw_fd(self.into_raw())
pub unsafe fn into_file(self) -> std::fs::File {
std::fs::File::from_raw_fd(self.0)
}
pub unsafe fn into_raw(&self) -> PlatformHandleType {
let mut h = self.0.borrow_mut();
assert!(h.owned);
h.owned = false;
h.handle
pub fn as_raw(self) -> PlatformHandleType {
self.0
}
}
impl Drop for PlatformHandle {
fn drop(&mut self) {
let inner = self.0.borrow();
if inner.owned {
unsafe { close_platformhandle(inner.handle) }
}
pub unsafe fn close(self) {
close_platformhandle(self.0);
}
}

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

@ -292,26 +292,24 @@ impl AssocRawPlatformHandle for ServerMessage {}
impl AssocRawPlatformHandle for ClientMessage {
fn platform_handles(&self) -> Option<([PlatformHandleType; 3], u32)> {
unsafe {
match *self {
ClientMessage::StreamCreated(ref data) => Some((
[
data.platform_handles[0].into_raw(),
data.platform_handles[1].into_raw(),
data.platform_handles[2].into_raw(),
],
data.target_pid,
)),
ClientMessage::ContextSetupDeviceCollectionCallback(ref data) => Some((
[
data.platform_handles[0].into_raw(),
data.platform_handles[1].into_raw(),
data.platform_handles[2].into_raw(),
],
data.target_pid,
)),
_ => None,
}
match *self {
ClientMessage::StreamCreated(ref data) => Some((
[
data.platform_handles[0].as_raw(),
data.platform_handles[1].as_raw(),
data.platform_handles[2].as_raw(),
],
data.target_pid,
)),
ClientMessage::ContextSetupDeviceCollectionCallback(ref data) => Some((
[
data.platform_handles[0].as_raw(),
data.platform_handles[1].as_raw(),
data.platform_handles[2].as_raw(),
],
data.target_pid,
)),
_ => None,
}
}
@ -319,23 +317,22 @@ impl AssocRawPlatformHandle for ClientMessage {
where
F: FnOnce() -> Option<[PlatformHandleType; 3]>,
{
let owned = cfg!(unix);
match *self {
ClientMessage::StreamCreated(ref mut data) => {
let handles =
f().expect("platform_handles must be available when processing StreamCreated");
data.platform_handles = [
PlatformHandle::new(handles[0], owned),
PlatformHandle::new(handles[1], owned),
PlatformHandle::new(handles[2], owned),
PlatformHandle::new(handles[0]),
PlatformHandle::new(handles[1]),
PlatformHandle::new(handles[2]),
]
}
ClientMessage::ContextSetupDeviceCollectionCallback(ref mut data) => {
let handles = f().expect("platform_handles must be available when processing ContextSetupDeviceCollectionCallback");
data.platform_handles = [
PlatformHandle::new(handles[0], owned),
PlatformHandle::new(handles[1], owned),
PlatformHandle::new(handles[2], owned),
PlatformHandle::new(handles[0]),
PlatformHandle::new(handles[1]),
PlatformHandle::new(handles[2]),
]
}
_ => {}

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

@ -39,12 +39,6 @@ impl MessageStream {
}
}
impl IntoRawFd for MessageStream {
fn into_raw_fd(self) -> RawFd {
self.0.into_raw_fd()
}
}
impl AsyncMessageStream {
fn new(stream: tokio_uds::UnixStream) -> AsyncMessageStream {
AsyncMessageStream(stream)
@ -103,3 +97,9 @@ impl AsRawFd for AsyncMessageStream {
self.0.as_raw_fd()
}
}
impl IntoRawFd for MessageStream {
fn into_raw_fd(self) -> RawFd {
self.0.into_raw_fd()
}
}

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

@ -8,7 +8,7 @@ use std::os::windows::fs::*;
use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
use std::sync::atomic::{AtomicUsize, Ordering};
use tokio_io::{AsyncRead, AsyncWrite};
use super::tokio_named_pipes;
use tokio_named_pipes;
use winapi::um::winbase::FILE_FLAG_OVERLAPPED;
#[derive(Debug)]
@ -23,8 +23,8 @@ impl MessageStream {
pub fn anonymous_ipc_pair(
) -> std::result::Result<(MessageStream, MessageStream), std::io::Error> {
let pipe_name = get_pipe_name();
let pipe_server = miow::pipe::NamedPipe::new(&pipe_name)?;
let pipe_client = {
let pipe1 = miow::pipe::NamedPipe::new(&pipe_name)?;
let pipe2 = {
let mut opts = std::fs::OpenOptions::new();
opts.read(true)
.write(true)
@ -32,7 +32,7 @@ impl MessageStream {
let file = opts.open(&pipe_name)?;
unsafe { miow::pipe::NamedPipe::from_raw_handle(file.into_raw_handle()) }
};
Ok((MessageStream::new(pipe_server), MessageStream::new(pipe_client)))
Ok((MessageStream::new(pipe1), MessageStream::new(pipe2)))
}
pub unsafe fn from_raw_fd(raw: super::PlatformHandleType) -> MessageStream {
@ -50,12 +50,6 @@ impl MessageStream {
}
}
impl IntoRawHandle for MessageStream {
fn into_raw_handle(self) -> RawHandle {
self.0.into_raw_handle()
}
}
impl AsyncMessageStream {
fn new(stream: tokio_named_pipes::NamedPipe) -> AsyncMessageStream {
AsyncMessageStream(stream)
@ -99,6 +93,12 @@ impl AsRawHandle for AsyncMessageStream {
}
}
impl IntoRawHandle for MessageStream {
fn into_raw_handle(self) -> RawHandle {
self.0.into_raw_handle()
}
}
static PIPE_ID: AtomicUsize = AtomicUsize::new(0);
fn get_pipe_name() -> String {

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

@ -153,10 +153,3 @@ where
!self.in_flight.is_empty()
}
}
impl<C: Client> Drop for ClientHandler<C> {
fn drop(&mut self) {
let _ = self.transport.close();
self.in_flight.clear();
}
}

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

@ -155,13 +155,6 @@ where
}
}
impl<S: Server> Drop for ServerHandler<S> {
fn drop(&mut self) {
let _ = self.transport.close();
self.in_flight.clear();
}
}
////////////////////////////////////////////////////////////////////////////////
enum InFlight<F: Future<Error = ()>> {

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

@ -9,7 +9,7 @@ description = "Cubeb Backend for talking to remote cubeb server."
edition = "2018"
[dependencies]
audio_thread_priority = "0.21"
audio_thread_priority = "0.20.2"
audioipc = { path="../audioipc" }
cubeb-backend = "0.6.0"
futures = { version="0.1.18", default-features=false, features=["use_std"] }

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

@ -372,7 +372,7 @@ impl ContextOps for ClientContext {
ContextSetupDeviceCollectionCallback())?;
let stream =
unsafe { audioipc::MessageStream::from_raw_fd(fds.platform_handles[0].into_raw()) };
unsafe { audioipc::MessageStream::from_raw_fd(fds.platform_handles[0].as_raw()) };
// TODO: The lowest comms layer expects exactly 3 PlatformHandles, but we only
// need one here. Drop the dummy handles the other side sent us to discard.

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

@ -178,16 +178,19 @@ impl<'ctx> ClientStream<'ctx> {
data.token, data.platform_handles
);
let stream = unsafe { audioipc::MessageStream::from_raw_fd(data.platform_handles[0].into_raw()) };
let stm = data.platform_handles[0];
let stream = unsafe { audioipc::MessageStream::from_raw_fd(stm.as_raw()) };
let input_file = unsafe { data.platform_handles[1].into_file() };
let input = data.platform_handles[1];
let input_file = unsafe { input.into_file() };
let input_shm = if has_input {
Some(SharedMemSlice::from(&input_file, audioipc::SHM_AREA_SIZE).unwrap())
} else {
None
};
let output_file = unsafe { data.platform_handles[2].into_file() };
let output = data.platform_handles[2];
let output_file = unsafe { output.into_file() };
let output_shm = if has_output {
Some(SharedMemMutSlice::from(&output_file, audioipc::SHM_AREA_SIZE).unwrap())
} else {

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

@ -9,7 +9,7 @@ description = "Remote cubeb server"
edition = "2018"
[dependencies]
audio_thread_priority = "0.21"
audio_thread_priority = "0.20.2"
audioipc = { path = "../audioipc" }
cubeb-core = "0.6.0"
futures = "0.1.18"

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

@ -124,7 +124,7 @@ pub extern "C" fn audioipc_server_new_client(p: *mut c_void) -> PlatformHandleTy
// is registered with the reactor core, the other side is returned
// to the caller.
MessageStream::anonymous_ipc_pair()
.and_then(|(ipc_server, ipc_client)| {
.and_then(|(sock1, sock2)| {
// Spawn closure to run on same thread as reactor::Core
// via remote handle.
wrapper
@ -133,22 +133,22 @@ pub extern "C" fn audioipc_server_new_client(p: *mut c_void) -> PlatformHandleTy
.spawn(futures::future::lazy(|| {
trace!("Incoming connection");
let handle = reactor::Handle::default();
ipc_server.into_tokio_ipc(&handle)
sock2.into_tokio_ipc(&handle)
.and_then(|sock| {
let transport = framed_with_platformhandles(sock, Default::default());
rpc::bind_server(transport, server::CubebServer::new(core_handle));
Ok(())
}).map_err(|_| ())
// Notify waiting thread that server has been registered.
// Notify waiting thread that sock2 has been registered.
.and_then(|_| wait_tx.send(()))
}))
.expect("Failed to spawn CubebServer");
// Wait for notification that server has been registered
// Wait for notification that sock2 has been registered
// with reactor::Core.
let _ = wait_rx.wait();
Ok(unsafe { PlatformHandle::from(ipc_client).into_raw() })
Ok(PlatformHandle::from(sock1).as_raw())
})
.unwrap_or(audioipc::INVALID_HANDLE_VALUE)
.unwrap_or(-1isize as PlatformHandleType)
}
#[no_mangle]

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

@ -465,8 +465,8 @@ impl CubebServer {
.unwrap_or_else(error),
ServerMessage::ContextSetupDeviceCollectionCallback => {
if let Ok((ipc_server, ipc_client)) = MessageStream::anonymous_ipc_pair() {
debug!("Created device collection RPC pair: {:?}-{:?}", ipc_server, ipc_client);
if let Ok((stm1, stm2)) = MessageStream::anonymous_ipc_pair() {
debug!("Created device collection RPC pair: {:?}-{:?}", stm1, stm2);
// This code is currently running on the Client/Server RPC
// handling thread. We need to move the registration of the
@ -477,7 +477,7 @@ impl CubebServer {
self.handle
.spawn(futures::future::lazy(move || {
let handle = reactor::Handle::default();
let stream = ipc_server.into_tokio_ipc(&handle).unwrap();
let stream = stm2.into_tokio_ipc(&handle).unwrap();
let transport = framed(stream, Default::default());
let rpc = rpc::bind_client::<DeviceCollectionClient>(transport);
drop(tx.send(rpc));
@ -496,7 +496,7 @@ impl CubebServer {
})));
let fds = RegisterDeviceCollectionChanged {
platform_handles: [
PlatformHandle::from(ipc_client),
PlatformHandle::from(stm1),
PlatformHandle::from(dummy1),
PlatformHandle::from(dummy2),
],
@ -595,8 +595,8 @@ impl CubebServer {
let input_frame_size = frame_size_in_bytes(params.input_stream_params.as_ref());
let output_frame_size = frame_size_in_bytes(params.output_stream_params.as_ref());
let (ipc_server, ipc_client) = MessageStream::anonymous_ipc_pair()?;
debug!("Created callback pair: {:?}-{:?}", ipc_server, ipc_client);
let (stm1, stm2) = MessageStream::anonymous_ipc_pair()?;
debug!("Created callback pair: {:?}-{:?}", stm1, stm2);
let mut shm_path = audioipc::get_shm_path();
shm_path.set_extension("input");
let (input_shm, input_file) = SharedMemWriter::new(&shm_path, audioipc::SHM_AREA_SIZE)?;
@ -612,7 +612,7 @@ impl CubebServer {
self.handle
.spawn(futures::future::lazy(move || {
let handle = reactor::Handle::default();
let stream = ipc_server.into_tokio_ipc(&handle).unwrap();
let stream = stm2.into_tokio_ipc(&handle).unwrap();
let transport = framed(stream, Default::default());
let rpc = rpc::bind_client::<CallbackClient>(transport);
drop(tx.send(rpc));
@ -687,7 +687,7 @@ impl CubebServer {
Ok(ClientMessage::StreamCreated(StreamCreate {
token: key,
platform_handles: [
PlatformHandle::from(ipc_client),
PlatformHandle::from(stm1),
PlatformHandle::from(input_file),
PlatformHandle::from(output_file),
],

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

@ -5,13 +5,13 @@ cp -p $1/README.md .
cp -p $1/Cargo.toml .
for crate in audioipc client server; do
rm -fr $crate
mkdir $crate
cp -pr $1/$crate/Cargo.toml $crate
cp -pr $1/$crate/src $crate
test -d $crate/src || mkdir -p $crate/src
rm -fr $crate/*
cp -pr $1/$crate/Cargo.toml $crate/
cp -pr $1/$crate/src/ $crate/src/
done
rm -f audioipc/src/cmsghdr.c
rm audioipc/src/cmsghdr.c
if [ -d $1/.git ]; then
rev=$(cd $1 && git rev-parse --verify HEAD)
@ -26,7 +26,7 @@ if [ -n "$rev" ]; then
echo "WARNING: updating from a dirty git repository."
fi
sed -i.bak -e "/The git commit ID used was/ s/[0-9a-f]\{40\}\(-dirty\)\{0,1\} .\{1,100\}/$version ($date)/" README_MOZILLA
rm -f README_MOZILLA.bak
rm README_MOZILLA.bak
else
echo "Remember to update README_MOZILLA with the version details."
fi

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

@ -5877,8 +5877,6 @@
mirror: always
#if defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID)
value: true
#elif defined(XP_WIN) && !defined(_ARM64_)
value: @IS_NIGHTLY_BUILD@
#else
value: false
#endif

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

@ -569,6 +569,13 @@ pref("media.video-queue.send-to-compositor-size", 9999);
// "verbose", "normal" and "" (log disabled).
pref("media.cubeb.logging_level", "");
// Cubeb sandbox (remoting) control
#if defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID)
pref("media.audioipc.pool_size", 1);
// 64 * 4 kB stack per pool thread.
pref("media.audioipc.stack_size", 262144);
#endif
#if defined(XP_MACOSX)
pref("media.cubeb.backend", "audiounit-rust");
#endif

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

@ -1 +1 @@
{"files":{"Cargo.toml":"37f3e58612d632aa6fe4a2a2330317921f7a090faa071660e4665f3be63c96c0","Makefile":"0f9a771cfb30c7c4b9961d82fdca4e9e229a955bb2e636474a4101389e18e938","README.md":"bcfa4948edf52fdacd485200a0c1c886a92232cc1931eeb4e1044050f46ec253","atp_test.cpp":"8075a040941a65fb9e3f7cbf0535853ca6661c3ac442ec35569b42b24bbec797","audio_thread_priority.h":"f0ecaf1b674f794cde0dc834028e074d4e4675d22ae96acf08b2ae1dceb3474e","generate_osx_bindings.sh":"06e4e03450f788ced18d31fff5660919e6f6ec1119ddace363ffeb82f0518a71","src/lib.rs":"6103fbdd7b27b5680c8f70a1413a9bf707eee28b8e0717268ecaab4b2e4ef148","src/mach_sys.rs":"352560fcb9b41d877cff92e5b3b04d6dc68b1f30508ce4b9aed78940120a883e","src/rt_linux.rs":"d68a064bbe6617b9a277c55abc308510e4f719a74ebe2e2206e990ae6ba87149","src/rt_mach.rs":"3f864805297b1172ed39b0ffe8888d21ec51cdc6183b31273f3f915473e31234","src/rt_win.rs":"3aabdcf6db810e23086c8710f55027f322e721b43a28dc7c544ca32a6d7964a5"},"package":"e8391466145513620b0423a4e2f477686aed475f8e3c992cbfd876ffb33f4120"}
{"files":{"Cargo.toml":"363ab43ea4980149350eb3a4da691a93f0b7c61a5d3b4ce8b59f73cde5866a92","Makefile":"0f9a771cfb30c7c4b9961d82fdca4e9e229a955bb2e636474a4101389e18e938","README.md":"bcfa4948edf52fdacd485200a0c1c886a92232cc1931eeb4e1044050f46ec253","atp_test.cpp":"8075a040941a65fb9e3f7cbf0535853ca6661c3ac442ec35569b42b24bbec797","audio_thread_priority.h":"f0ecaf1b674f794cde0dc834028e074d4e4675d22ae96acf08b2ae1dceb3474e","generate_osx_bindings.sh":"06e4e03450f788ced18d31fff5660919e6f6ec1119ddace363ffeb82f0518a71","src/lib.rs":"516388cf4ccf55f23a6ccb248f56ab525b759a24819e67605cd12f640517ddd3","src/mach_sys.rs":"352560fcb9b41d877cff92e5b3b04d6dc68b1f30508ce4b9aed78940120a883e","src/rt_linux.rs":"b4db36baa754ab166b40f3801acc4f2046d226a2645f0e136dbbfa1bc771344e","src/rt_mach.rs":"5fce324b9a64305ff221fdd185eaa4b1c7386b6e61edc32cf63e424f9f3d90ef","src/rt_win.rs":"f8f5b7af21cadd686cf7d8099d1972d3265c3889574020bd4ea088b832fbfa51"},"package":"197b2d259505d11c92d266e1784f01cc935eb764d2f54e16aedf4e5085197871"}

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

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "audio_thread_priority"
version = "0.21.0"
version = "0.20.2"
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"

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

@ -3,50 +3,14 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#[warn(missing_docs)]
use cfg_if::cfg_if;
use std::error::Error;
use std::fmt;
#[derive(Debug)]
pub struct AudioThreadPriorityError {
message: String,
inner: Option<Box<dyn Error + 'static>>,
}
#[macro_use]
extern crate cfg_if;
#[cfg(feature = "terminal-logging")]
extern crate simple_logger;
#[macro_use]
extern crate log;
impl AudioThreadPriorityError {
fn new_with_inner(message: &str, inner: Box<dyn Error>) -> AudioThreadPriorityError {
AudioThreadPriorityError {
message: message.into(),
inner: Some(inner),
}
}
fn new(message: &str) -> AudioThreadPriorityError {
AudioThreadPriorityError {
message: message.into(),
inner: None,
}
}
}
impl fmt::Display for AudioThreadPriorityError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut rv = write!(f, "AudioThreadPriorityError: {}", &self.message);
if let Some(inner) = &self.inner {
rv = write!(f, " ({})", inner);
}
rv
}
}
impl Error for AudioThreadPriorityError {
fn description(&self) -> &str {
&self.message
}
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.inner.as_ref().map(|e| e.as_ref())
}
}
cfg_if! {
if #[cfg(target_os = "macos")] {
@ -82,14 +46,14 @@ cfg_if! {
} else {
// blanket implementations for Android and other systems.
pub struct RtPriorityHandleInternal {}
pub fn promote_current_thread_to_real_time_internal(_: u32, audio_samplerate_hz: u32) -> Result<RtPriorityHandle, AudioThreadPriorityError> {
pub fn promote_current_thread_to_real_time_internal(_: u32, audio_samplerate_hz: u32) -> Result<RtPriorityHandle, ()> {
if audio_samplerate_hz == 0 {
return Err(AudioThreadPriorityError("sample rate is zero"));
return Err(());
}
// no-op
Ok(RtPriorityHandle{})
}
pub fn demote_current_thread_from_real_time_internal(_: RtPriorityHandle) -> Result<(), AudioThreadPriorityError> {
pub fn demote_current_thread_from_real_time_internal(_: RtPriorityHandle) -> Result<(), ()> {
// no-op
Ok(())
}
@ -120,7 +84,7 @@ pub type RtPriorityThreadInfo = RtPriorityThreadInfoInternal;
///
/// Ok in case of success, with an opaque structure containing relevant info for the platform, Err
/// otherwise.
pub fn get_current_thread_info() -> Result<RtPriorityThreadInfo, AudioThreadPriorityError> {
pub fn get_current_thread_info() -> Result<RtPriorityThreadInfo, ()> {
return get_current_thread_info_internal();
}
@ -246,9 +210,9 @@ pub fn promote_thread_to_real_time(
thread_info: RtPriorityThreadInfo,
audio_buffer_frames: u32,
audio_samplerate_hz: u32,
) -> Result<RtPriorityHandle, AudioThreadPriorityError> {
) -> Result<RtPriorityHandle, ()> {
if audio_samplerate_hz == 0 {
return Err(AudioThreadPriorityError::new("sample rate is zero"));
return Err(());
}
return promote_thread_to_real_time_internal(
thread_info,
@ -267,7 +231,7 @@ pub fn promote_thread_to_real_time(
/// # Return value
///
/// `Ok` in case of success, `Err` otherwise.
pub fn demote_thread_from_real_time(thread_info: RtPriorityThreadInfo) -> Result<(), AudioThreadPriorityError> {
pub fn demote_thread_from_real_time(thread_info: RtPriorityThreadInfo) -> Result<(), ()> {
return demote_thread_from_real_time_internal(thread_info);
}
@ -365,9 +329,9 @@ pub extern "C" fn atp_set_real_time_limit(audio_buffer_frames: u32,
pub fn promote_current_thread_to_real_time(
audio_buffer_frames: u32,
audio_samplerate_hz: u32,
) -> Result<RtPriorityHandle, AudioThreadPriorityError> {
) -> Result<RtPriorityHandle, ()> {
if audio_samplerate_hz == 0 {
return Err(AudioThreadPriorityError::new("sample rate is zero"));
return Err(());
}
return promote_current_thread_to_real_time_internal(audio_buffer_frames, audio_samplerate_hz);
}
@ -382,9 +346,7 @@ pub fn promote_current_thread_to_real_time(
/// # Return value
///
/// `Ok` in scase of success, `Err` otherwise.
pub fn demote_current_thread_from_real_time(
handle: RtPriorityHandle,
) -> Result<(), AudioThreadPriorityError> {
pub fn demote_current_thread_from_real_time(handle: RtPriorityHandle) -> Result<(), ()> {
return demote_current_thread_from_real_time_internal(handle);
}
@ -480,11 +442,9 @@ mod tests {
match promote_current_thread_to_real_time(0, 44100) {
Ok(rt_prio_handle) => {
demote_current_thread_from_real_time(rt_prio_handle).unwrap();
assert!(true);
}
Err(e) => {
eprintln!("{}", e.description());
assert!(false);
panic!(e);
}
}
}
@ -492,22 +452,17 @@ mod tests {
match promote_current_thread_to_real_time(512, 44100) {
Ok(rt_prio_handle) => {
demote_current_thread_from_real_time(rt_prio_handle).unwrap();
assert!(true);
}
Err(e) => {
eprintln!("{}", e.description());
assert!(false);
panic!(e);
}
}
}
{
match promote_current_thread_to_real_time(512, 44100) {
Ok(_) => {
assert!(true);
}
Ok(_) => {}
Err(e) => {
eprintln!("{}", e.description());
assert!(false);
panic!(e);
}
}
// automatically deallocated, but not demoted until the thread exits.
@ -524,11 +479,9 @@ mod tests {
let info = get_current_thread_info().unwrap();
match promote_thread_to_real_time(info, 512, 44100) {
Ok(_) => {
assert!(true);
}
Err(e) => {
eprintln!("{}", e);
assert!(false);
panic!(e);
}
}
}
@ -563,7 +516,6 @@ mod tests {
}
Err(_) => {
eprintln!("promotion Err");
kill(child, SIGKILL).expect("Could not kill the child?");
assert!(false);
}
}
@ -585,7 +537,7 @@ mod tests {
match write(wr, &bytes) {
Ok(_) => {
loop {
std::thread::sleep(std::time::Duration::from_millis(1000));
std::thread::sleep(std::time::Duration::from_millis(100));
eprintln!("child sleeping, waiting to be promoted...");
}
}

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

@ -13,26 +13,12 @@ use std::io::Error as OSError;
use dbus::{Connection, BusType, Props, MessageItem, Message};
use crate::AudioThreadPriorityError;
const DBUS_SOCKET_TIMEOUT: i32 = 10_000;
const RT_PRIO_DEFAULT: u32 = 10;
// This is different from libc::pid_t, which is 32 bits, and is defined in sys/types.h.
#[allow(non_camel_case_types)]
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()))
}
}
impl From<Box<dyn Error>> for AudioThreadPriorityError {
fn from(error: Box<dyn Error>) -> Self {
AudioThreadPriorityError::new(&format!("{}", error.description()))
}
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct RtPriorityThreadInfoInternal {
@ -45,7 +31,9 @@ pub struct RtPriorityThreadInfoInternal {
/// process.
pthread_id: libc::pthread_t,
/// ...
policy: libc::c_int
policy: libc::c_int,
/// ...
param: libc::sched_param,
}
impl RtPriorityThreadInfoInternal {
@ -71,11 +59,11 @@ pub struct RtPriorityHandleInternal {
thread_info: RtPriorityThreadInfoInternal,
}
fn item_as_i64(i: MessageItem) -> Result<i64, AudioThreadPriorityError> {
fn item_as_i64(i: MessageItem) -> Result<i64, Box<dyn Error>> {
match i {
MessageItem::Int32(i) => Ok(i as i64),
MessageItem::Int64(i) => Ok(i),
_ => Err(AudioThreadPriorityError::new(&format!("Property is not integer ({:?})", i)))
_ => Err(Box::from(&*format!("Property is not integer ({:?})", i)))
}
}
@ -102,7 +90,7 @@ fn rtkit_set_realtime(thread: u64, pid: u64, prio: u32) -> Result<(), Box<dyn Er
/// Returns the maximum priority, maximum real-time time slice, and the current real-time time
/// slice for this process.
fn get_limits() -> Result<(i64, u64, libc::rlimit64), AudioThreadPriorityError> {
fn get_limits() -> Result<(i64, u64, libc::rlimit64), Box<dyn Error>> {
let c = Connection::get_private(BusType::System)?;
let p = Props::new(&c, "org.freedesktop.RealtimeKit1", "/org/freedesktop/RealtimeKit1",
@ -114,28 +102,29 @@ fn get_limits() -> Result<(i64, u64, libc::rlimit64), AudioThreadPriorityError>
let max_prio = item_as_i64(p.get("MaxRealtimePriority")?)?;
if max_prio < 0 {
return Err(AudioThreadPriorityError::new("invalid negative MaxRealtimePriority"));
return Err(Box::from("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(Box::from("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())));
error!("getrlimit64: {}", OSError::last_os_error().raw_os_error().unwrap());
return Err(Box::from("getrlimit failed"));
}
Ok((max_prio, (max_rttime as u64), current_limit))
}
fn set_limits(request: u64, max: u64) -> Result<(), AudioThreadPriorityError> {
fn set_limits(request: u64, max: u64) -> Result<(), Box<dyn Error>> {
// 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 };
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(Box::from("setrlimit failed"));
}
Ok(())
@ -143,28 +132,27 @@ fn set_limits(request: u64, max: u64) -> Result<(), AudioThreadPriorityError> {
pub fn promote_current_thread_to_real_time_internal(audio_buffer_frames: u32,
audio_samplerate_hz: u32)
-> Result<RtPriorityHandleInternal, AudioThreadPriorityError> {
-> Result<RtPriorityHandleInternal, ()> {
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> {
-> Result<(), ()> {
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())));
&rt_priority_handle.thread_info.param) } < 0 {
error!("could not demote thread {}", OSError::last_os_error().raw_os_error().unwrap());
return Err(());
}
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> {
-> Result<(), ()> {
let param = unsafe { std::mem::zeroed::<libc::sched_param>() };
// https://github.com/rust-lang/libc/issues/1511
@ -173,7 +161,8 @@ pub fn demote_thread_from_real_time_internal(thread_info: RtPriorityThreadInfoIn
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())));
error!("could not demote thread {}", OSError::last_os_error().raw_os_error().unwrap());
return Err(());
}
return Ok(());
}
@ -181,14 +170,15 @@ 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, ()> {
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())));
error!("pthread_getschedparam error {}", OSError::last_os_error().raw_os_error().unwrap());
return Err(());
}
let pid = unsafe { libc::getpid() };
@ -197,7 +187,8 @@ pub fn get_current_thread_info_internal() -> Result<RtPriorityThreadInfoInternal
pid,
thread_id,
pthread_id,
policy
policy,
param
})
}
@ -206,7 +197,7 @@ pub fn get_current_thread_info_internal() -> Result<RtPriorityThreadInfoInternal
/// 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> {
audio_samplerate_hz: u32) -> Result<(), ()> {
let buffer_frames = if audio_buffer_frames > 0 {
audio_buffer_frames
} else {
@ -217,11 +208,11 @@ pub fn set_real_time_hard_limit_internal(audio_buffer_frames: u32,
// It's only necessary to set RLIMIT_RTTIME to something when in the child, skip it if it's a
// remoting call.
let (_, max_rttime, _) = get_limits()?;
let (_, max_rttime, _) = get_limits().map_err(|_| {})?;
// Only take what we need, or cap at the system limit, no further.
let rttime_request = cmp::min(budget_us, max_rttime as u64);
set_limits(rttime_request, max_rttime)?;
set_limits(rttime_request, max_rttime).map_err(|_| {})?;
Ok(())
}
@ -229,27 +220,23 @@ 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>
audio_samplerate_hz: u32) -> Result<RtPriorityHandleInternal, ()>
{
let RtPriorityThreadInfoInternal { pid, thread_id, .. } = thread_info;
let handle = RtPriorityHandleInternal { thread_info };
let (_, _, limits) = get_limits()?;
let (_, _, limits) = get_limits().map_err(|_| {})?;
set_real_time_hard_limit_internal(audio_buffer_frames, audio_samplerate_hz)?;
let r = rtkit_set_realtime(thread_id as u64, pid as u64, RT_PRIO_DEFAULT);
match r {
Ok(_) => {
return Ok(handle);
if r.is_err() {
if unsafe { libc::setrlimit64(libc::RLIMIT_RTTIME, &limits) } < 0 {
error!("setrlimit64: {}", OSError::last_os_error().raw_os_error().unwrap());
return Err(());
}
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(&"Thread promotion error", e));
}
}
return Ok(handle);
}

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

@ -9,8 +9,6 @@ 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 log::info;
extern "C" {
fn pthread_mach_thread_np(tid: pthread_t) -> mach_port_t;
@ -56,7 +54,7 @@ impl RtPriorityHandleInternal {
}
pub fn demote_current_thread_from_real_time_internal(rt_priority_handle: RtPriorityHandleInternal)
-> Result<(), AudioThreadPriorityError> {
-> Result<(), ()> {
unsafe {
let rv: kern_return_t;
let mut h = rt_priority_handle;
@ -66,10 +64,11 @@ pub fn demote_current_thread_from_real_time_internal(rt_priority_handle: RtPrior
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"));
warn!("thread demotion error: thread_policy_set: RT");
return Err(());
}
info!("thread {} priority restored.", h.tid);
warn!("thread {} priority restored.", h.tid);
}
return Ok(());
@ -77,7 +76,7 @@ pub fn demote_current_thread_from_real_time_internal(rt_priority_handle: RtPrior
pub fn promote_current_thread_to_real_time_internal(audio_buffer_frames: u32,
audio_samplerate_hz: u32)
-> Result<RtPriorityHandleInternal, AudioThreadPriorityError> {
-> Result<RtPriorityHandleInternal, ()> {
let mut rt_priority_handle = RtPriorityHandleInternal::new();
@ -114,7 +113,8 @@ pub fn promote_current_thread_to_real_time_internal(audio_buffer_frames: u32,
&mut get_default);
if rv != KERN_SUCCESS as i32 {
return Err(AudioThreadPriorityError::new("thread promotion error: thread_policy_get: time_constraint"));
error!("thread promotion error: thread_policy_get: time_constraint");
return Err(());
}
rt_priority_handle.previous_time_constraint_policy = time_constraints;
@ -139,7 +139,8 @@ pub fn promote_current_thread_to_real_time_internal(audio_buffer_frames: u32,
(&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"));
warn!("thread promotion error: thread_policy_set: time_constraint");
return Err(());
}
info!("thread {} bumped to real time priority.", tid);

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

@ -7,10 +7,6 @@ use winapi::shared::ntdef::HANDLE;
use winapi::shared::minwindef::DWORD;
use winapi::um::errhandlingapi::GetLastError;
use crate::AudioThreadPriorityError;
use log::info;
#[derive(Debug)]
pub struct RtPriorityHandleInternal {
mmcss_task_index: DWORD,
@ -27,11 +23,12 @@ impl RtPriorityHandleInternal {
}
pub fn demote_current_thread_from_real_time_internal(rt_priority_handle: RtPriorityHandleInternal)
-> Result<(), AudioThreadPriorityError> {
-> Result<(), ()> {
unsafe {
let rv = AvRevertMmThreadCharacteristics(rt_priority_handle.task_handle);
if rv == 0 {
return Err(AudioThreadPriorityError::new(&format!("Unable to restore the thread priority ({})", GetLastError())));
warn!("Unable to restore the thread priority ({})", GetLastError());
return Err(())
}
}
@ -42,14 +39,15 @@ pub fn demote_current_thread_from_real_time_internal(rt_priority_handle: RtPrior
pub fn promote_current_thread_to_real_time_internal(_audio_buffer_frames: u32,
_audio_samplerate_hz: u32)
-> Result<RtPriorityHandleInternal, AudioThreadPriorityError> {
-> Result<RtPriorityHandleInternal, ()> {
let mut handle = RtPriorityHandleInternal::new();
unsafe {
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())));
warn!("Unable to use mmcss to bump the thread priority ({})", GetLastError());
return Err(())
}
}

1
third_party/rust/tokio-named-pipes/.cargo-checksum.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"files":{"Cargo.toml":"1e278b68a4af7dc6212bf86cf8fa94a52ce1e3b318eb5d086053e614cc1e6dbd","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"030621290d10cb2eec6393f553117a1b4245d024efe159eac70c4b57dc121e79","appveyor.yml":"87f3eab680a0ab6a891f8cf109a355d0ce3f4d8bee4728c2e3d45596677ade82","src/lib.rs":"06e5e32338ef81ef6fe1a7efd12a90419463e5b6c54fe179a076dc629eb43e0d"},"package":null}

19
third_party/rust/tokio-named-pipes/Cargo.toml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,19 @@
[package]
name = "tokio-named-pipes"
version = "0.2.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
license = "MIT/Apache-2.0"
readme = "README.md"
repository = "https://github.com/alexcrichton/tokio-named-pipes"
homepage = "https://github.com/alexcrichton/tokio-named-pipes"
documentation = "http://alexcrichton.com/tokio-named-pipes"
description = """
Windows named pipe bindings for tokio.
"""
[dependencies]
mio = "0.6"
tokio = "0.1"
mio-named-pipes = { git = "https://github.com/alexcrichton/mio-named-pipes" }
futures = "0.1"
bytes = "0.4"

201
third_party/rust/tokio-named-pipes/LICENSE-APACHE поставляемый Normal file
Просмотреть файл

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
third_party/rust/tokio-named-pipes/LICENSE-MIT поставляемый Normal file
Просмотреть файл

@ -0,0 +1,25 @@
Copyright (c) 2014 Alex Crichton
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

31
third_party/rust/tokio-named-pipes/README.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,31 @@
# tokio-named-pipes
[![Build status](https://ci.appveyor.com/api/projects/status/motwon3ro35xwb2x?svg=true)](https://ci.appveyor.com/project/NikolayVolf/tokio-named-pipes)
[Documentation](http://alexcrichton.com/tokio-named-pipes)
A library for integrating Windows [Named Pipes] with [tokio].
[Named Pipes]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365590(v=vs.85).aspx
[tokio]: https://github.com/tokio-rs/tokio
```toml
# Cargo.toml
[dependencies]
tokio-named-pipes = { git = "https://github.com/NikVolf/tokio-named-pipes", branch = "stable" }
```
Next, add this to your crate:
```rust
extern crate tokio_named_pipes;
```
# License
`tokio-named-pipes` is primarily distributed under the terms of both the MIT
license and the Apache License (Version 2.0), with portions covered by various
BSD-like licenses.
See LICENSE-APACHE, and LICENSE-MIT for details.

16
third_party/rust/tokio-named-pipes/appveyor.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,16 @@
environment:
matrix:
- TARGET: x86_64-pc-windows-msvc
install:
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
- rustup-init.exe -y --default-host %TARGET%
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin;C:\MinGW\bin
- rustc -vV
- cargo -vV
build: false
test_script:
- cargo test

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

@ -1,9 +1,11 @@
// Copied from tokio-named-pipes/src/lib.rs revision 49ec1ba8bbc94ab6fc9636af2a00dfb3204080c8 (tokio-named-pipes 0.2.0)
// This file is dual licensed under the MIT and Apache-2.0 per upstream: https://github.com/NikVolf/tokio-named-pipes/blob/stable/LICENSE-MIT and https://github.com/NikVolf/tokio-named-pipes/blob/stable/LICENSE-APACHE
// - Implement AsyncWrite::shutdown
#![cfg(windows)]
extern crate tokio;
extern crate bytes;
extern crate mio;
extern crate mio_named_pipes;
extern crate futures;
use std::ffi::OsStr;
use std::fmt;
use std::io::{Read, Write};
@ -25,7 +27,7 @@ impl NamedPipe {
}
fn _new(p: &OsStr, handle: &Handle) -> std::io::Result<NamedPipe> {
let inner = mio_named_pipes::NamedPipe::new(p)?;
let inner = try!(mio_named_pipes::NamedPipe::new(p));
NamedPipe::from_pipe(inner, handle)
}
@ -101,7 +103,7 @@ impl AsyncRead for NamedPipe {
let mut stack_buf = [0u8; 1024];
let bytes_read = self.io_mut().read(&mut stack_buf);
match bytes_read {
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
self.io_mut().clear_read_ready(Ready::readable())?;
return Ok(Async::NotReady);
},
@ -116,8 +118,7 @@ impl AsyncRead for NamedPipe {
impl AsyncWrite for NamedPipe {
fn shutdown(&mut self) -> Poll<(), std::io::Error> {
let _ = self.disconnect();
Ok(().into())
Ok(().into())
}
fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, std::io::Error> {
@ -127,7 +128,7 @@ impl AsyncWrite for NamedPipe {
let bytes_wrt = self.io_mut().write(buf.bytes());
match bytes_wrt {
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
self.io_mut().clear_write_ready()?;
return Ok(Async::NotReady);
},

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

@ -1,7 +1,6 @@
[DEFAULT]
prefs =
plugin.load_flash_only=false
media.cubeb.sandbox=false # BMO 1610640
support-files =
almostSilentAudioTrack.webm
audio.ogg

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

@ -40,7 +40,7 @@ storage = { path = "../../../../storage/rust" }
bookmark_sync = { path = "../../../components/places/bookmark_sync", optional = true }
shift_or_euc_c = "0.1.0"
chardetng_c = "0.1.1"
audio_thread_priority = "0.21"
audio_thread_priority = "0.20.2"
mdns_service = { path="../../../../media/mtransport/mdns_service", optional = true }
neqo_glue = { path = "../../../../netwerk/socket/neqo_glue" }
rlbox_lucet_sandbox = { version = "0.1.0", optional = true }