Skip to content

Commit d7f70a7

Browse files
authored
Use MBox<T> to manage lifetimes of tskit C structs. (#203)
Closes #194
1 parent 034204e commit d7f70a7

File tree

5 files changed

+114
-108
lines changed

5 files changed

+114
-108
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ serde = {version = "1.0.118", features = ["derive"], optional = true}
2525
serde_json = {version = "1.0.67", optional = true}
2626
bincode = {version = "1.3.1", optional = true}
2727
tskit-derive = {version = "0.2.0", path = "tskit-derive", optional = true}
28+
mbox = "0.6.0"
2829

2930
[dev-dependencies]
3031
clap = "~2.34.0"

src/_macros.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,6 @@ macro_rules! drop_for_tskit_type {
132132
fn drop(&mut self) {
133133
let rv = unsafe { $drop(&mut *self.inner) };
134134
panic_on_tskit_error!(rv);
135-
unsafe {
136-
libc::free(self.inner as *mut libc::c_void);
137-
}
138-
self.inner = std::ptr::null_mut();
139135
}
140136
}
141137
};
@@ -145,11 +141,11 @@ macro_rules! tskit_type_access {
145141
($name: ident, $ll_name: ty) => {
146142
impl $crate::TskitTypeAccess<$ll_name> for $name {
147143
fn as_ptr(&self) -> *const $ll_name {
148-
self.inner
144+
&*self.inner
149145
}
150146

151147
fn as_mut_ptr(&mut self) -> *mut $ll_name {
152-
self.inner
148+
&mut *self.inner
153149
}
154150
}
155151
};
@@ -159,12 +155,15 @@ macro_rules! build_tskit_type {
159155
($name: ident, $ll_name: ty, $drop: ident) => {
160156
impl $crate::ffi::WrapTskitType<$ll_name> for $name {
161157
fn wrap() -> Self {
158+
use mbox::MBox;
162159
let temp =
163160
unsafe { libc::malloc(std::mem::size_of::<$ll_name>()) as *mut $ll_name };
164-
if temp.is_null() {
165-
panic!("out of memory");
166-
}
167-
$name { inner: temp }
161+
let nonnull = match std::ptr::NonNull::<$ll_name>::new(temp) {
162+
Some(x) => x,
163+
None => panic!("out of memory"),
164+
};
165+
let mbox = unsafe { MBox::from_non_null_raw(nonnull) };
166+
$name { inner: mbox }
168167
}
169168
}
170169
drop_for_tskit_type!($name, $drop);

src/ffi.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ mod tests {
2323
use crate::bindings as ll_bindings;
2424
use crate::TskitTypeAccess;
2525
use ll_bindings::tsk_table_collection_free;
26+
use mbox::MBox;
2627

2728
pub struct TableCollectionMock {
28-
inner: *mut ll_bindings::tsk_table_collection_t,
29+
inner: MBox<ll_bindings::tsk_table_collection_t>,
2930
}
3031

3132
build_tskit_type!(
@@ -41,15 +42,13 @@ mod tests {
4142
let rv = unsafe { ll_bindings::tsk_table_collection_init(s.as_mut_ptr(), 0) };
4243
assert_eq!(rv, 0);
4344

44-
unsafe {
45-
(*s.inner).sequence_length = len;
46-
}
45+
(*s.inner).sequence_length = len;
4746

4847
s
4948
}
5049

5150
fn sequence_length(&self) -> f64 {
52-
unsafe { (*self.inner).sequence_length }
51+
(*self.inner).sequence_length
5352
}
5453
}
5554

0 commit comments

Comments
 (0)