From c9f52098b965eb5345a02b5444ba7a0cd42e92e1 Mon Sep 17 00:00:00 2001 From: "William E. Kempf" Date: Sat, 22 Mar 2003 22:28:57 +0000 Subject: [PATCH] More changes for named mutexes. [SVN r18063] --- include/boost/thread/detail/named.hpp | 12 +- include/boost/thread/mutex.hpp | 9 +- src/mutex.cpp | 170 ++++++++++++++------------ src/named.cpp | 79 +++++++----- 4 files changed, 148 insertions(+), 122 deletions(-) diff --git a/include/boost/thread/detail/named.hpp b/include/boost/thread/detail/named.hpp index c8642442..6c6573fe 100644 --- a/include/boost/thread/detail/named.hpp +++ b/include/boost/thread/detail/named.hpp @@ -12,24 +12,22 @@ #ifndef BOOST_NAMED_WEK031703_HPP #define BOOST_NAMED_WEK031703_HPP -#include - namespace boost { namespace detail { class named_object { protected: - named_object(); - named_object(const char* name); + named_object(const char* name=0); ~named_object(); public: - std::string name() const; - std::string effective_name() const; + const char* name() const; + const char* effective_name() const; protected: - std::string m_name; + char* m_name; + char* m_ename; }; } // namespace detail diff --git a/include/boost/thread/mutex.hpp b/include/boost/thread/mutex.hpp index b9b1b300..e3b6ba5b 100644 --- a/include/boost/thread/mutex.hpp +++ b/include/boost/thread/mutex.hpp @@ -42,8 +42,7 @@ public: typedef detail::thread::scoped_lock scoped_lock; - mutex(); - mutex(const char* name); + mutex(const char* name=0); ~mutex(); private: @@ -84,8 +83,7 @@ public: typedef detail::thread::scoped_lock scoped_lock; typedef detail::thread::scoped_try_lock scoped_try_lock; - try_mutex(); - try_mutex(const char* name); + try_mutex(const char* name=0); ~try_mutex(); private: @@ -128,8 +126,7 @@ public: typedef detail::thread::scoped_try_lock scoped_try_lock; typedef detail::thread::scoped_timed_lock scoped_timed_lock; - timed_mutex(); - timed_mutex(const char* name); + timed_mutex(const char* name=0); ~timed_mutex(); private: diff --git a/src/mutex.cpp b/src/mutex.cpp index 0f93949e..d5ddc4dd 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -34,12 +34,45 @@ namespace { #if defined(BOOST_HAS_WINTHREADS) + +HANDLE mutex_cast(void* p) +{ + return reinterpret_cast(p); +} + +LPCRITICAL_SECTION critsect_cast(void* p) +{ + return reinterpret_cast(p); +} + +inline void close(void* mutex) +{ + int res = 0; + res = CloseHandle(mutex_cast(mutex)); + assert(res); +} + +inline int wait(void* mutex, int time) +{ + unsigned int res = 0; + res = WaitForSingleObject(mutex_cast(mutex), time); + assert(res != WAIT_FAILED && res != WAIT_ABANDONED); + return res; +} + +inline void release(void* mutex) +{ + int res = 0; + res = ReleaseMutex(mutex_cast(mutex)); + assert(res); +} + class critsect_impl { public: critsect_impl() { - InitializeCriticalSection(&m_critsect); + } ~critsect_impl() { @@ -79,14 +112,14 @@ public: res = WaitForSingleObject(m_mutex, INFINITE); assert(res != WAIT_FAILED && res != WAIT_ABANDONED); } - virtual bool trylock() + bool trylock() { unsigned int res = 0; res = WaitForSingleObject(reinterpret_cast(m_mutex), 0); assert(res != WAIT_FAILED && res != WAIT_ABANDONED); return res == WAIT_OBJECT_0; } - virtual bool timedlock(const boost::xtime& xt) + bool timedlock(const boost::xtime& xt) { unsigned int res = 0; for (;;) @@ -96,7 +129,7 @@ public: res = WaitForSingleObject(reinterpret_cast(m_mutex), milliseconds); - assert(res != WAIT_FAILED && res != WAIT_ABANDONED); + if (res == WAIT_TIMEOUT) { @@ -109,7 +142,7 @@ public: return res == WAIT_OBJECT_0; } } - virtual void unlock() + void unlock() { int res = 0; res = ReleaseMutex(reinterpret_cast(m_mutex)); @@ -126,58 +159,55 @@ private: namespace boost { #if defined(BOOST_HAS_WINTHREADS) -mutex::mutex() -{ - try - { - m_mutex = reinterpret_cast(new critsect_impl()); - } - catch (std::bad_alloc&) - { - m_mutex = 0; - } - if (!m_mutex) - throw thread_resource_error(); - m_critsect = true; -} mutex::mutex(const char* name) : boost::detail::named_object(name) { - try + if (name) { - m_mutex = reinterpret_cast(new mutex_impl( - effective_name().c_str())); + HANDLE mutex = CreateMutex(0, 0, effective_name()); + if (mutex == INVALID_HANDLE_VALUE) + throw thread_resource_error(); + m_critsect = false; } - catch (std::bad_alloc&) + else { - throw thread_resource_error(); + try + { + LPCRITICAL_SECTION cs = new CRITICAL_SECTION; + InitializeCriticalSection(cs); + m_mutex = reinterpret_cast(cs); + m_critsect = true; + } + catch (std::bad_alloc&) + { + throw thread_resource_error(); + } } - m_critsect = false; } mutex::~mutex() { if (m_critsect) - delete reinterpret_cast(m_mutex); + delete critsect_cast(m_mutex); else - delete reinterpret_cast(m_mutex); + close(m_mutex); } void mutex::do_lock() { if (m_critsect) - reinterpret_cast(m_mutex)->lock(); + EnterCriticalSection(critsect_cast(m_mutex)); else - reinterpret_cast(m_mutex)->lock(); + wait(m_mutex, INFINITE); } void mutex::do_unlock() { if (m_critsect) - reinterpret_cast(m_mutex)->unlock(); + LeaveCriticalSection(critsect_cast(m_mutex)); else - reinterpret_cast(m_mutex)->unlock(); + release(m_mutex); } void mutex::do_lock(cv_state&) @@ -190,50 +220,32 @@ void mutex::do_unlock(cv_state&) do_unlock(); } -try_mutex::try_mutex() -{ - try - { - m_mutex = reinterpret_cast(new mutex_impl(0)); - } - catch (std::bad_alloc&) - { - throw thread_resource_error(); - } -} - try_mutex::try_mutex(const char* name) : boost::detail::named_object(name) { - try - { - m_mutex = reinterpret_cast(new mutex_impl( - effective_name().c_str())); - } - catch (std::bad_alloc&) - { + HANDLE mutex = CreateMutex(0, 0, effective_name()); + if (mutex == INVALID_HANDLE_VALUE) throw thread_resource_error(); - } } try_mutex::~try_mutex() { - delete reinterpret_cast(m_mutex); + close(m_mutex); } void try_mutex::do_lock() { - reinterpret_cast(m_mutex)->lock(); + wait(m_mutex, INFINITE); } bool try_mutex::do_trylock() { - return reinterpret_cast(m_mutex)->trylock(); + return wait(m_mutex, 0) == WAIT_OBJECT_0; } void try_mutex::do_unlock() { - reinterpret_cast(m_mutex)->unlock(); + release(m_mutex); } void try_mutex::do_lock(cv_state&) @@ -246,55 +258,53 @@ void try_mutex::do_unlock(cv_state&) do_unlock(); } -timed_mutex::timed_mutex() -{ - try - { - m_mutex = reinterpret_cast(new mutex_impl(0)); - } - catch (std::bad_alloc&) - { - throw thread_resource_error(); - } -} - timed_mutex::timed_mutex(const char* name) : boost::detail::named_object(name) { - try - { - m_mutex = reinterpret_cast(new mutex_impl( - effective_name().c_str())); - } - catch (std::bad_alloc&) - { + HANDLE mutex = CreateMutex(0, 0, effective_name()); + if (mutex == INVALID_HANDLE_VALUE) throw thread_resource_error(); - } } timed_mutex::~timed_mutex() { - delete reinterpret_cast(m_mutex); + close(m_mutex); } void timed_mutex::do_lock() { - reinterpret_cast(m_mutex)->lock(); + wait(m_mutex, INFINITE); } bool timed_mutex::do_trylock() { - return reinterpret_cast(m_mutex)->trylock(); + return wait(m_mutex, 0) == WAIT_OBJECT_0; } bool timed_mutex::do_timedlock(const xtime& xt) { - return reinterpret_cast(m_mutex)->timedlock(xt); + for (;;) + { + int milliseconds; + to_duration(xt, milliseconds); + + int res = wait(m_mutex, milliseconds); + + if (res == WAIT_TIMEOUT) + { + boost::xtime cur; + boost::xtime_get(&cur, boost::TIME_UTC); + if (boost::xtime_cmp(xt, cur) > 0) + continue; + } + + return res == WAIT_OBJECT_0; + } } void timed_mutex::do_unlock() { - reinterpret_cast(m_mutex)->unlock(); + release(m_mutex); } void timed_mutex::do_lock(cv_state&) diff --git a/src/named.cpp b/src/named.cpp index 1dd0fb77..0bc698ba 100644 --- a/src/named.cpp +++ b/src/named.cpp @@ -1,14 +1,41 @@ #include +#include +#include namespace { -std::string encode(const char* str) +char* concat(char* result, const char* buf) +{ + if (result == 0) + return strdup(buf); + + int len = strlen(result) + strlen(buf) + 1; + result = (char*)realloc(result, len); + strcat(result, buf); + return result; +} + +char* get_root() +{ +#if defined(BOOST_HAS_WINTHREADS) + return ""; +#elif defined(BOOST_HAS_PTHREADS) + return "/"; +#else + return ""; +#endif +} + +char* encode(const char* str) { const char* digits="0123456789abcdef"; - std::string result; + char* result=0; static char buf[100]; char* ebuf = buf + 100; char* p = buf; + *p = 0; + strcat(p, get_root()); + p = p + strlen(p); while (*str) { if (((*str >= '0') && (*str <= '9')) || @@ -27,7 +54,7 @@ std::string encode(const char* str) if (p + 3 >= ebuf) { *p = 0; - result += buf; + result = concat(result, buf); p = buf; } *p = '%'; @@ -43,59 +70,53 @@ std::string encode(const char* str) if (++p == ebuf) { *p = 0; - result += buf; + result = concat(result, buf); p = buf; } ++str; } *p = 0; - result += buf; + result = concat(result, buf); return result; } -std::string get_root() -{ -#if defined(BOOST_HAS_WINTHREADS) - return ""; -#elif defined(BOOST_HAS_PTHREADS) - return "/"; -#else - return ""; -#endif -} - } // namespace namespace boost { namespace detail { -named_object::named_object() -{ -} - named_object::named_object(const char* name) - : m_name(name) + : m_name(0), m_ename(0) { + if (name) + { + m_name = strdup(name); + if (*m_name == '%') + m_ename = m_name + 1; + else + m_ename = encode(name); + } } named_object::~named_object() { + if (m_name) + { + if (*m_name != '%') + free(m_ename); + free(m_name); + } } -std::string named_object::name() const +const char* named_object::name() const { return m_name; } -std::string named_object::effective_name() const +const char* named_object::effective_name() const { - if (m_name.empty()) - return m_name; - if (m_name[0] == '%') - return m_name.substr(1); - return get_root() + encode(m_name.c_str()); + return m_ename; } } // namespace detail } // namespace boost -