Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export low-level common interfaces for mutex, condvar, etc. #68163

Open
avieth opened this issue Jan 12, 2020 · 7 comments
Open

Export low-level common interfaces for mutex, condvar, etc. #68163

avieth opened this issue Jan 12, 2020 · 7 comments
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@avieth
Copy link

avieth commented Jan 12, 2020

I'd like to work directly with std::sys_common mutex and condvar types. Is there any way to do this short of a custom rustc build with a modified standard library?

@csmoe csmoe added C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jan 13, 2020
@jonas-schievink
Copy link
Contributor

What's your use case for this? These APIs might be replaced in the future, and libstd might stop using OS primitives for this completely.

@avieth
Copy link
Author

avieth commented Jan 13, 2020

What's your use case for this?

The std::sync::Mutex is good about ensuring every lock is also unlocked. But I'm interested in making an abstraction which ensures the programmer can never double-lock (but could of course forget to unlock). The idea is that locking the mutex takes ownership of the mutex, rather than a reference to it, and the only way to get the mutex back is to unlock that thing. Something like

// Just like the std::sync:Mutex.
struct Mutex<T> {
  sys_mutex: ...,
  cell: UnsafeCell<T>
}

impl<T> Mutex<T> {
  pub fn lock(self) -> Locked<T> {
    // do actual low-level OS mutex lock
    self.sys_mutex.lock();
    return Locked { locked_mutex: self };
  }
}

struct Locked<T> {
  locked_mutex: Mutex<T>
}

impl<T> Locked<T> {
  pub fn unlock(self) -> Mutex<T> {
    // Do low-level OS mutex unlock
    self.locked_mutex.sys_mutex.unlock();
    return self.locked_mutex;
  }
}

impl<T> Deref for Locked<T> { ... }
impl<T> DerefMut for Locked<T> { ... }

Of course it's possible I just don't know how to do what I want. I found that, with the std interface, because the MutexGuard has a reference to the Mutex, it's impossible create the abstraction that I want; the programmer can always keep the Mutex around after calling lock(); I can't move it to the same struct as the guard.

@jonas-schievink
Copy link
Contributor

It sounds like what you want is an interface for raw (non-guard) locking/unlocking of the mutex. This sounds more reasonable to expose than sys_common, and should just be 2-3 functions (or 1, if you're fine with leaking a MutexGuard).

@avieth
Copy link
Author

avieth commented Jan 13, 2020

Sure, it doesn't have to be the sys_common interface. Something with lock, try_lock, and unlock, where locking doesn't make a MutexGuard, would be enough I think. But then, I'd also want to use Condvars, but those require a MutexGuard.

@sfackler
Copy link
Member

How would you ever be able to call Mutex::lock when you don't have unique access to the Mutex?

@avieth
Copy link
Author

avieth commented Jan 13, 2020

How would you ever be able to call Mutex::lock when you don't have unique access to the Mutex?

I only posted a rough sketch of an implementation. Really I'd want to wrap the whole thing in an Arc so it can be cloned and moved to other threads, then use an unsafe raw pointer dereference of Arc::into_raw, casting to the underlying mutex type. I think this would all be safe.

Then when unlocking, Arc::from_raw would be used to get back to the original mutex type on which lock was called.

But then, with that setup you can still double-lock, by cloning it again in the same thread and locking that thing. Hm...

@sfackler
Copy link
Member

You can base your API off of parking_lot's RawMutex etc to avoid blocking on this request, BTW.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants