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; }