sl@0: // Copyright (C) 2001-2003 sl@0: // William E. Kempf sl@0: // sl@0: // Distributed under the Boost Software License, Version 1.0. (See accompanying sl@0: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) sl@0: sl@0: #ifndef BOOST_XLOCK_WEK070601_HPP sl@0: #define BOOST_XLOCK_WEK070601_HPP sl@0: sl@0: #include sl@0: sl@0: #include sl@0: #include sl@0: sl@0: namespace boost { sl@0: sl@0: class condition; sl@0: struct xtime; sl@0: sl@0: namespace detail { namespace thread { sl@0: sl@0: template sl@0: class lock_ops : private noncopyable sl@0: { sl@0: private: sl@0: lock_ops() { } sl@0: sl@0: public: sl@0: typedef typename Mutex::cv_state lock_state; sl@0: sl@0: static void lock(Mutex& m) sl@0: { sl@0: m.do_lock(); sl@0: } sl@0: static bool trylock(Mutex& m) sl@0: { sl@0: return m.do_trylock(); sl@0: } sl@0: static bool timedlock(Mutex& m, const xtime& xt) sl@0: { sl@0: return m.do_timedlock(xt); sl@0: } sl@0: static void unlock(Mutex& m) sl@0: { sl@0: m.do_unlock(); sl@0: } sl@0: static void lock(Mutex& m, lock_state& state) sl@0: { sl@0: m.do_lock(state); sl@0: } sl@0: static void unlock(Mutex& m, lock_state& state) sl@0: { sl@0: m.do_unlock(state); sl@0: } sl@0: }; sl@0: sl@0: template sl@0: class scoped_lock : private noncopyable sl@0: { sl@0: public: sl@0: typedef Mutex mutex_type; sl@0: sl@0: explicit scoped_lock(Mutex& mx, bool initially_locked=true) sl@0: : m_mutex(mx), m_locked(false) sl@0: { sl@0: if (initially_locked) lock(); sl@0: } sl@0: ~scoped_lock() sl@0: { sl@0: if (m_locked) unlock(); sl@0: } sl@0: sl@0: void lock() sl@0: { sl@0: if (m_locked) throw lock_error(); sl@0: lock_ops::lock(m_mutex); sl@0: m_locked = true; sl@0: } sl@0: void unlock() sl@0: { sl@0: if (!m_locked) throw lock_error(); sl@0: lock_ops::unlock(m_mutex); sl@0: m_locked = false; sl@0: } sl@0: sl@0: bool locked() const { return m_locked; } sl@0: operator const void*() const { return m_locked ? this : 0; } sl@0: sl@0: private: sl@0: friend class boost::condition; sl@0: sl@0: Mutex& m_mutex; sl@0: bool m_locked; sl@0: }; sl@0: sl@0: template sl@0: class scoped_try_lock : private noncopyable sl@0: { sl@0: public: sl@0: typedef TryMutex mutex_type; sl@0: sl@0: explicit scoped_try_lock(TryMutex& mx) sl@0: : m_mutex(mx), m_locked(false) sl@0: { sl@0: try_lock(); sl@0: } sl@0: scoped_try_lock(TryMutex& mx, bool initially_locked) sl@0: : m_mutex(mx), m_locked(false) sl@0: { sl@0: if (initially_locked) lock(); sl@0: } sl@0: ~scoped_try_lock() sl@0: { sl@0: if (m_locked) unlock(); sl@0: } sl@0: sl@0: void lock() sl@0: { sl@0: if (m_locked) throw lock_error(); sl@0: lock_ops::lock(m_mutex); sl@0: m_locked = true; sl@0: } sl@0: bool try_lock() sl@0: { sl@0: if (m_locked) throw lock_error(); sl@0: return (m_locked = lock_ops::trylock(m_mutex)); sl@0: } sl@0: void unlock() sl@0: { sl@0: if (!m_locked) throw lock_error(); sl@0: lock_ops::unlock(m_mutex); sl@0: m_locked = false; sl@0: } sl@0: sl@0: bool locked() const { return m_locked; } sl@0: operator const void*() const { return m_locked ? this : 0; } sl@0: sl@0: private: sl@0: friend class boost::condition; sl@0: sl@0: TryMutex& m_mutex; sl@0: bool m_locked; sl@0: }; sl@0: sl@0: template sl@0: class scoped_timed_lock : private noncopyable sl@0: { sl@0: public: sl@0: typedef TimedMutex mutex_type; sl@0: sl@0: scoped_timed_lock(TimedMutex& mx, const xtime& xt) sl@0: : m_mutex(mx), m_locked(false) sl@0: { sl@0: timed_lock(xt); sl@0: } sl@0: scoped_timed_lock(TimedMutex& mx, bool initially_locked) sl@0: : m_mutex(mx), m_locked(false) sl@0: { sl@0: if (initially_locked) lock(); sl@0: } sl@0: ~scoped_timed_lock() sl@0: { sl@0: if (m_locked) unlock(); sl@0: } sl@0: sl@0: void lock() sl@0: { sl@0: if (m_locked) throw lock_error(); sl@0: lock_ops::lock(m_mutex); sl@0: m_locked = true; sl@0: } sl@0: bool try_lock() sl@0: { sl@0: if (m_locked) throw lock_error(); sl@0: return (m_locked = lock_ops::trylock(m_mutex)); sl@0: } sl@0: bool timed_lock(const xtime& xt) sl@0: { sl@0: if (m_locked) throw lock_error(); sl@0: return (m_locked = lock_ops::timedlock(m_mutex, xt)); sl@0: } sl@0: void unlock() sl@0: { sl@0: if (!m_locked) throw lock_error(); sl@0: lock_ops::unlock(m_mutex); sl@0: m_locked = false; sl@0: } sl@0: sl@0: bool locked() const { return m_locked; } sl@0: operator const void*() const { return m_locked ? this : 0; } sl@0: sl@0: private: sl@0: friend class boost::condition; sl@0: sl@0: TimedMutex& m_mutex; sl@0: bool m_locked; sl@0: }; sl@0: sl@0: } // namespace thread sl@0: } // namespace detail sl@0: } // namespace boost sl@0: sl@0: #endif // BOOST_XLOCK_WEK070601_HPP sl@0: sl@0: // Change Log: sl@0: // 8 Feb 01 WEKEMPF Initial version. sl@0: // 22 May 01 WEKEMPF Modified to use xtime for time outs. sl@0: // 30 Jul 01 WEKEMPF Moved lock types into boost::detail::thread. Renamed sl@0: // some types. Added locked() methods.