コード例 #1
0
 cv_status wait_until( LockType & lt, std::chrono::time_point< Clock, Duration > const& timeout_time_) {
     cv_status status = cv_status::no_timeout;
     std::chrono::steady_clock::time_point timeout_time(
             detail::convert( timeout_time_) );
     context * ctx = context::active();
     // atomically call lt.unlock() and block on *this
     // store this fiber in waiting-queue
     detail::spinlock_lock lk( wait_queue_splk_);
     BOOST_ASSERT( ! ctx->wait_is_linked() );
     ctx->wait_link( wait_queue_);
     // unlock external lt
     lt.unlock();
     // suspend this fiber
     if ( ! ctx->wait_until( timeout_time, lk) ) {
         status = cv_status::timeout;
     }
     // relock local lk
     lk.lock();
     // remove from waiting-queue
     ctx->wait_unlink();
     // unlock local lk
     lk.unlock();
     // relock external again before returning
     try {
         lt.lock();
     } catch (...) {
         std::terminate();
     }
     // post-conditions
     BOOST_ASSERT( ! ctx->wait_is_linked() );
     return status;
 }
コード例 #2
0
ファイル: timed_mutex.hpp プロジェクト: chenbk85/boost-fiber
 bool try_lock_until( std::chrono::time_point< Clock, Duration > const& timeout_time_) {
     std::chrono::steady_clock::time_point timeout_time(
             detail::convert( timeout_time_) );
     return try_lock_until_( timeout_time);
 }
コード例 #3
0
ファイル: condition.hpp プロジェクト: 654894017/fiberproxy
    cv_status wait_until( LockType & lt, chrono::time_point< Clock, Duration > const& timeout_time_)
    {
        cv_status status = cv_status::no_timeout;
        chrono::high_resolution_clock::time_point timeout_time(
            detail::convert_tp( timeout_time_) );

        detail::fiber_base * n( fm_active() );
        try
        {
            if ( n)
            {
                // lock spinlock
                unique_lock< detail::spinlock > lk( splk_);

                // store this fiber in waiting-queue
                // in order notify (resume) this fiber later
                waiting_.push_back( n);

                // unlock external
                lt.unlock();

                // suspend this fiber
                // locked spinlock will be released if this fiber
                // was stored inside schedulers's waiting-queue
                if ( ! fm_wait_until( timeout_time, lk) )
                {
                    // this fiber was not notified before timeout
                    // lock spinlock again
                    unique_lock< detail::spinlock > lk( splk_);
                    std::deque< detail::fiber_base * >::iterator wit = std::find( waiting_.begin(), waiting_.end(), n);
                    if (wit != waiting_.end())
                    {
                        // remove fiber from waiting-list
                        waiting_.erase( wit );
                    }

                    status = cv_status::timeout;
                }

                // check if fiber was interrupted
                this_fiber::interruption_point();

                // lock external again before returning
                lt.lock();
            }
            else
            {
                // notification for main-fiber
                detail::main_fiber mf;
                n = & mf;

                // lock spinlock
                unique_lock< detail::spinlock > lk( splk_);

                // store this fiber in order to be notified later
                waiting_.push_back( n);

                // unlock external
                lt.unlock();

                // release spinlock
                lk.unlock();

                // loop until main-notifier gets notified
                while ( ! n->is_ready() )
                {
                    // check timepoint
                    if ( ! ( chrono::high_resolution_clock::now() < timeout_time) )
                    {
                        // timeout happend before notified
                        // lock spinlock
                        unique_lock< detail::spinlock > lk( splk_);
                        std::deque< detail::fiber_base * >::iterator wit = std::find( waiting_.begin(), waiting_.end(), n);
                        if (wit != waiting_.end())
                        {
                            // remove fiber from waiting-list
                            waiting_.erase(wit);
                        }

                        status = cv_status::timeout;
                        break;
                    }
                    // run scheduler
                    fm_run();
                }

                // lock external again before returning
                lt.lock();
            }
        }
        catch (...)
        {
            unique_lock< detail::spinlock > lk( splk_);
            std::deque< detail::fiber_base * >::iterator wit = std::find( waiting_.begin(), waiting_.end(), n);
            if (wit != waiting_.end())
            {
                // remove fiber from waiting-list
                waiting_.erase( wit );
            }
            throw;
        }

        return status;
    }