4
4
//!
5
5
//! C header: [`include/linux/types.h`](../../../../include/linux/types.h)
6
6
7
- use core:: { ops:: Deref , pin:: Pin } ;
8
-
7
+ use crate :: {
8
+ bindings, c_types,
9
+ sync:: { Ref , RefCounted } ,
10
+ } ;
9
11
use alloc:: { boxed:: Box , sync:: Arc } ;
10
-
11
- use crate :: bindings;
12
- use crate :: c_types;
13
- use crate :: sync:: { Ref , RefCounted } ;
12
+ use core:: { ops:: Deref , pin:: Pin , ptr:: NonNull } ;
14
13
15
14
/// Permissions.
16
15
///
@@ -37,9 +36,22 @@ impl Mode {
37
36
/// in kernel data structures, for example, an implementation of [`FileOperations`] in `struct
38
37
/// file::private_data`.
39
38
pub trait PointerWrapper {
39
+ /// Type of values borrowed between calls to [`PointerWrapper::into_pointer`] and
40
+ /// [`PointerWrapper::from_pointer`].
41
+ type Borrowed : Deref ;
42
+
40
43
/// Returns the raw pointer.
41
44
fn into_pointer ( self ) -> * const c_types:: c_void ;
42
45
46
+ /// Returns a borrowed value.
47
+ ///
48
+ /// # Safety
49
+ ///
50
+ /// `ptr` must have been returned by a previous call to [`PointerWrapper::into_pointer`].
51
+ /// Additionally, [`PointerWrapper::from_pointer`] can only be called after *all* values
52
+ /// returned by [`PointerWrapper::borrow`] have been dropped.
53
+ unsafe fn borrow ( ptr : * const c_types:: c_void ) -> Self :: Borrowed ;
54
+
43
55
/// Returns the instance back from the raw pointer.
44
56
///
45
57
/// # Safety
@@ -49,46 +61,121 @@ pub trait PointerWrapper {
49
61
}
50
62
51
63
impl < T > PointerWrapper for Box < T > {
64
+ type Borrowed = UnsafeReference < T > ;
65
+
52
66
fn into_pointer ( self ) -> * const c_types:: c_void {
53
67
Box :: into_raw ( self ) as _
54
68
}
55
69
70
+ unsafe fn borrow ( ptr : * const c_types:: c_void ) -> Self :: Borrowed {
71
+ // SAFETY: The safety requirements for this function ensure that the object is still alive,
72
+ // so it is safe to dereference the raw pointer.
73
+ // The safety requirements also ensure that the object remains alive for the lifetime of
74
+ // the returned value.
75
+ unsafe { UnsafeReference :: new ( & * ptr. cast ( ) ) }
76
+ }
77
+
56
78
unsafe fn from_pointer ( ptr : * const c_types:: c_void ) -> Self {
57
79
// SAFETY: The passed pointer comes from a previous call to [`Self::into_pointer()`].
58
80
unsafe { Box :: from_raw ( ptr as _ ) }
59
81
}
60
82
}
61
83
62
84
impl < T : RefCounted > PointerWrapper for Ref < T > {
85
+ type Borrowed = UnsafeReference < T > ;
86
+
63
87
fn into_pointer ( self ) -> * const c_types:: c_void {
64
88
Ref :: into_raw ( self ) as _
65
89
}
66
90
91
+ unsafe fn borrow ( ptr : * const c_types:: c_void ) -> Self :: Borrowed {
92
+ // SAFETY: The safety requirements for this function ensure that the object is still alive,
93
+ // so it is safe to dereference the raw pointer.
94
+ // The safety requirements also ensure that the object remains alive for the lifetime of
95
+ // the returned value.
96
+ unsafe { UnsafeReference :: new ( & * ptr. cast ( ) ) }
97
+ }
98
+
67
99
unsafe fn from_pointer ( ptr : * const c_types:: c_void ) -> Self {
68
100
// SAFETY: The passed pointer comes from a previous call to [`Self::into_pointer()`].
69
101
unsafe { Ref :: from_raw ( ptr as _ ) }
70
102
}
71
103
}
72
104
73
105
impl < T > PointerWrapper for Arc < T > {
106
+ type Borrowed = UnsafeReference < T > ;
107
+
74
108
fn into_pointer ( self ) -> * const c_types:: c_void {
75
109
Arc :: into_raw ( self ) as _
76
110
}
77
111
112
+ unsafe fn borrow ( ptr : * const c_types:: c_void ) -> Self :: Borrowed {
113
+ // SAFETY: The safety requirements for this function ensure that the object is still alive,
114
+ // so it is safe to dereference the raw pointer.
115
+ // The safety requirements also ensure that the object remains alive for the lifetime of
116
+ // the returned value.
117
+ unsafe { UnsafeReference :: new ( & * ptr. cast ( ) ) }
118
+ }
119
+
78
120
unsafe fn from_pointer ( ptr : * const c_types:: c_void ) -> Self {
79
121
// SAFETY: The passed pointer comes from a previous call to [`Self::into_pointer()`].
80
122
unsafe { Arc :: from_raw ( ptr as _ ) }
81
123
}
82
124
}
83
125
126
+ /// A reference with manually-managed lifetime.
127
+ ///
128
+ /// # Invariants
129
+ ///
130
+ /// There are no mutable references to the underlying object, and it remains valid for the lifetime
131
+ /// of the [`UnsafeReference`] instance.
132
+ pub struct UnsafeReference < T : ?Sized > {
133
+ ptr : NonNull < T > ,
134
+ }
135
+
136
+ impl < T : ?Sized > UnsafeReference < T > {
137
+ /// Creates a new [`UnsafeReference`] instance.
138
+ ///
139
+ /// # Safety
140
+ ///
141
+ /// Callers must ensure the following for the lifetime of the returned [`UnsafeReference`]
142
+ /// instance:
143
+ /// 1. That `obj` remains valid;
144
+ /// 2. That no mutable references to `obj` are created.
145
+ unsafe fn new ( obj : & T ) -> Self {
146
+ // INVARIANT: The safety requirements of this function ensure that the invariants hold.
147
+ Self {
148
+ ptr : NonNull :: from ( obj) ,
149
+ }
150
+ }
151
+ }
152
+
153
+ impl < T : ?Sized > Deref for UnsafeReference < T > {
154
+ type Target = T ;
155
+
156
+ fn deref ( & self ) -> & Self :: Target {
157
+ // SAFETY: By the type invariant, the object is still valid and alive, and there are no
158
+ // mutable references to it.
159
+ unsafe { self . ptr . as_ref ( ) }
160
+ }
161
+ }
162
+
84
163
impl < T : PointerWrapper + Deref > PointerWrapper for Pin < T > {
164
+ type Borrowed = T :: Borrowed ;
165
+
85
166
fn into_pointer ( self ) -> * const c_types:: c_void {
86
167
// SAFETY: We continue to treat the pointer as pinned by returning just a pointer to it to
87
168
// the caller.
88
169
let inner = unsafe { Pin :: into_inner_unchecked ( self ) } ;
89
170
inner. into_pointer ( )
90
171
}
91
172
173
+ unsafe fn borrow ( ptr : * const c_types:: c_void ) -> Self :: Borrowed {
174
+ // SAFETY: The safety requirements for this function are the same as the ones for
175
+ // `T::borrow`.
176
+ unsafe { T :: borrow ( ptr) }
177
+ }
178
+
92
179
unsafe fn from_pointer ( p : * const c_types:: c_void ) -> Self {
93
180
// SAFETY: The object was originally pinned.
94
181
// The passed pointer comes from a previous call to `inner::into_pointer()`.
0 commit comments