Skip to content

Commit

Permalink
ndk: Requre all off-thread dyn Fn* callback types to implement Send
Browse files Browse the repository at this point in the history
In all these cases the NDK either documents or implements the callback
to be invoked from a single, separate thread.  For this to be allowed
by Rust thread safety, the closures and their (moved) contents are
effectively  "moved" to a different thread (`Send`) but not accessed
concurrently (`Sync`), but the type definitions were never requiring
this marker trait which could lead to undefined/invalid behaviour.

A request has been filed to solidify this "behavioural contract" in the
documentation where not done so yet:
https://issuetracker.google.com/issues/300602767#comment12
  • Loading branch information
MarijnS95 committed Dec 11, 2023
1 parent 2d269e1 commit a0a6b17
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 8 deletions.
9 changes: 9 additions & 0 deletions ndk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

- Move `MediaFormat` from `media::media_codec` to its own `media::media_format` module. (#442)
- media_format: Expose `MediaFormat::copy()` and `MediaFormat::clear()` from API level 29. (#449)
- **Breaking**: Require all `dyn Fn*` types to implement `Send` when the FFI implementation invokes them on a separate thread (#455)
- `audio::AudioStreamDataCallback`;
- `audio::AudioStreamErrorCallback`;
- `media::image_reader::BufferRemovedListener`;
- `media::image_reader::ImageListener`;
- `media::media_codec::ErrorCallback`;
- `media::media_codec::FormatChangedCallback`;
- `media::media_codec::InputAvailableCallback`;
- `media::media_codec::OutputAvailableCallback`.

# 0.8.0 (2023-10-15)

Expand Down
4 changes: 2 additions & 2 deletions ndk/src/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,9 @@ impl fmt::Debug for AudioStreamBuilder {

#[doc(alias = "AAudioStream_dataCallback")]
pub type AudioStreamDataCallback =
Box<dyn FnMut(&AudioStream, *mut c_void, i32) -> AudioCallbackResult>;
Box<dyn FnMut(&AudioStream, *mut c_void, i32) -> AudioCallbackResult + Send>;
#[doc(alias = "AAudioStream_errorCallback")]
pub type AudioStreamErrorCallback = Box<dyn FnMut(&AudioStream, AudioError)>;
pub type AudioStreamErrorCallback = Box<dyn FnMut(&AudioStream, AudioError) + Send>;

impl AudioStreamBuilder {
fn from_ptr(inner: NonNull<ffi::AAudioStreamBuilder>) -> Self {
Expand Down
4 changes: 2 additions & 2 deletions ndk/src/media/image_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ pub enum ImageFormat {
DEPTH_JPEG = ffi::AIMAGE_FORMATS::AIMAGE_FORMAT_DEPTH_JPEG.0,
}

pub type ImageListener = Box<dyn FnMut(&ImageReader)>;
pub type ImageListener = Box<dyn FnMut(&ImageReader) + Send>;

#[cfg(feature = "api-level-26")]
pub type BufferRemovedListener = Box<dyn FnMut(&ImageReader, &HardwareBuffer)>;
pub type BufferRemovedListener = Box<dyn FnMut(&ImageReader, &HardwareBuffer) + Send>;

/// A native [`AImageReader *`]
///
Expand Down
8 changes: 4 additions & 4 deletions ndk/src/media/media_codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ impl fmt::Debug for AsyncNotifyCallback {
}
}

pub type InputAvailableCallback = Box<dyn FnMut(usize)>;
pub type OutputAvailableCallback = Box<dyn FnMut(usize, &BufferInfo)>;
pub type FormatChangedCallback = Box<dyn FnMut(&MediaFormat)>;
pub type ErrorCallback = Box<dyn FnMut(MediaError, ActionCode, &CStr)>;
pub type InputAvailableCallback = Box<dyn FnMut(usize) + Send>;
pub type OutputAvailableCallback = Box<dyn FnMut(usize, &BufferInfo) + Send>;
pub type FormatChangedCallback = Box<dyn FnMut(&MediaFormat) + Send>;
pub type ErrorCallback = Box<dyn FnMut(MediaError, ActionCode, &CStr) + Send>;

impl MediaCodec {
fn as_ptr(&self) -> *mut ffi::AMediaCodec {
Expand Down

0 comments on commit a0a6b17

Please sign in to comment.