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!
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.