diff --git a/src/mutex.cpp b/src/mutex.cpp index d5ddc4dd..0bee58e4 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -56,102 +56,16 @@ inline int wait(void* mutex, int time) { unsigned int res = 0; res = WaitForSingleObject(mutex_cast(mutex), time); - assert(res != WAIT_FAILED && res != WAIT_ABANDONED); +// assert(res != WAIT_FAILED && res != WAIT_ABANDONED); return res; } inline void release(void* mutex) { - int res = 0; + BOOL res = FALSE; res = ReleaseMutex(mutex_cast(mutex)); assert(res); } - -class critsect_impl -{ -public: - critsect_impl() - { - - } - ~critsect_impl() - { - DeleteCriticalSection(&m_critsect); - } - void lock() - { - EnterCriticalSection(&m_critsect); - } - void unlock() - { - LeaveCriticalSection(&m_critsect); - } - -private: - CRITICAL_SECTION m_critsect; -}; - -class mutex_impl -{ -public: - mutex_impl(const char* name=0) - { - m_mutex = CreateMutexA(0, 0, name); - if (m_mutex == INVALID_HANDLE_VALUE) - throw boost::thread_resource_error(); - } - ~mutex_impl() - { - int res = 0; - res = CloseHandle(m_mutex); - assert(res); - } - void lock() - { - unsigned int res = 0; - res = WaitForSingleObject(m_mutex, INFINITE); - assert(res != WAIT_FAILED && res != WAIT_ABANDONED); - } - 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; - } - bool timedlock(const boost::xtime& xt) - { - unsigned int res = 0; - for (;;) - { - int milliseconds; - to_duration(xt, milliseconds); - - res = WaitForSingleObject(reinterpret_cast(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 unlock() - { - int res = 0; - res = ReleaseMutex(reinterpret_cast(m_mutex)); - assert(res); - } - -private: - HANDLE m_mutex; -}; #endif } // namesapce @@ -168,21 +82,16 @@ mutex::mutex(const char* name) HANDLE mutex = CreateMutex(0, 0, effective_name()); if (mutex == INVALID_HANDLE_VALUE) throw thread_resource_error(); + m_mutex = reinterpret_cast(mutex); m_critsect = false; } else { - 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(); - } + LPCRITICAL_SECTION cs = new CRITICAL_SECTION; + if (cs == 0) throw std::bad_alloc(); + InitializeCriticalSection(cs); + m_mutex = reinterpret_cast(cs); + m_critsect = true; } } @@ -226,6 +135,7 @@ try_mutex::try_mutex(const char* name) HANDLE mutex = CreateMutex(0, 0, effective_name()); if (mutex == INVALID_HANDLE_VALUE) throw thread_resource_error(); + m_mutex = reinterpret_cast(mutex); } try_mutex::~try_mutex() @@ -264,6 +174,7 @@ timed_mutex::timed_mutex(const char* name) HANDLE mutex = CreateMutex(0, 0, effective_name()); if (mutex == INVALID_HANDLE_VALUE) throw thread_resource_error(); + m_mutex = reinterpret_cast(mutex); } timed_mutex::~timed_mutex() @@ -288,7 +199,7 @@ bool timed_mutex::do_timedlock(const xtime& xt) int milliseconds; to_duration(xt, milliseconds); - int res = wait(m_mutex, milliseconds); + int res = wait(m_mutex, milliseconds); if (res == WAIT_TIMEOUT) { @@ -304,7 +215,7 @@ bool timed_mutex::do_timedlock(const xtime& xt) void timed_mutex::do_unlock() { - release(m_mutex); + release(m_mutex); } void timed_mutex::do_lock(cv_state&) diff --git a/src/thread.cpp b/src/thread.cpp index 24761a48..6a7c90c1 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -61,8 +61,7 @@ public: { creating, running, - finished, - // joining, + finished, joined }; @@ -177,62 +176,71 @@ bool thread_data::release() void thread_data::join() { - boost::mutex::scoped_lock lock(m_mutex); - while (m_state != joined && m_state != finished) - m_cond.wait(lock); - if (m_state == finished) - { - int res = 0; + bool do_join=false; + { + boost::mutex::scoped_lock lock(m_mutex); + while (m_state != joined && m_state != finished) + m_cond.wait(lock); + do_join = (m_state == finished); + } + if (do_join) + { + int res = 0; #if defined(BOOST_HAS_WINTHREADS) - res = WaitForSingleObject(m_thread, INFINITE); - assert(res == WAIT_OBJECT_0); - res = CloseHandle(m_thread); - assert(res); + res = WaitForSingleObject(m_thread, INFINITE); + assert(res == WAIT_OBJECT_0); + res = CloseHandle(m_thread); + assert(res); #elif defined(BOOST_HAS_PTHREADS) - res = pthread_join(m_thread, 0); - assert(res == 0); + res = pthread_join(m_thread, 0); + assert(res == 0); #elif defined(BOOST_HAS_MPTASKS) - OSStatus lStatus = - threads::mac::detail::safe_wait_on_queue(m_pJoinQueueID, NULL, - NULL, NULL, - kDurationForever); - assert(lStatus == noErr); + OSStatus lStatus = + threads::mac::detail::safe_wait_on_queue(m_pJoinQueueID, NULL, + NULL, NULL, + kDurationForever); + assert(lStatus == noErr); #endif - m_state = joined; - m_cond.notify_all(); - } + boost::mutex::scoped_lock lock(m_mutex); + m_state = joined; + m_cond.notify_all(); + } } bool thread_data::timed_join(const boost::xtime& xt) { - boost::mutex::scoped_lock lock(m_mutex); - while (m_state != joined && m_state != finished) - { - if (!m_cond.timed_wait(lock, xt)) - return false; - } - if (m_state == finished) - { - int res = 0; + bool do_join=false; + { + boost::mutex::scoped_lock lock(m_mutex); + while (m_state != joined && m_state != finished) + { + if (!m_cond.timed_wait(lock, xt)) + return false; + } + } + if (do_join) + { + int res = 0; #if defined(BOOST_HAS_WINTHREADS) - res = WaitForSingleObject(m_thread, INFINITE); - assert(res == WAIT_OBJECT_0); - res = CloseHandle(m_thread); - assert(res); + res = WaitForSingleObject(m_thread, INFINITE); + assert(res == WAIT_OBJECT_0); + res = CloseHandle(m_thread); + assert(res); #elif defined(BOOST_HAS_PTHREADS) - res = pthread_join(m_thread, 0); - assert(res == 0); + res = pthread_join(m_thread, 0); + assert(res == 0); #elif defined(BOOST_HAS_MPTASKS) - OSStatus lStatus = - threads::mac::detail::safe_wait_on_queue(m_pJoinQueueID, NULL, - NULL, NULL, - kDurationForever); - assert(lStatus == noErr); + OSStatus lStatus = + threads::mac::detail::safe_wait_on_queue(m_pJoinQueueID, NULL, + NULL, NULL, + kDurationForever); + assert(lStatus == noErr); #endif - m_state = joined; - m_cond.notify_all(); - } - return true; + boost::mutex::scoped_lock lock(m_mutex); + m_state = joined; + m_cond.notify_all(); + } + return true; } void thread_data::cancel() @@ -282,7 +290,16 @@ void thread_data::run() m_state = running; m_cond.notify_all(); } - m_threadfunc(); + try + { + m_threadfunc(); + } + catch (boost::thread_cancel) + { + } + boost::mutex::scoped_lock lock(m_mutex); + m_state = finished; + m_cond.notify_all(); } boost::thread::id_type thread_data::id() const @@ -395,9 +412,6 @@ extern "C" { tss_thread_data.reset(data); data->run(); } - catch (boost::thread_cancel) - { - } catch (...) { using namespace std; @@ -842,7 +856,7 @@ void thread::sleep(const xtime& xt) AbsoluteTime sWakeTime(DurationToAbsolute(lMicroseconds)); threads::mac::detail::safe_delay_until(&sWakeTime); #endif - thread::test_cancel(); + thread::test_cancel(); xtime cur; xtime_get(&cur, TIME_UTC); if (xtime_cmp(xt, cur) <= 0) diff --git a/test/.cvsignore b/test/.cvsignore index 14acbe0d..d8693b10 100644 --- a/test/.cvsignore +++ b/test/.cvsignore @@ -1,2 +1,3 @@ bin -*.pdb \ No newline at end of file +*.pdb +.jamdeps \ No newline at end of file diff --git a/test/Jamfile b/test/Jamfile index 66e1e7d2..c89a885f 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -54,7 +54,7 @@ include testing.jam ; [ run test_once.cpp