Skip to content

Commit 2c82585

Browse files
committed
📝 adjust EntryImpl to remove unsafe code
1 parent f92fd64 commit 2c82585

File tree

1 file changed

+67
-70
lines changed

1 file changed

+67
-70
lines changed

src/d_list.rs

Lines changed: 67 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use alloc::sync::{Arc, Weak};
22
use rcu_cell::{RcuCell, RcuWeak};
33

4-
use core::mem::MaybeUninit;
54
use core::ops::Deref;
65
use core::{cmp, fmt};
76

@@ -148,56 +147,43 @@ pub struct StaticEntry<T> {
148147
}
149148

150149
impl<T> StaticEntry<T> {
150+
fn new(node: Arc<Node<T>>) -> Self {
151+
StaticEntry { node }
152+
}
151153
/// Returns true if the entry is removed.
152154
pub fn is_removed(&self) -> bool {
153155
self.node.is_removed()
154156
}
155157

156158
/// Remove the entry from the list.
157159
pub fn remove(&self) {
158-
let dummy_list = MaybeUninit::uninit();
159-
// Safety: we will not deref the dummy_list
160-
let dummy_list_ref = unsafe { dummy_list.assume_init_ref() };
161-
162-
EntryImpl::new(dummy_list_ref, &self.node).remove()
160+
EntryImpl::new(&self.node).remove()
163161
}
164162

165163
/// Replace the entry with new value,
166164
/// and return the old Entry which is marked as removed.
167165
/// If the node is alredy removed, return the passed in value in Err().
168166
/// Internally we create a new node to replace the old entry
169167
pub fn replace(&self, elt: T) -> Result<StaticEntry<T>, T> {
170-
let dummy_list = MaybeUninit::uninit();
171-
// Safety: we will not deref the dummy_list
172-
let dummy_list_ref = unsafe { dummy_list.assume_init_ref() };
173-
174-
EntryImpl::new(dummy_list_ref, &self.node)
168+
EntryImpl::new(&self.node)
175169
.replace(elt)
176-
.map(|v| v.into())
170+
.map(StaticEntry::new)
177171
}
178172

179173
/// insert an element after the entry.
180174
/// if the entry was removed, the element will be returned in Err()
181175
pub fn insert_after(&self, elt: T) -> Result<StaticEntry<T>, T> {
182-
let dummy_list = MaybeUninit::uninit();
183-
// Safety: we will not deref the dummy_list
184-
let dummy_list_ref = unsafe { dummy_list.assume_init_ref() };
185-
186-
EntryImpl::new(dummy_list_ref, &self.node)
176+
EntryImpl::new(&self.node)
187177
.insert_after(elt)
188-
.map(|v| v.into())
178+
.map(StaticEntry::new)
189179
}
190180

191181
/// insert an element ahead the entry.
192182
/// if the entry was removed, the element will be returned in Err()
193183
pub fn insert_ahead(&self, elt: T) -> Result<StaticEntry<T>, T> {
194-
let dummy_list = MaybeUninit::uninit();
195-
// Safety: we will not deref the dummy_list
196-
let dummy_list_ref = unsafe { dummy_list.assume_init_ref() };
197-
198-
EntryImpl::new(dummy_list_ref, &self.node)
184+
EntryImpl::new(&self.node)
199185
.insert_ahead(elt)
200-
.map(|v| v.into())
186+
.map(StaticEntry::new)
201187
}
202188
}
203189

@@ -250,7 +236,7 @@ impl<T: PartialOrd> PartialOrd for StaticEntry<T> {
250236

251237
impl<T> From<Entry<'_, T>> for StaticEntry<T> {
252238
fn from(entry: Entry<'_, T>) -> Self {
253-
StaticEntry { node: entry.node }
239+
entry.into_static()
254240
}
255241
}
256242

@@ -275,34 +261,57 @@ impl<'a, T> Entry<'a, T> {
275261
/// If the node is alredy removed, return the passed in value in Err().
276262
/// Internally we create a new node to replace the old entry
277263
pub fn replace(&self, elt: T) -> Result<Entry<'a, T>, T> {
278-
EntryImpl::new(self.list, &self.node).replace(elt)
264+
EntryImpl::new(&self.node).replace(elt).map(|node| Entry {
265+
list: self.list,
266+
node,
267+
})
279268
}
280269

281270
/// Remove the entry from the list.
282271
pub fn remove(&self) {
283-
EntryImpl::new(self.list, &self.node).remove()
272+
EntryImpl::new(&self.node).remove()
284273
}
285274

286275
/// insert an element after the entry.
287276
/// if the entry was removed, the element will be returned in Err()
288277
pub fn insert_after(&self, elt: T) -> Result<Entry<'a, T>, T> {
289-
EntryImpl::new(self.list, &self.node).insert_after(elt)
278+
EntryImpl::new(&self.node)
279+
.insert_after(elt)
280+
.map(|node| Entry {
281+
list: self.list,
282+
node,
283+
})
290284
}
291285

292286
/// insert an element ahead the entry.
293287
/// if the entry was removed, the element will be returned in Err()
294288
pub fn insert_ahead(&self, elt: T) -> Result<Entry<'a, T>, T> {
295-
EntryImpl::new(self.list, &self.node).insert_ahead(elt)
289+
EntryImpl::new(&self.node)
290+
.insert_ahead(elt)
291+
.map(|node| Entry {
292+
list: self.list,
293+
node,
294+
})
296295
}
297296

298297
/// Remove the entry after this entry.
299298
pub fn remove_after(&self) -> Option<Entry<'a, T>> {
300-
EntryImpl::new(self.list, &self.node).remove_after()
299+
EntryImpl::new(&self.node)
300+
.remove_after(self.list)
301+
.map(|node| Entry {
302+
list: self.list,
303+
node,
304+
})
301305
}
302306

303307
/// Remove the entry ahead this entry.
304308
pub fn remove_ahead(&self) -> Option<Entry<'a, T>> {
305-
EntryImpl::new(self.list, &self.node).remove_ahead()
309+
EntryImpl::new(&self.node)
310+
.remove_ahead(self.list)
311+
.map(|node| Entry {
312+
list: self.list,
313+
node,
314+
})
306315
}
307316

