Skip to content

Commit b646632

Browse files
committed
Document resources as unretained
And mark `commandBufferWithUnretainedReferences` as safe.
1 parent 5f13c1c commit b646632

File tree

4 files changed

+37
-12
lines changed

4 files changed

+37
-12
lines changed

crates/header-translator/src/rust_type.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,18 @@ impl PointeeTy {
11751175
// `MTLFence` (GPU side).
11761176
[(protocol, _)] if protocol.is_subprotocol_of("MTLResource") => {
11771177
let safety = TypeSafety::unknown_in_argument("may need to be synchronized");
1178+
1179+
// Additionally, resources in a command buffer must be
1180+
// kept alive by the application for as long as they're
1181+
// used. If this is not done, it is possible to encounter
1182+
// use-after-frees with:
1183+
// - `MTLCommandBufferDescriptor::setRetainedReferences(false)`.
1184+
// - `MTLCommandQueue::commandBufferWithUnretainedReferences()`.
1185+
// - All `MTL4CommandBuffer`s.
1186+
let safety = safety.merge(TypeSafety::unknown_in_argument(
1187+
"may be unretained, you must ensure it is kept alive while in use",
1188+
));
1189+
11781190
// `MTLBuffer` is effectively a `Box<[u8]>` stored on the
11791191
// GPU (and depending on the storage mode, optionally also
11801192
// on the CPU). Type-safety of the contents is left

framework-crates/objc2-metal/src/lib.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
//!
3333
//! ## Shaders
3434
//!
35-
//! Loading shaders (via `MTLLibrary`, function stitching etc.) is perfectly
35+
//! Shaders are (often) written in an unsafe C-like language.
36+
//!
37+
//! Loading them (via `MTLLibrary`, function stitching etc.) is perfectly
3638
//! safe, it is similar to dynamic linking. The restrictions that e.g.
3739
//! `libloading::Library::new` labours under do not apply, since there are no
3840
//! ctors in [the Metal Shading Language][msl-spec] (see section 4.2).
@@ -56,17 +58,23 @@
5658
//!
5759
//! ## Synchronization
5860
//!
59-
//! `MTLResource` subclasses such as `MTLBuffer` require synchronization
60-
//! between the CPU and the GPU, or between different threads on the GPU
61-
//! itself, so APIs taking these are often unsafe.
61+
//! `MTLResource` subclasses such as `MTLBuffer` and `MTLTexture` require
62+
//! synchronization between the CPU and the GPU, or between different threads
63+
//! on the GPU itself, so APIs taking these are often unsafe.
64+
//!
65+
//! ## Memory management and lifetimes
6266
//!
63-
//! ## Resource allocation and memory management
67+
//! Resources used in `MTL4CommandBuffer`s or command buffers with created
68+
//! with one of:
69+
//! - `MTLCommandBufferDescriptor::setRetainedReferences(false)`.
70+
//! - `MTLCommandQueue::commandBufferWithUnretainedReferences()`.
6471
//!
65-
//! TODO.
72+
//! Must be kept alive for as long as they're used.
6673
//!
6774
//! ## Type safety
6875
//!
69-
//! TODO.
76+
//! `MTLBuffer` is untyped (in a similar manner as a `[u8]` slice), you must
77+
//! ensure that any usage of it is done with valid types.
7078
#![recursion_limit = "256"]
7179
#![allow(non_snake_case)]
7280
#![no_std]

framework-crates/objc2-metal/translation-config.toml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,15 @@ protocol.MTLResource.methods.makeAliasable.unsafe = true
190190
# TODO(breaking): Mark this as unsafe?
191191
class.MTLHeapDescriptor.methods."setType:".unsafe = false
192192

193-
# These affect lifetime safety, and can cause use-after-free if used incorrectly.
194-
class.MTLCommandBufferDescriptor.methods."setRetainedReferences:".unsafe = true
195-
protocol.MTLCommandQueue.methods.commandBufferWithUnretainedReferences.unsafe = true
196-
protocol.MTLIOCommandQueue.methods.commandBufferWithUnretainedReferences.unsafe = true
193+
# SAFETY: We could consider marking these as unsafe, since they affect
194+
# lifetime safety, and can cause use-after-free if used incorrectly.
195+
#
196+
# Unretained references are the only option for `MTL4CommandBuffer`s though,
197+
# and we already mark `MTLResource`s as unsafe, so we choose to move the
198+
# unsafety of this to the resources instead.
199+
# class.MTLCommandBufferDescriptor.methods."setRetainedReferences:".unsafe = true
200+
# protocol.MTLCommandQueue.methods.commandBufferWithUnretainedReferences.unsafe = true
201+
# protocol.MTLIOCommandQueue.methods.commandBufferWithUnretainedReferences.unsafe = true
197202

198203
# Must be a multiple of 4.
199204
class.MTLVertexBufferLayoutDescriptor.methods."setStride:".unsafe = true

generated

Submodule generated updated 62 files

0 commit comments

Comments
 (0)