38#include <snapdev/timespec_ex.h>
49#include <snapdev/poison.h>
75 pthread_mutex_t
f_mutex = pthread_mutex_t();
230 : f_impl(std::make_shared<detail::mutex_impl>())
233 pthread_mutexattr_t mattr;
234 int err(pthread_mutexattr_init(&mattr));
237 log << log_level_t::fatal
238 <<
"a mutex attribute structure could not be initialized, error #"
241 throw invalid_error(
"pthread_muteattr_init() failed");
243 err = pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
246 log << log_level_t::fatal
247 <<
"a mutex attribute structure type could not be setup, error #"
250 pthread_mutexattr_destroy(&mattr);
251 throw invalid_error(
"pthread_muteattr_settype() failed");
253 err = pthread_mutex_init(&
f_impl->f_mutex, &mattr);
256 log << log_level_t::fatal
257 <<
"a mutex structure could not be initialized, error #"
260 pthread_mutexattr_destroy(&mattr);
261 throw invalid_error(
"pthread_mutex_init() failed");
263 err = pthread_mutexattr_destroy(&mattr);
266 log << log_level_t::fatal
267 <<
"a mutex attribute structure could not be destroyed, error #"
270 pthread_mutex_destroy(&
f_impl->f_mutex);
271 throw invalid_error(
"pthread_mutexattr_destroy() failed");
275 pthread_condattr_t cattr;
276 err = pthread_condattr_init(&cattr);
279 log << log_level_t::fatal
280 <<
"a mutex condition attribute structure could not be initialized, error #"
283 pthread_mutex_destroy(&
f_impl->f_mutex);
284 throw invalid_error(
"pthread_condattr_init() failed");
286 err = pthread_cond_init(&
f_impl->f_condition, &cattr);
289 log << log_level_t::fatal
290 <<
"a mutex condition structure could not be initialized, error #"
293 pthread_condattr_destroy(&cattr);
294 pthread_mutex_destroy(&
f_impl->f_mutex);
295 throw invalid_error(
"pthread_cond_init() failed");
297 err = pthread_condattr_destroy(&cattr);
300 log << log_level_t::fatal
301 <<
"a mutex condition attribute structure could not be destroyed, error #"
304 pthread_mutex_destroy(&
f_impl->f_mutex);
305 throw invalid_error(
"pthread_condattr_destroy() failed");
330 log << log_level_t::fatal
331 <<
"a mutex is being destroyed when its reference count is "
333 <<
" instead of zero."
337 int err(pthread_cond_destroy(&
f_impl->f_condition));
340 log << log_level_t::error
341 <<
"a mutex condition destruction generated error #"
345 err = pthread_mutex_destroy(&
f_impl->f_mutex);
348 log << log_level_t::fatal
349 <<
"a mutex destruction generated error #"
371 int const err(pthread_mutex_lock(&
f_impl->f_mutex));
374 log << log_level_t::error
375 <<
"a mutex lock generated error #"
380 throw invalid_error(
"pthread_mutex_lock() failed");
402 int const err(pthread_mutex_trylock(&
f_impl->f_mutex));
418 log << log_level_t::error
419 <<
"a mutex try lock generated error #"
424 throw invalid_error(
"pthread_mutex_trylock() failed");
448 log << log_level_t::fatal
449 <<
"attempting to unlock a mutex when it is still locked "
453 throw not_locked_error(
"unlock was called too many times");
460 int const err(pthread_mutex_unlock(&
f_impl->f_mutex));
463 log << log_level_t::fatal
464 <<
"a mutex unlock generated error #"
469 throw invalid_error(
"pthread_mutex_unlock() failed");
511 int const err(pthread_cond_wait(&
f_impl->f_condition, &
f_impl->f_mutex));
515 log << log_level_t::fatal
516 <<
"a mutex conditional wait generated error #"
521 throw mutex_failed_error(
"pthread_cond_wait() failed");
552 static_cast<time_t
>(usecs / 1'000'000ULL)
553 ,
static_cast<long>((usecs % 1'000'000ULL) * 1'000ULL)
589 snapdev::timespec_ex abstime(snapdev::timespec_ex::gettime());
595 err = pthread_cond_timedwait(
607 log << log_level_t::fatal
608 <<
"a mutex conditional timed wait generated error #"
612 <<
" (time out sec = "
618 throw mutex_failed_error(
"pthread_cond_timedwait() failed");
645 static_cast<long>(usec / 1'000'000ULL)
646 ,
static_cast<long>((usec % 1'000'000ULL) * 1'000ULL)
688 int const err(pthread_cond_timedwait(
700 log << log_level_t::error
701 <<
"a mutex conditional wait generated error #"
705 <<
" (time out sec = "
711 throw mutex_failed_error(
"pthread_cond_timedwait() failed");
739 int const err(pthread_cond_signal(&
f_impl->f_condition));
742 log << log_level_t::fatal
743 <<
"a mutex condition signal generated error #"
746 throw invalid_error(
"pthread_cond_signal() failed");
769 int const err(pthread_cond_signal(&
f_impl->f_condition));
772 log << log_level_t::fatal
773 <<
"a mutex condition signal generated error #"
776 throw invalid_error(
"pthread_cond_signal() failed");
803 int const err(pthread_cond_broadcast(&
f_impl->f_condition));
806 log << log_level_t::fatal
807 <<
"a mutex signal broadcast generated error #"
810 throw invalid_error(
"pthread_cond_broadcast() failed");
842 int const err(pthread_cond_broadcast(&
f_impl->f_condition));
845 log << log_level_t::fatal
846 <<
"a mutex signal broadcast generated error #"
849 throw invalid_error(
"pthread_cond_broadcast() failed");
930 std::cerr <<
"fatal: create_system_mutex() called twice." << std::endl;
The implementation of the mutex.
pthread_cond_t f_condition
Condition linked to the mutex to support signalling.
pthread_mutex_t f_mutex
Mutex to support guards & signals.
Lock a mutex in an RAII manner.
A mutex object to ensures atomicity.
bool dated_wait(std::uint64_t const date)
Wait on a mutex until the specified date.
bool timed_wait(std::uint64_t const usec)
Wait on a mutex condition with a time limit.
void wait()
Wait on a mutex condition.
void safe_signal()
Signal a mutex.
mutex()
An inter-thread mutex to ensure unicity of execution.
void unlock()
Unlock a mutex.
void signal()
Signal at least one mutex.
std::shared_ptr< detail::mutex_impl > f_impl
The pthread mutex implementation.
std::uint32_t f_reference_count
The lock reference count.
void broadcast()
Broadcast a mutex signal.
void safe_broadcast()
Broadcast a mutex signal.
bool try_lock()
Try locking the mutex.
~mutex()
Clean up a mutex object.
Exceptions for the thread environment.
Thread Runner and Managers.
void create_system_mutex()
Function used to initialize the system mutex.
logger log
The logger object used to send logs out.
Declaration of the log class used to send error messages.
logger & end(logger &l)
Close a log statement.
mutex * g_system_mutex
The system mutex.
Thread Runner and Managers.