Skip to content

Commit

Permalink
Bug 1710095 - Update audioipc to 7537bfad for memmap -> memmap2 trans…
Browse files Browse the repository at this point in the history
…ition. r=chunmin,cubeb-reviewers,padenot

Differential Revision: https://phabricator.services.mozilla.com/D114665
  • Loading branch information
kinetiknz committed May 10, 2021
1 parent 19b3cf4 commit a455211
Show file tree
Hide file tree
Showing 34 changed files with 740 additions and 91 deletions.
7 changes: 6 additions & 1 deletion .cargo/config.in
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ rev = "ad56ea14ac915f1e7ecbcf6ac38182443b0dd29e"
[source."https://github.com/mozilla/audioipc-2"]
git = "https://github.com/mozilla/audioipc-2"
replace-with = "vendored-sources"
rev = "8fb5ff19fba7b09e8e66598122421e68a5c573ac"
rev = "7537bfadad2e981577eb75e4f13662fc517e1a09"

[source."https://github.com/mozilla/application-services"]
git = "https://github.com/mozilla/application-services"
Expand All @@ -62,6 +62,11 @@ git = "https://github.com/kinetiknz/mio-named-pipes"
replace-with = "vendored-sources"
rev = "21c26326f5f45f415c49eac4ba5bc41a2f961321"

[source."https://github.com/kinetiknz/ashmem-rs"]
git = "https://github.com/kinetiknz/ashmem-rs"
replace-with = "vendored-sources"
rev = "e47f470a54193532d60057ec54f864e06aeaff36"

[source."https://github.com/jfkthame/mapped_hyph.git"]
git = "https://github.com/jfkthame/mapped_hyph.git"
replace-with = "vendored-sources"
Expand Down
24 changes: 20 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions third_party/rust/ashmem/.cargo-checksum.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"files":{"Cargo.toml":"90a69817003711b9f60ce9c907c8bd35b52aafafd074aecf4e66b1fa6e1c716f","src/lib.rs":"0024c010b7618e4e25bb6ea3295f229a0e4bf2ecd7144c764de3f175ad839ce5"},"package":null}
10 changes: 10 additions & 0 deletions third_party/rust/ashmem/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "ashmem"
version = "0.1.0"
authors = ["Matthew Gregan <[email protected]>"]
edition = "2018"
license = "ISC"

[dependencies]
libc = "0.2"
ioctl-sys = "0.7"
160 changes: 160 additions & 0 deletions third_party/rust/ashmem/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#![cfg(target_os = "android")]
//! Provides a wrapper around Android's ASharedMemory API.
//!
//! ashmem has existed in Android as a non-public API for some time.
//! Originally accessed via ioctl, it was later available via libcutils as ashmem_create_region etc.
//! ASharedMemory is the new public API, but it isn't available until API 26 (Android 8).
//! Builds targeting Android 10 (API 29) are no longer permitted to access ashmem via the ioctl interface.
//! This makes life for a portable program difficult - you can't reliably use the old or new interface during this transition period.
//! We try to dynamically load the new API first, then fall back to the ioctl interface.
//!
//! References:
//! - [ASharedMemory documentation](https://developer.android.com/ndk/reference/group/memory)
//! - [Linux ashmem.h definitions](https://elixir.bootlin.com/linux/v5.11.8/source/drivers/staging/android/uapi/ashmem.h)
#[macro_use]
extern crate ioctl_sys;

const __ASHMEMIOC: u32 = 0x77;

static mut LIBANDROID_ASHAREDMEMORY_CREATE: Option<
extern "C" fn(*const libc::c_char, libc::size_t) -> libc::c_int,
> = None;
static mut LIBANDROID_ASHAREDMEMORY_GETSIZE: Option<extern "C" fn(libc::c_int) -> libc::size_t> =
None;
static mut LIBANDROID_ASHAREDMEMORY_SETPROT: Option<
extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int,
> = None;

unsafe fn maybe_init() {
const LIBANDROID_NAME: *const libc::c_char = "libandroid\0".as_ptr() as *const libc::c_char;
const LIBANDROID_ASHAREDMEMORY_CREATE_NAME: *const libc::c_char =
"ASharedMemory_create\0".as_ptr() as _;
const LIBANDROID_ASHAREDMEMORY_GETSIZE_NAME: *const libc::c_char =
"ASharedMemory_getSize\0".as_ptr() as _;
const LIBANDROID_ASHAREDMEMORY_SETPROT_NAME: *const libc::c_char =
"ASharedMemory_setProt\0".as_ptr() as _;
static ONCE: std::sync::Once = std::sync::Once::new();
ONCE.call_once(|| {
// Leak the handle, there's no safe time to close it.
let handle = libc::dlopen(LIBANDROID_NAME, libc::RTLD_LAZY | libc::RTLD_LOCAL);
if handle.is_null() {
return;
}
// Transmute guarantee for `fn -> Option<fn>`: https://doc.rust-lang.org/std/option/#representation
LIBANDROID_ASHAREDMEMORY_CREATE =
std::mem::transmute(libc::dlsym(handle, LIBANDROID_ASHAREDMEMORY_CREATE_NAME));
LIBANDROID_ASHAREDMEMORY_GETSIZE =
std::mem::transmute(libc::dlsym(handle, LIBANDROID_ASHAREDMEMORY_GETSIZE_NAME));
LIBANDROID_ASHAREDMEMORY_SETPROT =
std::mem::transmute(libc::dlsym(handle, LIBANDROID_ASHAREDMEMORY_SETPROT_NAME));
});
}

/// See [ASharedMemory_create NDK documentation](https://developer.android.com/ndk/reference/group/memory#asharedmemory_create)
///
/// # Safety
///
/// Directly calls C or kernel APIs.
#[allow(non_snake_case)]
pub unsafe fn ASharedMemory_create(name: *const libc::c_char, size: libc::size_t) -> libc::c_int {
const ASHMEM_NAME_DEF: *const libc::c_char = "/dev/ashmem".as_ptr() as _;
const ASHMEM_NAME_LEN: usize = 256;
const ASHMEM_SET_NAME: libc::c_int = iow!(
__ASHMEMIOC,
1,
std::mem::size_of::<[libc::c_char; ASHMEM_NAME_LEN]>()
) as _;
const ASHMEM_SET_SIZE: libc::c_int =
iow!(__ASHMEMIOC, 3, std::mem::size_of::<libc::size_t>()) as _;

maybe_init();
if let Some(fun) = LIBANDROID_ASHAREDMEMORY_CREATE {
return fun(name, size);
}

let fd = libc::open(ASHMEM_NAME_DEF, libc::O_RDWR, 0o600);
if fd < 0 {
return fd;
}

if !name.is_null() {
// NOTE: libcutils uses a local stack copy of `name`.
let r = libc::ioctl(fd, ASHMEM_SET_NAME, name);
if r != 0 {
libc::close(fd);
return -1;
}
}

let r = libc::ioctl(fd, ASHMEM_SET_SIZE, size);
if r != 0 {
libc::close(fd);
return -1;
}

fd
}

/// See [ASharedMemory_getSize NDK documentation](https://developer.android.com/ndk/reference/group/memory#asharedmemory_getsize)
///
/// # Safety
///
/// Directly calls C or kernel APIs.
#[allow(non_snake_case)]
pub unsafe fn ASharedMemory_getSize(fd: libc::c_int) -> libc::size_t {
const ASHMEM_GET_SIZE: libc::c_int = io!(__ASHMEMIOC, 4) as _;

maybe_init();
if let Some(fun) = LIBANDROID_ASHAREDMEMORY_GETSIZE {
return fun(fd);
}

libc::ioctl(fd, ASHMEM_GET_SIZE) as libc::size_t
}

