1

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!

1
  • 2
    Note that you should use UnsafeCell<libc::sem_t>, otherwise your code is unsound on 64-bit systems. Commented Apr 19, 2022 at 11:07

1 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.