|
@@ -15,6 +15,8 @@
|
|
|
#ifndef B10_THREAD_SYNC_H
|
|
|
#define B10_THREAD_SYNC_H
|
|
|
|
|
|
+#include <exceptions/exceptions.h>
|
|
|
+
|
|
|
#include <boost/noncopyable.hpp>
|
|
|
|
|
|
#include <cstdlib> // for NULL.
|
|
@@ -77,17 +79,34 @@ public:
|
|
|
/// of function no matter by what means.
|
|
|
class Locker : boost::noncopyable {
|
|
|
public:
|
|
|
+ /// \brief Exception thrown when the mutex is already locked and
|
|
|
+ /// a non-blocking locker is attempted around it.
|
|
|
+ struct AlreadyLocked : public isc::InvalidParameter {
|
|
|
+ AlreadyLocked(const char* file, size_t line, const char* what) :
|
|
|
+ isc::InvalidParameter(file, line, what)
|
|
|
+ {}
|
|
|
+ };
|
|
|
+
|
|
|
/// \brief Constructor.
|
|
|
///
|
|
|
- /// Locks the mutex. May block for extended period of time.
|
|
|
+ /// Locks the mutex. May block for extended period of time if
|
|
|
+ /// \c block is true.
|
|
|
///
|
|
|
/// \throw isc::InvalidOperation when OS reports error. This usually
|
|
|
/// means an attempt to use the mutex in a wrong way (locking
|
|
|
/// a mutex second time from the same thread, for example).
|
|
|
- Locker(Mutex& mutex) :
|
|
|
+ /// \throw AlreadyLocked if \c block is false and the mutex is
|
|
|
+ /// already locked.
|
|
|
+ Locker(Mutex& mutex, bool block = true) :
|
|
|
mutex_(mutex)
|
|
|
{
|
|
|
- mutex.lock();
|
|
|
+ if (block) {
|
|
|
+ mutex.lock();
|
|
|
+ } else {
|
|
|
+ if (!mutex.tryLock()) {
|
|
|
+ isc_throw(AlreadyLocked, "The mutex is already locked");
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// \brief Destructor.
|
|
@@ -107,6 +126,24 @@ public:
|
|
|
///
|
|
|
/// \todo Disable in non-debug build
|
|
|
bool locked() const;
|
|
|
+
|
|
|
+private:
|
|
|
+ /// \brief Lock the mutex
|
|
|
+ ///
|
|
|
+ /// This method blocks until the mutex can be locked.
|
|
|
+ void lock();
|
|
|
+
|
|
|
+ /// \brief Try to lock the mutex
|
|
|
+ ///
|
|
|
+ /// This method doesn't block and returns immediately with a status
|
|
|
+ /// on whether the lock operation was successful.
|
|
|
+ ///
|
|
|
+ /// \return true if the lock was successful, false otherwise.
|
|
|
+ bool tryLock();
|
|
|
+
|
|
|
+ /// \brief Unlock the mutex
|
|
|
+ void unlock();
|
|
|
+
|
|
|
private:
|
|
|
friend class CondVar;
|
|
|
|
|
@@ -131,8 +168,6 @@ private:
|
|
|
|
|
|
class Impl;
|
|
|
Impl* impl_;
|
|
|
- void lock();
|
|
|
- void unlock();
|
|
|
};
|
|
|
|
|
|
/// \brief Encapsulation for a condition variable.
|