public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* std::shared_mutex deadlock
@ 2023-03-06  8:21 Bastian Hauda
  2023-03-06 10:00 ` Jonathan Wakely
  0 siblings, 1 reply; 2+ messages in thread
From: Bastian Hauda @ 2023-03-06  8:21 UTC (permalink / raw)
  To: gcc-help

[-- Attachment #1: Type: text/plain, Size: 998 bytes --]

Hi,
I observe a deadlock from time to time using the msvc + microsoft std
library and recently asked a question about std::shared_mutex in their dev
forum:
https://developercommunity.visualstudio.com/t/std::shared_mutex-deadlock/10299619#T-ND10299805

Now I would like to know if the gnu std library exhibits the same
behaviour.
(I just could not test the code on Linux yet.)

In short:
Thread C tries(!) to write access (lock via scoped_lock or unique_lock)
while Thread B already has(!) it shared locked - read access (via
std::shared_lock).
Meanwhile Thread A is also trying(!) to read access (via std::shared_lock)
the shared_mutex.

In order:
Thread B: std::shared_lock _(mutex); // ok - acquired and now waiting for
Thread A to finish
Thread C: std::scoped_lock _(mutex); // ok - stuck for now
Thread A: std::shared_lock _(mutex); // failure - stuck as well

-> Thread C should be stuck but Thread A should be able to acquire the
shared lock and continue but it is stuck as well.

Thank you.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: std::shared_mutex deadlock
  2023-03-06  8:21 std::shared_mutex deadlock Bastian Hauda
@ 2023-03-06 10:00 ` Jonathan Wakely
  0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2023-03-06 10:00 UTC (permalink / raw)
  To: Bastian Hauda; +Cc: gcc-help

[-- Attachment #1: Type: text/plain, Size: 2572 bytes --]

On Mon, 6 Mar 2023, 08:23 Bastian Hauda via Gcc-help, <gcc-help@gcc.gnu.org>
wrote:

> Hi,
> I observe a deadlock from time to time using the msvc + microsoft std
> library and recently asked a question about std::shared_mutex in their dev
> forum:
>
> https://developercommunity.visualstudio.com/t/std::shared_mutex-deadlock/10299619#T-ND10299805
>
> Now I would like to know if the gnu std library exhibits the same
> behaviour.
> (I just could not test the code on Linux yet.)
>

You could use Compiler Explorer: https://gcc.godbolt.org/


>
> In short:
> Thread C tries(!) to write access (lock via scoped_lock or unique_lock)
> while Thread B already has(!) it shared locked - read access (via
> std::shared_lock).
> Meanwhile Thread A is also trying(!) to read access (via std::shared_lock)
> the shared_mutex.
>
> In order:
> Thread B: std::shared_lock _(mutex); // ok - acquired and now waiting for
> Thread A to finish
> Thread C: std::scoped_lock _(mutex); // ok - stuck for now
> Thread A: std::shared_lock _(mutex); // failure - stuck as well
>
> -> Thread C should be stuck but Thread A should be able to acquire the
> shared lock and continue but it is stuck as well.
>

No, that's not guaranteed by the C++ standard. If you assume that behaviour
is guaranteed, then your program has a bug.

The behaviour you expect can lead to writer starvation, where thread C is
never able to acquire the lock, because there is always at least one
reader. The way to avoid writer starvation is to have a flag saying there
is at least one thread waiting for an exclusive lock, and to block later
attempts to take a shared lock. That way the writer can make progress.

The problem here is that you've made thread A depend on thread B, and wait
for it while holding a lock. That's a bad idea.

Libstdc++ has two shared_mutex implementations. The first one is used if
the OS supports POSIX pthread_rwlock_t, and then it's up to the OS's
Pthreads implementation whether readers or writers get priority. The second
implementation has the following comment, making it very clear that your
expectation is wrong:

    // This means that when no reader locks are held readers and writers get
    // equal priority. When one or more reader locks is held a writer gets
    // priority and no more reader locks can be taken while the writer is
    // queued.

This logic is based on the reference implementation of std::shared_mutex
described in the original proposal to add it to the C++ standard:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html#shared_mutex_imp

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-03-06 10:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-06  8:21 std::shared_mutex deadlock Bastian Hauda
2023-03-06 10:00 ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).