rustunsafe-pointers

How to safely get two mutable pointers to same int?


I would like to create a Rust semaphore wrapping the libc sem_post and sem_wait functions, both of which take a mutable int * parameter. This requires that the waiter and poster simultaneously have a mutable pointer to the same int. How can I arrange this without risking UB?

One thought I had was to use UnsafeCell:

use libc;
use std::cell::UnsafeCell;

pub struct Sema {
    sema: UnsafeCell<i32>,
}

impl Sema {
    pub fn post(&self) {
        unsafe { libc::sem_post(self.sema.get()) };
    }

    pub fn wait(&self) {
        unsafe { libc::sem_wait(self.sema.get()) };
    }
}

Is this safe, and is there a better way? Thanks for any help!


Solution

  • Raw pointers, the *mut T or *const T types, have no aliasing requirements or other validity constraints. It is always safe to create a pointer; note that UnsafeCell::get() is not an unsafe fn.

    And in this case, by using UnsafeCell you've also ensured that Rust has no expectations that would be violated by using the pointer with libc. (This would not be the case if you had sema: i32, for example.)

    I'm not going to say that your semaphore code is sound or correct, because I'm not familiar with these functions, but I feel confident saying it isn't misusing Rust pointer types.