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;
        }
    }
Esempio n. 2
0
 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;
 }