📄 process_mutex.hpp
字号:
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
if(EBUSY != m_error)
{
STLSOFT_THROW_X(synchronisation_exception("Mutex try-lock failed", m_error));
}
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
return false;
}
}
/// \brief Releases an aquired lock on the mutex
///
/// \exception unixstl::synchronisation_exception When compiling with exception support, this will throw
/// unixstl::synchronisation_exception if the lock cannot be released. When
/// compiling absent exception support, failure to release the lock
/// will be reflected in a non-zero return from get_error().
void unlock()
{
m_error = ::pthread_mutex_unlock(m_mx);
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
if(0 != m_error)
{
STLSOFT_THROW_X(synchronisation_exception("Mutex unlock failed", m_error));
}
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
/// \brief Contains the last failed error code from the underlying PTHREADS API
int get_error() const stlsoft_throw_0()
{
return m_error;
}
/// @}
/// \name Accessors
/// @{
public:
/// \brief The underlying kernel object handle
pthread_mutex_t* handle() stlsoft_throw_0()
{
return m_mx;
}
/// \brief The underlying kernel object handle
pthread_mutex_t* get() stlsoft_throw_0()
{
return m_mx;
}
/// @}
/// \name Implementation
/// @{
private:
static int create_(pthread_mutex_t* mx, int pshared, bool_type bRecursive)
{
pthread_mutexattr_t attr;
int res = 0;
if(0 == (res = ::pthread_mutexattr_init(&attr)))
{
stlsoft::scoped_handle<pthread_mutexattr_t*> attr_(&attr, ::pthread_mutexattr_destroy);
if( !bRecursive ||
0 == (res = ::pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)))
{
#if defined(_POSIX_THREAD_PROCESS_SHARED)
if(0 != (res = ::pthread_mutexattr_setpshared(&attr, pshared)))
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
STLSOFT_THROW_X(synchronisation_exception("Failed to set process-sharing attribute for PTHREADS mutex", res));
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
else
#else /* ? _POSIX_THREAD_PROCESS_SHARED */
STLSOFT_SUPPRESS_UNUSED(pshared);
#endif /* _POSIX_THREAD_PROCESS_SHARED */
{
if(0 == (res = ::pthread_mutex_init(mx, &attr)))
{
}
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
else
{
STLSOFT_THROW_X(synchronisation_exception("Failed to set initialise PTHREADS mutex", res));
}
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
}
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
else
{
STLSOFT_THROW_X(synchronisation_exception("Failed to set recursive attribute to PTHREADS mutex", res));
}
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
else
{
STLSOFT_THROW_X(synchronisation_exception("Failed to initialise PTHREADS mutex attributes", res));
}
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
return res;
}
/// @}
/// \name Members
/// @{
private:
pthread_mutex_t m_mx_; // The mutex used when created and owned by the instance
pthread_mutex_t* const m_mx; // The mutex "handle"
int m_error; // The last PThreads error
const bool_type m_bOwnHandle; // Does the instance own the handle?
/// @}
/// \name Not to be implemented
/// @{
private:
process_mutex(class_type const& rhs);
process_mutex& operator =(class_type const& rhs);
/// @}
};
/* /////////////////////////////////////////////////////////////////////////
* Control shims
*/
#ifndef _UNIXSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace unixstl
# else
} // namespace unixstl_project
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_UNIXSTL_NO_NAMESPACE */
/** \brief This \ref group__concept__shims "control shim" aquires a lock on the given mutex
*
* \ingroup group__concept__shim__synchronisation_control
*
* \param mx The mutex on which to aquire the lock.
*/
inline void lock_instance(unixstl_ns_qual(process_mutex) &mx)
{
mx.lock();
}
/** \brief This \ref group__concept__shims "control shim" releases a lock on the given mutex
*
* \ingroup group__concept__shim__synchronisation_control
*
* \param mx The mutex on which to release the lock
*/
inline void unlock_instance(unixstl_ns_qual(process_mutex) &mx)
{
mx.unlock();
}
#ifndef _UNIXSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
namespace unixstl
{
# else /* ? _STLSOFT_NO_NAMESPACE */
namespace unixstl_project
{
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_UNIXSTL_NO_NAMESPACE */
/* /////////////////////////////////////////////////////////////////////////
* lock_traits
*/
// class lock_traits
/** \brief Traits for the process_mutex class
*
* \ingroup group__library__synch
*/
struct process_mutex_lock_traits
{
public:
/// The lockable type
typedef process_mutex lock_type;
typedef process_mutex_lock_traits class_type;
// Operations
public:
/// Lock the given process_mutex instance
static void lock(process_mutex &c)
{
#if defined(STLSOFT_COMPILER_IS_BORLAND)
// Borland requires that we explicitly qualify the shim functions, even
// though they're defined in the enclosing namespace of this one.
stlsoft_ns_qual(lock_instance)(c);
#else /* ? compiler */
lock_instance(c);
#endif /* compiler */
}
/// Unlock the given process_mutex instance
static void unlock(process_mutex &c)
{
#if defined(STLSOFT_COMPILER_IS_BORLAND)
// Borland requires that we explicitly qualify the shim functions, even
// though they're defined in the enclosing namespace of this one.
stlsoft_ns_qual(unlock_instance)(c);
#else /* ? compiler */
unlock_instance(c);
#endif /* compiler */
}
};
////////////////////////////////////////////////////////////////////////////
// Unit-testing
#ifdef STLSOFT_UNITTEST
# include "./unittest/process_mutex_unittest_.h"
#endif /* STLSOFT_UNITTEST */
/* ////////////////////////////////////////////////////////////////////// */
#ifndef _UNIXSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace unixstl
# else
} // namespace unixstl_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_UNIXSTL_NO_NAMESPACE */
/* ////////////////////////////////////////////////////////////////////// */
#endif /* !UNIXSTL_INCL_UNIXSTL_SYNCH_HPP_PROCESS_MUTEX */
/* ////////////////////////////////////////////////////////////////////// */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -