Changeset 53c6e6a in mainline


Ignore:
Timestamp:
2018-07-05T21:41:20Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b4b961b
Parents:
ce22ac6
git-author:
Dzejrou <dzejrou@…> (2018-03-29 14:13:16)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:20)
Message:

cpp: added shared_lock and lock()

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/cpp/include/impl/mutex.hpp

    rce22ac6 r53c6e6a  
    387387            }
    388388
    389             void unlock();
     389            void unlock()
    390390            {
    391391                /**
     
    450450     */
    451451
    452     // TODO:
    453452    template<class Mutex>
    454     class shared_lock;
     453    class shared_lock
     454    {
     455        public:
     456            using mutex_type = Mutex;
     457
     458            /**
     459             * 30.4.2.2.1, construction/copy/destroy:
     460             */
     461
     462            shared_lock() noexcept
     463                : mtx_{nullptr}, owns_{false}
     464            { /* DUMMY BODY */ }
     465
     466            explicit shared_lock(mutex_type& mtx)
     467                : mtx_{&mtx}, owns_{true}
     468            {
     469                mtx_->lock_shared();
     470            }
     471
     472            shared_lock(mutex_type& mtx, defer_lock_t) noexcept
     473                : mtx_{&mtx}, owns_{false}
     474            { /* DUMMY BODY */ }
     475
     476            shared_lock(mutex_type& mtx, try_to_lock_t)
     477                : mtx_{&mtx}, owns_{}
     478            {
     479                owns_ = mtx_->try_lock_shared();
     480            }
     481
     482            shared_lock(mutex_type& mtx, adopt_lock_t)
     483                : mtx_{&mtx}, owns_{true}
     484            { /* DUMMY BODY */ }
     485
     486            template<class Clock, class Duration>
     487            shared_lock(mutex_type& mtx, const chrono::time_point<Clock, Duration>& abs_time)
     488                : mtx_{&mtx}, owns_{}
     489            {
     490                owns_ = mtx_->try_lock_shared_until(abs_time);
     491            }
     492
     493            template<class Rep, class Period>
     494            shared_lock(mutex_type& mtx, const chrono::duration<Rep, Period>& rel_time)
     495                : mtx_{&mtx}, owns_{}
     496            {
     497                owns_ = mtx_->try_lock_shared_for(rel_time);
     498            }
     499
     500            ~shared_lock()
     501            {
     502                if (owns_)
     503                    mtx_->unlock_shared();
     504            }
     505
     506            shared_lock(const shared_lock&) = delete;
     507            shared_lock& operator=(const shared_lock&) = delete;
     508
     509            shared_lock(shared_lock&& other) noexcept
     510                : mtx_{move(other.mtx_)}, owns_{move(other.owns_)}
     511            {
     512                other.mtx_ = nullptr;
     513                other.owns_ = false;
     514            }
     515
     516            shared_lock& operator=(shared_lock&& other)
     517            {
     518                if (owns_)
     519                    mtx_->unlock_shared();
     520
     521                mtx_ = move(other.mtx_);
     522                owns_ = move(other.owns_);
     523
     524                other.mtx_ = nullptr;
     525                other.owns_ = false;
     526            }
     527
     528            /**
     529             * 30.4.2.2.2, locking:
     530             */
     531
     532            void lock()
     533            {
     534                /**
     535                 * TODO:
     536                 * throw system_error operation_not_permitted if mtx_ == nullptr
     537                 * throw system_error resource_deadlock_would_occur if owns_ == true
     538                 */
     539
     540                mtx_->lock_shared();
     541                owns_ = true;
     542            }
     543
     544            bool try_lock()
     545            {
     546                /**
     547                 * TODO:
     548                 * throw system_error operation_not_permitted if mtx_ == nullptr
     549                 * throw system_error resource_deadlock_would_occur if owns_ == true
     550                 */
     551
     552                owns_ = mtx_->try_lock_shared();
     553
     554                return owns_;
     555            }
     556
     557            template<class Rep, class Period>
     558            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
     559            {
     560                /**
     561                 * TODO:
     562                 * throw system_error operation_not_permitted if mtx_ == nullptr
     563                 * throw system_error resource_deadlock_would_occur if owns_ == true
     564                 */
     565
     566                owns_ = mtx_->try_lock_shared_for(rel_time);
     567
     568                return owns_;
     569            }
     570
     571            template<class Clock, class Duration>
     572            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
     573            {
     574                /**
     575                 * TODO:
     576                 * throw system_error operation_not_permitted if mtx_ == nullptr
     577                 * throw system_error resource_deadlock_would_occur if owns_ == true
     578                 */
     579
     580                owns_ = mtx_->try_lock_shared_until(abs_time);
     581
     582                return owns_;
     583            }
     584
     585            void unlock()
     586            {
     587                /**
     588                 * TODO:
     589                 * throw system_error operation_not_permitted if owns_ == false
     590                 */
     591
     592                mtx_->unlock_shared();
     593            }
     594
     595            /**
     596             * 30.4.2.2.3, modifiers:
     597             */
     598
     599            void swap(shared_lock& other) noexcept
     600            {
     601                std::swap(mtx_, other.mtx_);
     602                std::swap(owns_, other.owns_);
     603            }
     604
     605            mutex_type* release() noexcept
     606            {
     607                auto ret = mtx_;
     608                mtx_ = nullptr;
     609                owns_ = false;
     610
     611                return ret;
     612            }
     613
     614            /**
     615             * 30.4.2.2.4, observers:
     616             */
     617
     618            bool owns_lock() const noexcept
     619            {
     620                return owns_;
     621            }
     622
     623            explicit operator bool() const noexcept
     624            {
     625                return owns_;
     626            }
     627
     628            mutex_type* mutex() const noexcept
     629            {
     630                return mtx_;
     631            }
     632
     633        private:
     634            mutex_type* mtx_;
     635            bool owns_;
     636    };
    455637
    456638    template<class Mutex>
    457     void swap(shared_lock<Mutex>& lhs, shared_lock<Mutex>& rhs) noexcept;
     639    void swap(shared_lock<Mutex>& lhs, shared_lock<Mutex>& rhs) noexcept
     640    {
     641        lhs.swap(rhs);
     642    }
    458643
    459644    template<class L1, class L2, class... L3>
    460645    int try_lock(L1& l1, L2& l2, L3&... ls);
    461646
     647    namespace aux
     648    {
     649        template<class L>
     650        bool lock_tail(L& l)
     651        {
     652            return l.try_lock();
     653        }
     654
     655        template<class L1, class... L2>
     656        bool lock_tail(L1& l1, L2&... ls)
     657        {
     658            if (l1.try_lock())
     659            {
     660                auto ret = lock_tail(ls...);
     661                if (ret)
     662                    return true;
     663
     664                l1.unlock();
     665            }
     666
     667            return false;
     668        }
     669    }
     670
    462671    template<class L1, class L2, class... L3>
    463     void lock(L1& l1, L2& l2, L3&... ls);
     672    void lock(L1& l1, L2& l2, L3&... ls)
     673    {
     674        do
     675        {
     676            l1.lock();
     677
     678            if (aux::lock_tail(l2, ls...))
     679                return;
     680            l1.unlock();
     681        } while (true);
     682    }
    464683
    465684    struct once_flag
Note: See TracChangeset for help on using the changeset viewer.