#include <x/mutex.H> #include <x/mlock.H> x::mutex m{x::mutex::create()}; // ... { x::mlock lock=m->lock(); // ... }
x::mutex
is a
reference-counted
object with similar semantics as
std::mutex
.
Its lock
() method returns a
x::mlock
, which itself a
reference on a reference-counted object. Only one lock object may exist
at a time.
The mutex gets unlocked when the last reference to the lock object
goes out of scope and gets destroyed.
x::mutex
and
x::mlock
are references to
reference-counted objects; as such,
for example, a lock can get acquired by one thread, and passed around.
Whichever thread holds the last reference to the lock unlocks the mutex
when it goes out of scope and gets destroyed. The
std::mutex
limitations, that the mutex must be
unlocked by the same thread that locked it, do not apply here.
If a lock object already exists, lock
() waits until
the existing lock object goes out of scope.
Following the usual convention for reference-counted objects,
x::mutexptr
is a typedef for a nullable pointer reference to a mutex, and
x::mlockptr
is a nullable
pointer reference to a lock object:
x::mlockptr lock=m->trylock(); if (lock.null()) // ...
trylock
() does not wait until an existing lock
object goes out of scope. If one exists, a null pointer reference gets
returned instead of constructing a lock.
There's also an overloaded wait_until
() that takes
a time point that sets the wait expiration.
If a lock is not immediately available, it gets waited for until
the specified time point. A null pointer reference gets returned also,
instead of a lock object reference:
#include <x/mutex.H> #include <chrono> x::mutex m=x::mutex::create(); x::mlockptr p= m->wait_until(std::chrono::monotonic_clock::now() + std::chrono::milliseconds(500)); if (!p.null()) // ...
This example waits half a second for the lock to be acquired, before giving up.