308317
/// Returns true if the entry is removed.
@@ -457,28 +466,32 @@ impl<T> LinkedList<T> {
457466

458467
/// Pushes an element to the front of the list, and returns an Entry to it.
459468
pub fn push_front(&self, elt: T) -> Entry<T> {
460-
match EntryImpl::new(self, &self.head).insert_after(elt) {
461-
Ok(entry) => entry,
469+
match EntryImpl::new(&self.head).insert_after(elt) {
470+
Ok(node) => Entry { list: self, node },
462471
Err(_) => unreachable!("push_front should always success"),
463472
}
464473
}
465474

466475
/// Pops the front element of the list, returns `None` if the list is empty.
467476
pub fn pop_front(&self) -> Option<Entry<T>> {
468-
EntryImpl::new(self, &self.head).remove_after()
477+
EntryImpl::new(&self.head)
478+
.remove_after(self)
479+
.map(|node| Entry { list: self, node })
469480
}
470481

471482
/// Pushes an element to the back of the list, and returns an Entry to it.
472483
pub fn push_back(&self, elt: T) -> Entry<T> {
473-
match EntryImpl::new(self, &self.tail).insert_ahead(elt) {
474-
Ok(entry) => entry,
484+
match EntryImpl::new(&self.tail).insert_ahead(elt) {
485+
Ok(node) => Entry { list: self, node },
475486
Err(_) => unreachable!("push_back should always success"),
476487
}
477488
}
478489

479490
/// Pops the back element of the list, returns `None` if the list is empty.
480491
pub fn pop_back(&self) -> Option<Entry<T>> {
481-
EntryImpl::new(self, &self.tail).remove_ahead()
492+
EntryImpl::new(&self.tail)
493+
.remove_ahead(self)
494+
.map(|node| Entry { list: self, node })
482495
}
483496

484497
/// Returns an iterator over the elements of the list.
@@ -513,15 +526,14 @@ impl<'a, T> Iterator for Iter<'a, T> {
513526
}
514527
}
515528

516-
struct EntryImpl<'a, 'b, T> {
517-
list: &'a LinkedList<T>,
518-
node: &'b Arc<Node<T>>,
529+
struct EntryImpl<'a, T> {
530+
node: &'a Arc<Node<T>>,
519531
}
520532

521-
impl<'a, 'b, T> EntryImpl<'a, 'b, T> {
533+
impl<'a, T> EntryImpl<'a, T> {
522534
#[inline]
523-
fn new(list: &'a LinkedList<T>, node: &'b Arc<Node<T>>) -> Self {
524-
Self { list, node }
535+
fn new(node: &'a Arc<Node<T>>) -> Self {
536+
Self { node }
525537
}
526538

527539
/// Remove the entry from the list.
@@ -554,7 +566,7 @@ impl<'a, 'b, T> EntryImpl<'a, 'b, T> {
554566
}
555567

556568
/// Replace the entry with new value,
557-
fn replace(&self, elt: T) -> Result<Entry<'a, T>, T> {
569+
fn replace(&self, elt: T) -> Result<Arc<Node<T>>, T> {
558570
let new_node = Arc::new(Node::new(elt));
559571
new_node.next.write(self.node.clone());
560572

@@ -588,15 +600,12 @@ impl<'a, 'b, T> EntryImpl<'a, 'b, T> {
588600
drop(old_node_prev);
589601
drop(old_prev_next);
590602

591-
Ok(Entry {
592-
list: self.list,
593-
node: new_node,
594-
})
603+
Ok(new_node)
595604
}
596605

597606
/// insert an element after the entry.
598607
/// if the entry was removed, the element will be returned in Err()
599-
fn insert_after(&self, elt: T) -> Result<Entry<'a, T>, T> {
608+
fn insert_after(&self, elt: T) -> Result<Arc<Node<T>>, T> {
600609
let new_node = Arc::new(Node::new(elt));
601610
new_node.set_prev_node(self.node);
602611

@@ -626,14 +635,11 @@ impl<'a, 'b, T> EntryImpl<'a, 'b, T> {
626635
drop(old_next_prev);
627636
drop(old_head_next);
628637

629-
Ok(Entry {
630-
list: self.list,
631-
node: new_node,
632-
})
638+
Ok(new_node)
633639
}
634640

635641
/// remove element after this entry
636-
fn remove_after(&self) -> Option<Entry<'a, T>> {
642+
fn remove_after(&self, list: &LinkedList<T>) -> Option<Arc<Node<T>>> {
637643
// move the drop out of locks
638644
let old_next_prev;
639645
let old_head_next;
@@ -644,7 +650,7 @@ impl<'a, 'b, T> EntryImpl<'a, 'b, T> {
644650
};
645651
{
646652
// there is no element after entry
647-
if Arc::ptr_eq(&curr_node, &self.list.tail) {
653+
if Arc::ptr_eq(&curr_node, &list.tail) {
648654
self.node.unlock();
649655
return None;
650656
}
@@ -665,14 +671,11 @@ impl<'a, 'b, T> EntryImpl<'a, 'b, T> {
665671
drop(old_next_prev);
666672
drop(old_head_next);
667673

668-
Some(Entry {
669-
list: self.list,
670-
node: curr_node,
671-
})
674+
Some(curr_node)
672675
}
673676

674677
/// Insert an element ahead of the entry, and returns the new Entry to it.
675-
pub fn insert_ahead(&self, elt: T) -> Result<Entry<'a, T>, T> {
678+
pub fn insert_ahead(&self, elt: T) -> Result<Arc<Node<T>>, T> {
676679
let new_node = Arc::new(Node::new(elt));
677680
new_node.next.write(self.node.clone());
678681

@@ -701,14 +704,11 @@ impl<'a, 'b, T> EntryImpl<'a, 'b, T> {
701704
drop(old_node_prev);
702705
drop(old_prev_next);
703706

704-
Ok(Entry {
705-
list: self.list,
706-
node: new_node,
707-
})
707+
Ok(new_node)
708708
}
709709

710710
/// Remove the element ahead of the entry, returns `None` if the list is empty.
711-
fn remove_ahead(&self) -> Option<Entry<'a, T>> {
711+
fn remove_ahead(&self, list: &LinkedList<T>) -> Option<Arc<Node<T>>> {
712712
loop {
713713
// move the drop out of locks
714714
let old_node_prev;
@@ -726,7 +726,7 @@ impl<'a, 'b, T> EntryImpl<'a, 'b, T> {
726726
};
727727

728728
// the list is empty
729-
if Arc::ptr_eq(&curr_node, &self.list.head) {
729+
if Arc::ptr_eq(&curr_node, &list.head) {
730730
return None;
731731
}
732732

@@ -758,10 +758,7 @@ impl<'a, 'b, T> EntryImpl<'a, 'b, T> {
758758
drop(old_node_prev);
759759
drop(old_prev_next);
760760

761-
return Some(Entry {
762-
list: self.list,
763-
node: curr_node,
764-
});
761+
return Some(curr_node);
765762
}
766763
}
767764
}

0 commit comments

Comments
 (0)