/// See [ASharedMemory_setProt NDK documentation](https://developer.android.com/ndk/reference/group/memory#asharedmemory_setprot)
///
/// # Safety
///
/// Directly calls C or kernel APIs.
#[allow(non_snake_case)]
pub unsafe fn ASharedMemory_setProt(fd: libc::c_int, prot: libc::c_int) -> libc::c_int {
const ASHMEM_SET_PROT_MASK: libc::c_int =
iow!(__ASHMEMIOC, 5, std::mem::size_of::<libc::c_ulong>()) as _;

maybe_init();
if let Some(fun) = LIBANDROID_ASHAREDMEMORY_SETPROT {
return fun(fd, prot);
}

let r = libc::ioctl(fd, ASHMEM_SET_PROT_MASK, prot);
if r != 0 {
return -1;
}
r
}

#[cfg(test)]
mod tests {
#[test]
fn basic() {
unsafe {
let name = std::ffi::CString::new("/test-ashmem").unwrap();
let fd = super::ASharedMemory_create(name.as_ptr(), 128);
assert!(fd >= 0);
assert_eq!(super::ASharedMemory_getSize(fd), 128);
assert_eq!(super::ASharedMemory_setProt(fd, 0), 0);
libc::close(fd);
}
}

#[test]
fn anonymous() {
unsafe {
let fd = super::ASharedMemory_create(std::ptr::null(), 128);
assert!(fd >= 0);
libc::close(fd);
}
}
}
2 changes: 1 addition & 1 deletion third_party/rust/audioipc-client/.cargo-checksum.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"files":{"Cargo.toml":"4020e8c4119327dac49b47391c902eb69bb927c9e7d05f5882ad9e84cff4ec5e","cbindgen.toml":"bd89c5a9f52395b1c703ff04d1c0019dc3c92b691d571ae503c4b85753a44a39","src/context.rs":"a9bbd35faf15a579e92e56bc78881b4a064edb579f875b8804db1737fd2fdfeb","src/lib.rs":"ad38115edb187bcc7e5c57a355913f4f588ffebabc6f77b314b0b1f503886590","src/send_recv.rs":"450bdb1d8a346634c0237f2081b424d11e2c19ad81670009303f8a03b3bfb196","src/stream.rs":"9ef8ea1ccf33429f5ab63e0029e8818382f3f4d01617da3844fcd79d9ea1704e"},"package":null}
{"files":{"Cargo.toml":"4020e8c4119327dac49b47391c902eb69bb927c9e7d05f5882ad9e84cff4ec5e","cbindgen.toml":"bd89c5a9f52395b1c703ff04d1c0019dc3c92b691d571ae503c4b85753a44a39","src/context.rs":"7388ee487bc25bbdf5cc6475dfa78674bdd9f49c92968c1b0a8047cdd023476c","src/lib.rs":"7755001c8caf6899ca5ed00a517d7bf1b6425fe17157a97037dae619af567fc9","src/send_recv.rs":"450bdb1d8a346634c0237f2081b424d11e2c19ad81670009303f8a03b3bfb196","src/stream.rs":"a7b32be48f67ef6b7fbcf61b25e02cab1e961ef3146c3ace2f16ced9dab2953e"},"package":null}
27 changes: 8 additions & 19 deletions third_party/rust/audioipc-client/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use std::os::raw::c_void;
use std::sync::mpsc;
use std::sync::{Arc, Mutex};
use std::thread;
use std::{fmt, io, mem, ptr};
use std::{fmt, mem, ptr};
use tokio::reactor;
use tokio::runtime::current_thread;

