LCOV - code coverage report
Current view: top level - 11/bits - unique_lock.h (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 36 39 92.3 %
Date: 2025-08-24 09:11:10 Functions: 20 20 100.0 %

          Line data    Source code
       1             : // std::unique_lock implementation -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2008-2021 Free Software Foundation, Inc.
       4             : //
       5             : // This file is part of the GNU ISO C++ Library.  This library is free
       6             : // software; you can redistribute it and/or modify it under the
       7             : // terms of the GNU General Public License as published by the
       8             : // Free Software Foundation; either version 3, or (at your option)
       9             : // any later version.
      10             : 
      11             : // This library is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : 
      16             : // Under Section 7 of GPL version 3, you are granted additional
      17             : // permissions described in the GCC Runtime Library Exception, version
      18             : // 3.1, as published by the Free Software Foundation.
      19             : 
      20             : // You should have received a copy of the GNU General Public License and
      21             : // a copy of the GCC Runtime Library Exception along with this program;
      22             : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23             : // <http://www.gnu.org/licenses/>.
      24             : 
      25             : /** @file bits/unique_lock.h
      26             :  *  This is an internal header file, included by other library headers.
      27             :  *  Do not attempt to use it directly. @headername{mutex}
      28             :  */
      29             : 
      30             : #ifndef _GLIBCXX_UNIQUE_LOCK_H
      31             : #define _GLIBCXX_UNIQUE_LOCK_H 1
      32             : 
      33             : #pragma GCC system_header
      34             : 
      35             : #if __cplusplus < 201103L
      36             : # include <bits/c++0x_warning.h>
      37             : #else
      38             : 
      39             : #include <chrono>
      40             : #include <bits/move.h> // for std::swap
      41             : #include <bits/std_mutex.h> // for std::defer_lock_t
      42             : 
      43             : namespace std _GLIBCXX_VISIBILITY(default)
      44             : {
      45             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      46             : 
      47             :   /** @brief A movable scoped lock type.
      48             :    *
      49             :    * A unique_lock controls mutex ownership within a scope. Ownership of the
      50             :    * mutex can be delayed until after construction and can be transferred
      51             :    * to another unique_lock by move construction or move assignment. If a
      52             :    * mutex lock is owned when the destructor runs ownership will be released.
      53             :    *
      54             :    * @ingroup mutexes
      55             :    */
      56             :   template<typename _Mutex>
      57             :     class unique_lock
      58             :     {
      59             :     public:
      60             :       typedef _Mutex mutex_type;
      61             : 
      62             :       unique_lock() noexcept
      63             :       : _M_device(0), _M_owns(false)
      64             :       { }
      65             : 
      66      131301 :       explicit unique_lock(mutex_type& __m)
      67      131301 :       : _M_device(std::__addressof(__m)), _M_owns(false)
      68             :       {
      69      131288 :         lock();
      70      131285 :         _M_owns = true;
      71      131285 :       }
      72             : 
      73         144 :       unique_lock(mutex_type& __m, defer_lock_t) noexcept
      74         144 :       : _M_device(std::__addressof(__m)), _M_owns(false)
      75         144 :       { }
      76             : 
      77         418 :       unique_lock(mutex_type& __m, try_to_lock_t)
      78         418 :       : _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock())
      79         418 :       { }
      80             : 
      81             :       unique_lock(mutex_type& __m, adopt_lock_t) noexcept
      82             :       : _M_device(std::__addressof(__m)), _M_owns(true)
      83             :       {
      84             :         // XXX calling thread owns mutex
      85             :       }
      86             : 
      87             :       template<typename _Clock, typename _Duration>
      88             :         unique_lock(mutex_type& __m,
      89             :                     const chrono::time_point<_Clock, _Duration>& __atime)
      90             :         : _M_device(std::__addressof(__m)),
      91             :           _M_owns(_M_device->try_lock_until(__atime))
      92             :         { }
      93             : 
      94             :       template<typename _Rep, typename _Period>
      95             :         unique_lock(mutex_type& __m,
      96             :                     const chrono::duration<_Rep, _Period>& __rtime)
      97             :         : _M_device(std::__addressof(__m)),
      98             :           _M_owns(_M_device->try_lock_for(__rtime))
      99             :         { }
     100             : 
     101      131867 :       ~unique_lock()
     102             :       {
     103      131867 :         if (_M_owns)
     104       93958 :           unlock();
     105      131866 :       }
     106             : 
     107             :       unique_lock(const unique_lock&) = delete;
     108             :       unique_lock& operator=(const unique_lock&) = delete;
     109             : 
     110             :       unique_lock(unique_lock&& __u) noexcept
     111             :       : _M_device(__u._M_device), _M_owns(__u._M_owns)
     112             :       {
     113             :         __u._M_device = 0;
     114             :         __u._M_owns = false;
     115             :       }
     116             : 
     117             :       unique_lock& operator=(unique_lock&& __u) noexcept
     118             :       {
     119             :         if(_M_owns)
     120             :           unlock();
     121             : 
     122             :         unique_lock(std::move(__u)).swap(*this);
     123             : 
     124             :         __u._M_device = 0;
     125             :         __u._M_owns = false;
     126             : 
     127             :         return *this;
     128             :       }
     129             : 
     130             :       void
     131      131575 :       lock()
     132             :       {
     133      131575 :         if (!_M_device)
     134           0 :           __throw_system_error(int(errc::operation_not_permitted));
     135      131575 :         else if (_M_owns)
     136           0 :           __throw_system_error(int(errc::resource_deadlock_would_occur));
     137             :         else
     138             :           {
     139      131575 :             _M_device->lock();
     140      131580 :             _M_owns = true;
     141             :           }
     142      131580 :       }
     143             : 
     144             :       bool
     145             :       try_lock()
     146             :       {
     147             :         if (!_M_device)
     148             :           __throw_system_error(int(errc::operation_not_permitted));
     149             :         else if (_M_owns)
     150             :           __throw_system_error(int(errc::resource_deadlock_would_occur));
     151             :         else
     152             :           {
     153             :             _M_owns = _M_device->try_lock();
     154             :             return _M_owns;
     155             :           }
     156             :       }
     157             : 
     158             :       template<typename _Clock, typename _Duration>
     159             :         bool
     160             :         try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
     161             :         {
     162             :           if (!_M_device)
     163             :             __throw_system_error(int(errc::operation_not_permitted));
     164             :           else if (_M_owns)
     165             :             __throw_system_error(int(errc::resource_deadlock_would_occur));
     166             :           else
     167             :             {
     168             :               _M_owns = _M_device->try_lock_until(__atime);
     169             :               return _M_owns;
     170             :             }
     171             :         }
     172             : 
     173             :       template<typename _Rep, typename _Period>
     174             :         bool
     175             :         try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
     176             :         {
     177             :           if (!_M_device)
     178             :             __throw_system_error(int(errc::operation_not_permitted));
     179             :           else if (_M_owns)
     180             :             __throw_system_error(int(errc::resource_deadlock_would_occur));
     181             :           else
     182             :             {
     183             :               _M_owns = _M_device->try_lock_for(__rtime);
     184             :               return _M_owns;
     185             :             }
     186             :          }
     187             : 
     188             :       void
     189      145460 :       unlock()
     190             :       {
     191      145460 :         if (!_M_owns)
     192           0 :           __throw_system_error(int(errc::operation_not_permitted));
     193      145460 :         else if (_M_device)
     194             :           {
     195      145461 :             _M_device->unlock();
     196      145470 :             _M_owns = false;
     197             :           }
     198      145469 :       }
     199             : 
     200             :       void
     201             :       swap(unique_lock& __u) noexcept
     202             :       {
     203             :         std::swap(_M_device, __u._M_device);
     204             :         std::swap(_M_owns, __u._M_owns);
     205             :       }
     206             : 
     207             :       mutex_type*
     208         836 :       release() noexcept
     209             :       {
     210         836 :         mutex_type* __ret = _M_device;
     211         836 :         _M_device = 0;
     212         836 :         _M_owns = false;
     213         836 :         return __ret;
     214             :       }
     215             : 
     216             :       bool
     217         418 :       owns_lock() const noexcept
     218         418 :       { return _M_owns; }
     219             : 
     220             :       explicit operator bool() const noexcept
     221             :       { return owns_lock(); }
     222             : 
     223             :       mutex_type*
     224        6912 :       mutex() const noexcept
     225        6912 :       { return _M_device; }
     226             : 
     227             :     private:
     228             :       mutex_type*       _M_device;
     229             :       bool              _M_owns;
     230             :     };
     231             : 
     232             :   /// Swap overload for unique_lock objects.
     233             :   /// @relates unique_lock
     234             :   template<typename _Mutex>
     235             :     inline void
     236             :     swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) noexcept
     237             :     { __x.swap(__y); }
     238             : 
     239             : _GLIBCXX_END_NAMESPACE_VERSION
     240             : } // namespace
     241             : 
     242             : #endif // C++11
     243             : #endif // _GLIBCXX_UNIQUE_LOCK_H

Generated by: LCOV version 1.14