sendify/
sendify_mut.rs

1/// Wraps a mutable reference to make it [`Send`](https://doc.rust-lang.org/nightly/core/marker/trait.Send.html) + [`Sync`](https://doc.rust-lang.org/nightly/core/marker/trait.Sync.html).
2pub struct SendifyMut<T> {
3    ptr: *mut T,
4}
5
6impl<T> SendifyMut<T> {
7    /// Wraps a mutable reference to make it [`Send`](https://doc.rust-lang.org/nightly/core/marker/trait.Send.html) + [`Sync`](https://doc.rust-lang.org/nightly/core/marker/trait.Sync.html).
8    pub fn wrap(val: &mut T) -> SendifyMut<T> {
9        SendifyMut { ptr: val }
10    }
11
12    /// Unwraps the mutable reference. Make sure the reference is still valid while unwrapping it.
13    pub unsafe fn unwrap<'a>(self) -> &'a mut T {
14        self.ptr.as_mut().unwrap()
15    }
16}
17
18unsafe impl<T: Send + 'static> Send for SendifyMut<T> {}
19unsafe impl<T: Sync + 'static> Sync for SendifyMut<T> {}
20
21#[cfg(test)]
22mod tests {
23    use super::*;
24    use std::thread;
25
26    #[test]
27    fn test_sendify_mut() {
28        let mut data = "my string".to_owned();
29
30        let ref_val = &mut data;
31        let sendify_val = SendifyMut::wrap(ref_val);
32
33        thread::spawn(move || {
34            let ref_val = unsafe { sendify_val.unwrap() };
35            ref_val.push_str(" and more");
36            assert_eq!(ref_val, "my string and more")
37        })
38        .join()
39        .unwrap();
40
41        assert_eq!(data, "my string and more")
42    }
43}