Expand Down Expand Up @@ -189,13 +189,12 @@ impl ContextOps for ClientContext {
fn bind_and_send_client(
stream: audioipc::AsyncMessageStream,
tx_rpc: &mpsc::Sender<rpc::ClientProxy<ServerMessage, ClientMessage>>,
) -> io::Result<()> {
) {
let transport = framed_with_platformhandles(stream, Default::default());
let rpc = rpc::bind_client::<CubebClient>(transport);
// If send fails then the rx end has closed
// which is unlikely here.
let _ = tx_rpc.send(rpc);
Ok(())
}

assert_not_in_callback();
Expand All @@ -216,9 +215,9 @@ impl ContextOps for ClientContext {

register_thread(thread_create_callback);

server_stream
.into_tokio_ipc(&handle)
.and_then(|stream| bind_and_send_client(stream, &tx_rpc))
let stream = server_stream.into_tokio_ipc(&handle).unwrap();
bind_and_send_client(stream, &tx_rpc);
Ok(())
},
move || unregister_thread(thread_destroy_callback),
)
Expand Down Expand Up @@ -344,20 +343,10 @@ impl ContextOps for ClientContext {
) -> Result<Stream> {
assert_not_in_callback();

fn opt_stream_params(p: Option<&StreamParamsRef>) -> Option<messages::StreamParams> {
match p {
Some(p) => Some(messages::StreamParams::from(p)),
None => None,
}
}

let stream_name = match stream_name {
Some(s) => Some(s.to_bytes_with_nul().to_vec()),
None => None,
};
let stream_name = stream_name.map(|name| name.to_bytes_with_nul().to_vec());

let input_stream_params = opt_stream_params(input_stream_params);
let output_stream_params = opt_stream_params(output_stream_params);
let input_stream_params = input_stream_params.map(messages::StreamParams::from);
let output_stream_params = output_stream_params.map(messages::StreamParams::from);

let init_params = messages::StreamInitParams {
stream_name,
Expand Down
3 changes: 2 additions & 1 deletion third_party/rust/audioipc-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,11 @@ where

fn assert_not_in_callback() {
IN_CALLBACK.with(|b| {
assert_eq!(*b.borrow(), false);
assert!(!*b.borrow());
});
}

#[allow(clippy::missing_safety_doc)]
#[no_mangle]
/// Entry point from C code.
pub unsafe extern "C" fn audioipc_client_init(
Expand Down
10 changes: 2 additions & 8 deletions third_party/rust/audioipc-client/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,8 @@ impl rpc::Server for CallbackServer {
);

// Clone values that need to be moved into the cpu pool thread.
let input_shm = match self.input_shm {
Some(ref shm) => unsafe { Some(shm.unsafe_view()) },
None => None,
};
let output_shm = match self.output_shm {
Some(ref shm) => unsafe { Some(shm.unsafe_view()) },
None => None,
};
let input_shm = unsafe { self.input_shm.as_ref().map(|shm| shm.unsafe_view()) };
let output_shm = unsafe { self.output_shm.as_ref().map(|shm| shm.unsafe_view()) };
let user_ptr = self.user_ptr;
let cb = self.data_cb.unwrap();

Expand Down
2 changes: 1 addition & 1 deletion third_party/rust/audioipc-server/.cargo-checksum.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"files":{"Cargo.toml":"6329179497fb654bec0dea9f3642056309de3fa37d4042a48d18224e7b4742d3","cbindgen.toml":"bd89c5a9f52395b1c703ff04d1c0019dc3c92b691d571ae503c4b85753a44a39","src/lib.rs":"c1756c15724af6639cad7c3e3e730803323ac0357870262c835ccc9430ec457e","src/server.rs":"bbb7feac3daad9306aca572c4fb8471f99cef9e80914f6f860dbd3403151efcc"},"package":null}
{"files":{"Cargo.toml":"6329179497fb654bec0dea9f3642056309de3fa37d4042a48d18224e7b4742d3","cbindgen.toml":"bd89c5a9f52395b1c703ff04d1c0019dc3c92b691d571ae503c4b85753a44a39","src/lib.rs":"2e56bed9ea0012222bab33680a926b3761c66f455253baf09bd0166ce38237f4","src/server.rs":"7404bfdb69c6b830937dcc81c7996d638737ea4010ee255eb9895ff938b1a198"},"package":null}
Loading

0 comments on commit a455211

Please sign in to comment.