https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116586

Mike Crowe <mac at mcrowe dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mac at mcrowe dot com

--- Comment #3 from Mike Crowe <mac at mcrowe dot com> ---
The particularly nasty thing about this for shared_timed_mutex is that if
_GLIBCXX_ASSERTIONS is not defined then
std::shared_timed_mutex::try_lock_until() returns true even though it hasn't
successfully taken the lock! That feels like a particularly nasty failure mode
for such a bug. :(

IMO returning success when we know that _something_ went wrong isn't really a
great idea. Since we're checking the return value anyway it feels like
returning false for unrecognised errors would be safer and barely any more
expensive. It looks like I just blindly copied the _timedlock code in
ab40695a46c664 to exacerbate this problem. :(

I'd be interested in views on whether std::shared_timed_mutex::try_lock_until()
should return false on all unrecognised errors if the assert allows it to
continue. Perhaps something like:

--8<--
         int __ret = pthread_rwlock_clockwrlock(&_M_rwlock, CLOCK_MONOTONIC,    
                                                &__ts);                         
         if (__ret == 0)  /// ***NEW***                                         
           return true;   /// ***NEW***                                         

         // On self-deadlock, we just fail to acquire the lock.  Technically,   
         // the program violated the precondition.                              
         if (__ret == ETIMEDOUT || __ret == EDEADLK)                            
           return false;                                                        
         // Errors not handled: EINVAL                                          
         __glibcxx_assert(__ret == 0);                                          
         return false;  /// ***INVERTED***                                      
-->8--

As would be expected, this appears to generate ever-so-slightly-less-efficient
code with -O2 and _GLIBCXX_ASSERTIONS[1], but more efficient code without
_GLIBCXX_ASSERTIONS[2] because the compiler can throw away the checks against
the exact value of __ret.

In the meantime I'll write test cases for at least the other functions I added
_clock* versions of and ensure that they cope with negative timeouts.

[1] https://godbolt.org/z/b3dKGWeW6
[2] https://godbolt.org/z/a59G7nE7j

Reply via email to