bool priv_timed_lock(sync::detail::system_time_point const& t) { long old_count = m_mutex.m_active_count; m_mutex.mark_waiting_and_try_lock(old_count); if ((old_count & sync::detail::windows::basic_mutex::lock_flag_value) == 0) return true; try { boost::detail::winapi::HANDLE_ handles[2]; handles[0] = m_mutex.get_event(); handles[1] = sync::detail::windows::get_waitable_timer(); if (!boost::detail::winapi::SetWaitableTimer(handles[1], reinterpret_cast< const boost::detail::winapi::LARGE_INTEGER_* >(&t.get()), 0, NULL, NULL, false)) { const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError(); BOOST_SYNC_DETAIL_THROW(lock_error, (err)("timed_mutex::timed_lock failed to set a timeout")); } while (true) { const boost::detail::winapi::DWORD_ res = boost::detail::winapi::WaitForMultipleObjects(sizeof(handles) / sizeof(*handles), handles, false, boost::detail::winapi::infinite); if (res == boost::detail::winapi::wait_failed) { const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError(); BOOST_SYNC_DETAIL_THROW(lock_error, (err)("timed_mutex::timed_lock failed in WaitForMultipleObjects")); } switch (res) { case boost::detail::winapi::wait_object_0: // event was notified m_mutex.clear_waiting_and_try_lock(old_count); if ((old_count & sync::detail::windows::basic_mutex::lock_flag_value) == 0) return true; break; case boost::detail::winapi::wait_object_0 + 1: // timeout has expired BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&m_mutex.m_active_count, -1); return false; default: BOOST_ASSERT(false); } } } catch (...) { BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&m_mutex.m_active_count, -1); throw; } }
sync::cv_status priv_timed_wait(unique_lock< Mutex >& lock, sync::detail::system_time_point const& t) { int const res = sync::detail::posix::pthread_cond_timedwait(&m_cond, lock.mutex()->native_handle(), &t.get()); if (res == ETIMEDOUT) return sync::cv_status::timeout; else if (res != 0) BOOST_SYNC_DETAIL_THROW(wait_error, (res)("boost::sync::condition_variable timedwait failed in pthread_cond_timedwait")); return sync::cv_status::no_timeout; }
bool priv_timed_lock(sync::detail::system_duration t) { long old_count = m_mutex.m_active_count; m_mutex.mark_waiting_and_try_lock(old_count); if ((old_count & sync::detail::windows::basic_mutex::lock_flag_value) == 0) return true; try { const boost::detail::winapi::HANDLE_ evt = m_mutex.get_event(); sync::detail::system_duration::native_type time_left = t.get(); while (time_left > 0) { const boost::detail::winapi::DWORD_ dur = time_left > boost::detail::winapi::max_non_infinite_wait ? boost::detail::winapi::max_non_infinite_wait : static_cast< boost::detail::winapi::DWORD_ >(time_left); const boost::detail::winapi::DWORD_ res = boost::detail::winapi::WaitForSingleObject(evt, dur); switch (res) { case boost::detail::winapi::wait_object_0: m_mutex.clear_waiting_and_try_lock(old_count); if ((old_count & sync::detail::windows::basic_mutex::lock_flag_value) == 0) return true; break; case boost::detail::winapi::wait_timeout: time_left -= dur; break; default: { const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError(); BOOST_SYNC_DETAIL_THROW(lock_error, (err)("timed_mutex::timed_lock failed in WaitForSingleObject")); } } } BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&m_mutex.m_active_count, -1); return false; } catch (...) { BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&m_mutex.m_active_count, -1); throw; } }
void priv_wait(pthread_mutex_t* mtx) { int const res = sync::detail::posix::pthread_cond_wait(&m_cond, mtx); if (res != 0) BOOST_SYNC_DETAIL_THROW(wait_error, (res)("boost::sync::condition_variable::wait failed in pthread_cond_wait")); }