Skip to content

Commit 0f3ae60

Browse files
authored
Merge pull request #555 from wedsonaf/pin-cleanup
rust: remove all usages of `try_new_and_init` and `pin_init_and_share`.
2 parents f8a2c63 + 36a85e4 commit 0f3ae60

File tree

7 files changed

+149
-181
lines changed

7 files changed

+149
-181
lines changed

drivers/android/context.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use kernel::{
44
bindings,
55
prelude::*,
66
security,
7-
sync::{Mutex, Ref},
7+
sync::{Mutex, Ref, UniqueRef},
88
};
99

1010
use crate::{
@@ -26,22 +26,21 @@ unsafe impl Sync for Context {}
2626

2727
impl Context {
2828
pub(crate) fn new() -> Result<Ref<Self>> {
29-
Ref::try_new_and_init(
30-
Self {
31-
// SAFETY: Init is called below.
32-
manager: unsafe {
33-
Mutex::new(Manager {
34-
node: None,
35-
uid: None,
36-
})
37-
},
29+
let mut ctx = Pin::from(UniqueRef::try_new(Self {
30+
// SAFETY: Init is called below.
31+
manager: unsafe {
32+
Mutex::new(Manager {
33+
node: None,
34+
uid: None,
35+
})
3836
},
39-
|mut ctx| {
40-
// SAFETY: `manager` is also pinned when `ctx` is.
41-
let manager = unsafe { ctx.as_mut().map_unchecked_mut(|c| &mut c.manager) };
42-
kernel::mutex_init!(manager, "Context::manager");
43-
},
44-
)
37+
})?);
38+
39+
// SAFETY: `manager` is also pinned when `ctx` is.
40+
let manager = unsafe { ctx.as_mut().map_unchecked_mut(|c| &mut c.manager) };
41+
kernel::mutex_init!(manager, "Context::manager");
42+
43+
Ok(ctx.into())
4544
}
4645

4746
pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result {

drivers/android/process.rs

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -261,24 +261,24 @@ unsafe impl Sync for Process {}
261261

262262
impl Process {
263263
fn new(ctx: Ref<Context>) -> Result<Ref<Self>> {
264-
Ref::try_new_and_init(
265-
Self {
266-
ctx,
267-
task: Task::current().group_leader().clone(),
268-
// SAFETY: `inner` is initialised in the call to `mutex_init` below.
269-
inner: unsafe { Mutex::new(ProcessInner::new()) },
270-
// SAFETY: `node_refs` is initialised in the call to `mutex_init` below.
271-
node_refs: unsafe { Mutex::new(ProcessNodeRefs::new()) },
272-
},
273-
|mut process| {
274-
// SAFETY: `inner` is pinned when `Process` is.
275-
let pinned = unsafe { process.as_mut().map_unchecked_mut(|p| &mut p.inner) };
276-
kernel::mutex_init!(pinned, "Process::inner");
277-
// SAFETY: `node_refs` is pinned when `Process` is.
278-
let pinned = unsafe { process.as_mut().map_unchecked_mut(|p| &mut p.node_refs) };
279-
kernel::mutex_init!(pinned, "Process::node_refs");
280-
},
281-
)
264+
let mut process = Pin::from(UniqueRef::try_new(Self {
265+
ctx,
266+
task: Task::current().group_leader().clone(),
267+
// SAFETY: `inner` is initialised in the call to `mutex_init` below.
268+
inner: unsafe { Mutex::new(ProcessInner::new()) },
269+
// SAFETY: `node_refs` is initialised in the call to `mutex_init` below.
270+
node_refs: unsafe { Mutex::new(ProcessNodeRefs::new()) },
271+
})?);
272+
273+
// SAFETY: `inner` is pinned when `Process` is.
274+
let pinned = unsafe { process.as_mut().map_unchecked_mut(|p| &mut p.inner) };
275+
kernel::mutex_init!(pinned, "Process::inner");
276+
277+
// SAFETY: `node_refs` is pinned when `Process` is.
278+
let pinned = unsafe { process.as_mut().map_unchecked_mut(|p| &mut p.node_refs) };
279+
kernel::mutex_init!(pinned, "Process::node_refs");
280+
281+
Ok(process.into())
282282
}
283283

284284
/// Attemps to fetch a work item from the process queue.
@@ -704,12 +704,14 @@ impl Process {
704704
return Ok(());
705705
}
706706

707-
let death = death
708-
.write(
707+
let death = {
708+
let mut pinned = Pin::from(death.write(
709709
// SAFETY: `init` is called below.
710710
unsafe { NodeDeath::new(info.node_ref.node.clone(), self.clone(), cookie) },
711-
)
712-
.pin_init_and_share(|pinned_death| pinned_death.init());
711+
));
712+
pinned.as_mut().init();
713+
Ref::<NodeDeath>::from(pinned)
714+
};
713715

714716
info.death = Some(death.clone());
715717

drivers/android/thread.rs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use kernel::{
1313
linked_list::{GetLinks, Links, List},
1414
prelude::*,
1515
security,
16-
sync::{CondVar, Ref, SpinLock},
16+
sync::{CondVar, Ref, SpinLock, UniqueRef},
1717
user_ptr::{UserSlicePtr, UserSlicePtrWriter},
1818
};
1919

@@ -241,31 +241,31 @@ impl Thread {
241241
pub(crate) fn new(id: i32, process: Ref<Process>) -> Result<Ref<Self>> {
242242
let return_work = Ref::try_new(ThreadError::new(InnerThread::set_return_work))?;
243243
let reply_work = Ref::try_new(ThreadError::new(InnerThread::set_reply_work))?;
244-
Ref::try_new_and_init(
245-
Self {
246-
id,
247-
process,
248-
// SAFETY: `inner` is initialised in the call to `spinlock_init` below.
249-
inner: unsafe { SpinLock::new(InnerThread::new()) },
250-
// SAFETY: `work_condvar` is initalised in the call to `condvar_init` below.
251-
work_condvar: unsafe { CondVar::new() },
252-
links: Links::new(),
253-
},
254-
|mut thread| {
255-
// SAFETY: `inner` is pinned when `thread` is.
256-
let inner = unsafe { thread.as_mut().map_unchecked_mut(|t| &mut t.inner) };
257-
kernel::spinlock_init!(inner, "Thread::inner");
258-
259-
// SAFETY: `work_condvar` is pinned when `thread` is.
260-
let condvar = unsafe { thread.as_mut().map_unchecked_mut(|t| &mut t.work_condvar) };
261-
kernel::condvar_init!(condvar, "Thread::work_condvar");
262-
{
263-
let mut inner = thread.inner.lock();
264-
inner.set_reply_work(reply_work);
265-
inner.set_return_work(return_work);
266-
}
267-
},
268-
)
244+
let mut thread = Pin::from(UniqueRef::try_new(Self {
245+
id,
246+
process,
247+
// SAFETY: `inner` is initialised in the call to `spinlock_init` below.
248+
inner: unsafe { SpinLock::new(InnerThread::new()) },
249+
// SAFETY: `work_condvar` is initalised in the call to `condvar_init` below.
250+
work_condvar: unsafe { CondVar::new() },
251+
links: Links::new(),
252+
})?);
253+
254+
// SAFETY: `inner` is pinned when `thread` is.
255+
let inner = unsafe { thread.as_mut().map_unchecked_mut(|t| &mut t.inner) };
256+
kernel::spinlock_init!(inner, "Thread::inner");
257+
258+
// SAFETY: `work_condvar` is pinned when `thread` is.
259+
let condvar = unsafe { thread.as_mut().map_unchecked_mut(|t| &mut t.work_condvar) };
260+
kernel::condvar_init!(condvar, "Thread::work_condvar");
261+
262+
{
263+
let mut inner = thread.inner.lock();
264+
inner.set_reply_work(reply_work);
265+
inner.set_return_work(return_work);
266+
}
267+
268+
Ok(thread.into())
269269
}
270270

271271
pub(crate) fn set_current_transaction(&self, transaction: Ref<Transaction>) {

drivers/android/transaction.rs

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use kernel::{
88
linked_list::List,
99
linked_list::{GetLinks, Links},
1010
prelude::*,
11-
sync::{Ref, SpinLock},
11+
sync::{Ref, SpinLock, UniqueRef},
1212
user_ptr::UserSlicePtrWriter,
1313
ScopeGuard,
1414
};
@@ -55,29 +55,27 @@ impl Transaction {
5555
let data_address = alloc.ptr;
5656
let file_list = alloc.take_file_list();
5757
alloc.keep_alive();
58-
let tr = Ref::try_new_and_init(
59-
Self {
60-
// SAFETY: `spinlock_init` is called below.
61-
inner: unsafe { SpinLock::new(TransactionInner { file_list }) },
62-
node_ref: Some(node_ref),
63-
stack_next,
64-
from: from.clone(),
65-
to,
66-
code: tr.code,
67-
flags: tr.flags,
68-
data_size: tr.data_size as _,
69-
data_address,
70-
offsets_size: tr.offsets_size as _,
71-
links: Links::new(),
72-
free_allocation: AtomicBool::new(true),
73-
},
74-
|mut tr| {
75-
// SAFETY: `inner` is pinned when `tr` is.
76-
let pinned = unsafe { tr.as_mut().map_unchecked_mut(|t| &mut t.inner) };
77-
kernel::spinlock_init!(pinned, "Transaction::inner");
78-
},
79-
)?;
80-
Ok(tr)
58+
let mut tr = Pin::from(UniqueRef::try_new(Self {
59+
// SAFETY: `spinlock_init` is called below.
60+
inner: unsafe { SpinLock::new(TransactionInner { file_list }) },
61+
node_ref: Some(node_ref),
62+
stack_next,
63+
from: from.clone(),
64+
to,
65+
code: tr.code,
66+
flags: tr.flags,
67+
data_size: tr.data_size as _,
68+
data_address,
69+
offsets_size: tr.offsets_size as _,
70+
links: Links::new(),
71+
free_allocation: AtomicBool::new(true),
72+
})?);
73+
74+
// SAFETY: `inner` is pinned when `tr` is.
75+
let pinned = unsafe { tr.as_mut().map_unchecked_mut(|t| &mut t.inner) };
76+
kernel::spinlock_init!(pinned, "Transaction::inner");
77+
78+
Ok(tr.into())
8179
}
8280

8381
pub(crate) fn new_reply(
@@ -90,29 +88,27 @@ impl Transaction {
9088
let data_address = alloc.ptr;
9189
let file_list = alloc.take_file_list();
9290
alloc.keep_alive();
93-
let tr = Ref::try_new_and_init(
94-
Self {
95-
// SAFETY: `spinlock_init` is called below.
96-
inner: unsafe { SpinLock::new(TransactionInner { file_list }) },
97-
node_ref: None,
98-
stack_next: None,
99-
from: from.clone(),
100-
to,
101-
code: tr.code,
102-
flags: tr.flags,
103-
data_size: tr.data_size as _,
104-
data_address,
105-
offsets_size: tr.offsets_size as _,
106-
links: Links::new(),
107-
free_allocation: AtomicBool::new(true),
108-
},
109-
|mut tr| {
110-
// SAFETY: `inner` is pinned when `tr` is.
111-
let pinned = unsafe { tr.as_mut().map_unchecked_mut(|t| &mut t.inner) };
112-
kernel::spinlock_init!(pinned, "Transaction::inner");
113-
},
114-
)?;
115-
Ok(tr)
91+
let mut tr = Pin::from(UniqueRef::try_new(Self {
92+
// SAFETY: `spinlock_init` is called below.
93+
inner: unsafe { SpinLock::new(TransactionInner { file_list }) },
94+
node_ref: None,
95+
stack_next: None,
96+
from: from.clone(),
97+
to,
98+
code: tr.code,
99+
flags: tr.flags,
100+
data_size: tr.data_size as _,
101+
data_address,
102+
offsets_size: tr.offsets_size as _,
103+
links: Links::new(),
104+
free_allocation: AtomicBool::new(true),
105+
})?);
106+
107+
// SAFETY: `inner` is pinned when `tr` is.
108+
let pinned = unsafe { tr.as_mut().map_unchecked_mut(|t| &mut t.inner) };
109+
kernel::spinlock_init!(pinned, "Transaction::inner");
110+
111+
Ok(tr.into())
116112
}
117113

118114
/// Determines if the transaction is stacked on top of the given transaction.

rust/kernel/sync/arc.rs

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,6 @@ impl<T> Ref<T> {
9595
Ok(unsafe { Self::from_inner(inner) })
9696
}
9797

98-
/// Constructs a new reference counted instance of `T` and calls the initialisation function.
99-
///
100-
/// This is useful because it provides a mutable reference to `T` at its final location.
101-
pub fn try_new_and_init<U: FnOnce(Pin<&mut T>)>(contents: T, init: U) -> Result<Self> {
102-
Ok(UniqueRef::try_new(contents)?.pin_init_and_share(init))
103-
}
104-
10598
/// Deconstructs a [`Ref`] object into a `usize`.
10699
///
107100
/// It can be reconstructed once via [`Ref::from_usize`].
@@ -410,9 +403,10 @@ impl<T: ?Sized> Deref for RefBorrow<T> {
410403
/// }
411404
///
412405
/// fn test2() -> Result<Ref<Example>> {
413-
/// let mut x = UniqueRef::try_new(Example { a: 10, b: 20 })?;
406+
/// let mut pinned = Pin::from(UniqueRef::try_new(Example { a: 10, b: 20 })?);
414407
/// // We can modify `pinned` because it is `Unpin`.
415-
/// Ok(x.pin_init_and_share(|mut pinned| pinned.a += 1))
408+
/// pinned.as_mut().a += 1;
409+
/// Ok(pinned.into())
416410
/// }
417411
/// ```
418412
pub struct UniqueRef<T: ?Sized> {
@@ -437,26 +431,6 @@ impl<T> UniqueRef<T> {
437431
}
438432
}
439433

440-
impl<T: ?Sized> UniqueRef<T> {
441-
/// Converts a [`UniqueRef<T>`] into a [`Ref<T>`].
442-
///
443-
/// It allows callers to get a `Pin<&mut T>` that they can use to initialise the inner object
444-
/// just before it becomes shareable.
445-
pub fn pin_init_and_share<U: FnOnce(Pin<&mut T>)>(mut self, init: U) -> Ref<T> {
446-
let inner = self.deref_mut();
447-
448-
// SAFETY: By the `Ref` invariant, `RefInner` is pinned and `T` is also pinned.
449-
let pinned = unsafe { Pin::new_unchecked(inner) };
450-
451-
// INVARIANT: The only places where `&mut T` is available are here (where it is explicitly
452-
// pinned, i.e. implementations of `init` will see a Pin<&mut T>), and in `Ref::drop`. Both
453-
// are compatible with the pin requirements of the invariants of `Ref`.
454-
init(pinned);
455-
456-
self.into()
457-
}
458-
}
459-
460434
impl<T> UniqueRef<MaybeUninit<T>> {
461435
/// Converts a `UniqueRef<MaybeUninit<T>>` into a `UniqueRef<T>` by writing a value into it.
462436
pub fn write(mut self, value: T) -> UniqueRef<T> {

samples/rust/rust_miscdev.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use kernel::{
1111
file_operations::{FileOpener, FileOperations},
1212
io_buffer::{IoBufferReader, IoBufferWriter},
1313
miscdev,
14-
sync::{CondVar, Mutex, Ref},
14+
sync::{CondVar, Mutex, Ref, UniqueRef},
1515
};
1616

1717
module! {
@@ -35,22 +35,22 @@ struct SharedState {
3535

3636
impl SharedState {
3737
fn try_new() -> Result<Ref<Self>> {
38-
Ref::try_new_and_init(
39-
Self {
40-
// SAFETY: `condvar_init!` is called below.
41-
state_changed: unsafe { CondVar::new() },
42-
// SAFETY: `mutex_init!` is called below.
43-
inner: unsafe { Mutex::new(SharedStateInner { token_count: 0 }) },
44-
},
45-
|mut state| {
46-
// SAFETY: `state_changed` is pinned when `state` is.
47-
let pinned = unsafe { state.as_mut().map_unchecked_mut(|s| &mut s.state_changed) };
48-
kernel::condvar_init!(pinned, "SharedState::state_changed");
49-
// SAFETY: `inner` is pinned when `state` is.
50-
let pinned = unsafe { state.as_mut().map_unchecked_mut(|s| &mut s.inner) };
51-
kernel::mutex_init!(pinned, "SharedState::inner");
52-
},
53-
)
38+
let mut state = Pin::from(UniqueRef::try_new(Self {
39+
// SAFETY: `condvar_init!` is called below.
40+
state_changed: unsafe { CondVar::new() },
41+
// SAFETY: `mutex_init!` is called below.
42+
inner: unsafe { Mutex::new(SharedStateInner { token_count: 0 }) },
43+
})?);
44+
45+
// SAFETY: `state_changed` is pinned when `state` is.
46+
let pinned = unsafe { state.as_mut().map_unchecked_mut(|s| &mut s.state_changed) };
47+
kernel::condvar_init!(pinned, "SharedState::state_changed");
48+
49+
// SAFETY: `inner` is pinned when `state` is.
50+
let pinned = unsafe { state.as_mut().map_unchecked_mut(|s| &mut s.inner) };
51+
kernel::mutex_init!(pinned, "SharedState::inner");
52+
53+
Ok(state.into())
5454
}
5555
}
5656

0 commit comments

Comments
 (0)