unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
* bug#59055: [PATCH] Fix possible deadlock.
@ 2022-11-05 16:59 Olivier Dion via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-11-20 17:19 ` Ludovic Courtès
  0 siblings, 1 reply; 3+ messages in thread
From: Olivier Dion via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-11-05 16:59 UTC (permalink / raw)
  To: 59055; +Cc: Olivier Dion

If we got interrupted while waiting on our condition variable, we unlock
the kernel mutex momentarily while executing asynchronous operations
before putting us back into the waiting queue.

However, we have to retry acquiring the mutex before getting back into
the queue, otherwise it's possible that we wait indefinitely since
nobody could be the owner for a while.

* libguile/threads.c (lock_mutex): Try acquring the mutex after signal
interruption.
---
 libguile/threads.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/libguile/threads.c b/libguile/threads.c
index 280d306bf..0f5cf2ed5 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -1022,14 +1022,7 @@ lock_mutex (enum scm_mutex_kind kind, struct scm_mutex *m,
 
         if (err == 0)
           {
-            if (scm_is_eq (m->owner, SCM_BOOL_F))
-              {
-                m->owner = current_thread->handle;
-                scm_i_pthread_mutex_unlock (&m->lock);
-                return SCM_BOOL_T;
-              }
-            else
-              continue;
+            goto maybe_acquire;
           }
         else if (err == ETIMEDOUT)
           {
@@ -1041,7 +1034,7 @@ lock_mutex (enum scm_mutex_kind kind, struct scm_mutex *m,
             scm_i_pthread_mutex_unlock (&m->lock);
             scm_async_tick ();
             scm_i_scm_pthread_mutex_lock (&m->lock);
-            continue;
+            goto maybe_acquire;
           }
         else
           {
@@ -1050,6 +1043,14 @@ lock_mutex (enum scm_mutex_kind kind, struct scm_mutex *m,
             errno = err;
             SCM_SYSERROR;
           }
+
+      maybe_acquire:
+        if (scm_is_eq (m->owner, SCM_BOOL_F))
+          {
+            m->owner = current_thread->handle;
+            scm_i_pthread_mutex_unlock (&m->lock);
+            return SCM_BOOL_T;
+          }
       }
 }
 #undef FUNC_NAME
-- 
2.38.0






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

* bug#59055: [PATCH] Fix possible deadlock.
  2022-11-05 16:59 bug#59055: [PATCH] Fix possible deadlock Olivier Dion via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-11-20 17:19 ` Ludovic Courtès
  2022-11-20 18:33   ` Olivier Dion via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  0 siblings, 1 reply; 3+ messages in thread
From: Ludovic Courtès @ 2022-11-20 17:19 UTC (permalink / raw)
  To: Olivier Dion; +Cc: 59055-done

Hi,

Olivier Dion <olivier.dion@polymtl.ca> skribis:

> If we got interrupted while waiting on our condition variable, we unlock
> the kernel mutex momentarily while executing asynchronous operations
> before putting us back into the waiting queue.
>
> However, we have to retry acquiring the mutex before getting back into
> the queue, otherwise it's possible that we wait indefinitely since
> nobody could be the owner for a while.
>
> * libguile/threads.c (lock_mutex): Try acquring the mutex after signal
> interruption.

Looks reasonable to me; applied.

Did you try to come up with a reproducer?  That would be awesome but I
guess it’s hard because you need to trigger EINTR at the right point.

Thanks,
Ludo’.





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

* bug#59055: [PATCH] Fix possible deadlock.
  2022-11-20 17:19 ` Ludovic Courtès
@ 2022-11-20 18:33   ` Olivier Dion via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  0 siblings, 0 replies; 3+ messages in thread
From: Olivier Dion via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-11-20 18:33 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 59055-done

On Sun, 20 Nov 2022, Ludovic Courtès <ludo@gnu.org> wrote:

> Did you try to come up with a reproducer?  That would be awesome but I
> guess it’s hard because you need to trigger EINTR at the right point.

With a stress test in guile-parallel.  Very hard to reproduce indeed.
You can also reproduce it with `ice-9 futures` I think.

Here's the stress test that I've been using:
--8<---------------cut here---------------start------------->8---
(use-modules
  ((ice-9 futures) #:prefix ice-9:)
  (srfi srfi-1)
  (srfi srfi-26))

(define (run-stress-test N future touch)
  (for-each
   touch
   (unfold
    (cut = N <>)
    (lambda (_)
      (future
       (const #t)))
    1+
    0)))

(run-stress-test 10000000 ice-9:make-future ice-9:touch)
--8<---------------cut here---------------end--------------->8---

-- 
Olivier Dion
oldiob.dev





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

end of thread, other threads:[~2022-11-20 18:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-05 16:59 bug#59055: [PATCH] Fix possible deadlock Olivier Dion via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-11-20 17:19 ` Ludovic Courtès
2022-11-20 18:33   ` Olivier Dion via Bug reports for GUILE, GNU's Ubiquitous Extension Language

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).