Skip to content

Commit d91970d

Browse files
committed
Fix minor SharedPtr/SharedRef issues, and add unit tests (#450)
* The `Default` trait did not actually get derived for `SharedPtr<T>`. This is solved by implementing `Default` manually. * Trait function `Shared::get()` used to return a mutable raw pointer (`*mut Self`), but it would be inconceivable to ever mutate the referenced value. It was changed to return a const pointer instead. * Added some basic unit tests for types `SharedPtr` and `SharedRef`.
1 parent b88f9f5 commit d91970d

File tree

2 files changed

+85
-4
lines changed

2 files changed

+85
-4
lines changed

src/array_buffer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ impl Shared for Allocator {
113113
)
114114
}
115115
}
116-
fn get(ptr: &SharedPtrBase<Self>) -> *mut Self {
116+
fn get(ptr: &SharedPtrBase<Self>) -> *const Self {
117117
unsafe { std__shared_ptr__v8__ArrayBuffer__Allocator__get(ptr) }
118118
}
119119
fn reset(ptr: &mut SharedPtrBase<Self>) {
@@ -219,7 +219,7 @@ impl Shared for BackingStore {
219219
std__shared_ptr__v8__BackingStore__CONVERT__std__unique_ptr(unique_ptr)
220220
}
221221
}
222-
fn get(ptr: &SharedPtrBase<Self>) -> *mut Self {
222+
fn get(ptr: &SharedPtrBase<Self>) -> *const Self {
223223
unsafe { std__shared_ptr__v8__BackingStore__get(ptr) }
224224
}
225225
fn reset(ptr: &mut SharedPtrBase<Self>) {

src/support.rs

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,15 @@ where
178178
{
179179
fn clone(shared_ptr: &SharedPtrBase<Self>) -> SharedPtrBase<Self>;
180180
fn from_unique_ptr(unique_ptr: UniquePtr<Self>) -> SharedPtrBase<Self>;
181-
fn get(shared_ptr: &SharedPtrBase<Self>) -> *mut Self;
181+
fn get(shared_ptr: &SharedPtrBase<Self>) -> *const Self;
182182
fn reset(shared_ptr: &mut SharedPtrBase<Self>);
183183
fn use_count(shared_ptr: &SharedPtrBase<Self>) -> long;
184184
}
185185

186186
/// Private base type which is shared by the `SharedPtr` and `SharedRef`
187187
/// implementations.
188188
#[repr(C)]
189+
#[derive(Eq, PartialEq)]
189190
pub struct SharedPtrBase<T: Shared>([usize; 2], PhantomData<T>);
190191

191192
unsafe impl<T: Shared + Sync> Send for SharedPtrBase<T> {}
@@ -205,7 +206,6 @@ impl<T: Shared> Drop for SharedPtrBase<T> {
205206

206207
/// Wrapper around a C++ shared_ptr. A shared_ptr may be be null.
207208
#[repr(C)]
208-
#[derive(Default)]
209209
pub struct SharedPtr<T: Shared>(SharedPtrBase<T>);
210210

211211
impl<T: Shared> SharedPtr<T> {
@@ -238,6 +238,12 @@ impl<T: Shared> Clone for SharedPtr<T> {
238238
}
239239
}
240240

241+
impl<T: Shared> Default for SharedPtr<T> {
242+
fn default() -> Self {
243+
Self(Default::default())
244+
}
245+
}
246+
241247
impl<T, U> From<U> for SharedPtr<T>
242248
where
243249
T: Shared,
@@ -625,26 +631,101 @@ where
625631
#[cfg(test)]
626632
mod tests {
627633
use super::*;
634+
use std::ptr::null;
628635
use std::sync::atomic::AtomicBool;
629636
use std::sync::atomic::Ordering;
630637

638+
#[derive(Eq, PartialEq)]
639+
struct MockSharedObj {
640+
pub inner: u32,
641+
}
642+
643+
impl MockSharedObj {
644+
const INSTANCE_A: Self = Self { inner: 11111 };
645+
const INSTANCE_B: Self = Self { inner: 22222 };
646+
647+
const SHARED_PTR_BASE_A: SharedPtrBase<Self> =
648+
SharedPtrBase([1, 1], PhantomData);
649+
const SHARED_PTR_BASE_B: SharedPtrBase<Self> =
650+
SharedPtrBase([2, 2], PhantomData);
651+
}
652+
653+
impl Shared for MockSharedObj {
654+
fn clone(_: &SharedPtrBase<Self>) -> SharedPtrBase<Self> {
655+
unimplemented!()
656+
}
657+
658+
fn from_unique_ptr(_: UniquePtr<Self>) -> SharedPtrBase<Self> {
659+
unimplemented!()
660+
}
661+
662+
fn get(p: &SharedPtrBase<Self>) -> *const Self {
663+
match p {
664+
&Self::SHARED_PTR_BASE_A => &Self::INSTANCE_A,
665+
&Self::SHARED_PTR_BASE_B => &Self::INSTANCE_B,
666+
p if p == &Default::default() => null(),
667+
_ => unreachable!(),
668+
}
669+
}
670+
671+
fn reset(p: &mut SharedPtrBase<Self>) {
672+
forget(take(p));
673+
}
674+
675+
fn use_count(_: &SharedPtrBase<Self>) -> long {
676+
unimplemented!()
677+
}
678+
}
679+
680+
#[test]
681+
fn shared_ptr_and_shared_ref() {
682+
let mut shared_ptr_a1 = SharedPtr(MockSharedObj::SHARED_PTR_BASE_A);
683+
assert!(!shared_ptr_a1.is_null());
684+
685+
let shared_ref_a: SharedRef<_> = shared_ptr_a1.take().unwrap();
686+
assert_eq!(shared_ref_a.inner, 11111);
687+
688+
assert!(shared_ptr_a1.is_null());
689+
690+
let shared_ptr_a2: SharedPtr<_> = shared_ref_a.into();
691+
assert!(!shared_ptr_a2.is_null());
692+
assert_eq!(shared_ptr_a2.unwrap().inner, 11111);
693+
694+
let mut shared_ptr_b1 = SharedPtr(MockSharedObj::SHARED_PTR_BASE_B);
695+
assert!(!shared_ptr_b1.is_null());
696+
697+
let shared_ref_b: SharedRef<_> = shared_ptr_b1.take().unwrap();
698+
assert_eq!(shared_ref_b.inner, 22222);
699+
700+
assert!(shared_ptr_b1.is_null());
701+
702+
let shared_ptr_b2: SharedPtr<_> = shared_ref_b.into();
703+
assert!(!shared_ptr_b2.is_null());
704+
assert_eq!(shared_ptr_b2.unwrap().inner, 22222);
705+
}
706+
631707
static TEST_OBJ_DROPPED: AtomicBool = AtomicBool::new(false);
708+
632709
struct TestObj {
633710
pub id: u32,
634711
}
712+
635713
impl Drop for TestObj {
636714
fn drop(&mut self) {
637715
assert!(!TEST_OBJ_DROPPED.swap(true, Ordering::SeqCst));
638716
}
639717
}
640718

641719
struct TestObjRef(TestObj);
720+
642721
impl Deref for TestObjRef {
643722
type Target = TestObj;
723+
644724
fn deref(&self) -> &TestObj {
645725
&self.0
646726
}
647727
}
728+
648729
impl Borrow<TestObj> for TestObjRef {
649730
fn borrow(&self) -> &TestObj {
650731
&**self

0 commit comments

Comments
 (0)