emacs-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[debbugs-tracker] bug#10225: closed (Lock ordering mismatch)


From: GNU bug Tracking System
Subject: [debbugs-tracker] bug#10225: closed (Lock ordering mismatch)
Date: Thu, 23 Feb 2017 18:57:01 +0000

Your message dated Thu, 23 Feb 2017 19:56:25 +0100
with message-id <address@hidden>
and subject line Re: bug#10225: Lock ordering mismatch
has caused the debbugs.gnu.org bug report #10225,
regarding Lock ordering mismatch
to be marked as done.

(If you believe you have received this mail in error, please contact
address@hidden)


-- 
10225: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=10225
GNU Bug Tracking System
Contact address@hidden with problems
--- Begin Message --- Subject: Lock ordering mismatch Date: Mon, 05 Dec 2011 21:42:59 +0100 User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux)
This message from Ludovic on 1 July indicates a problem in our threading
code that we need to fix.

Andy

--- Begin Message --- Subject: Lock ordering mismatch Date: Fri, 01 Jul 2011 23:11:00 +0200 User-agent: Gnus/5.110017 (No Gnus v0.17) Emacs/24.0.50 (gnu/linux)
Hello,

As seen in ccb80964cd7cd112e300c34d32f67125a6d6da9a, there’s a lock
ordering mismatch between ‘do_thread exit’ and ‘fat_mutex_lock’
wrt. ‘t->admin_mutex’ and ‘m->lock’.

I thought this commit solved the problem, but now I think it doesn’t
because it leaves a small window during which a mutex could be held by a
thread without being part of its `mutexes' list, thereby violating the
invariant tested at line 667:

        /* Since MUTEX is in `t->mutexes', T must be its owner.  */
        assert (scm_is_eq (m->owner, t->handle));

So I reverted the patch.

(The situation isn’t better without the patch since
“while ./check-guile srfi-18.test threads.test ; do : ; done”
eventually hits the assertion failure.)

I tried the attached patch, which is inelegant and leads to deadlocks
with canceled threads (namely the “cancel succeeds” test in
threads.test.)

IOW I would welcome fresh ideas to approach the problem.  :-)

Thanks,
Ludo’.

        Modified libguile/threads.c
diff --git a/libguile/threads.c b/libguile/threads.c
index cbacfca..d537e0e 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -1353,12 +1353,24 @@ fat_mutex_lock (SCM mutex, scm_t_timespec *timeout, SCM 
owner, int *ret)
   fat_mutex *m = SCM_MUTEX_DATA (mutex);
 
   SCM new_owner = SCM_UNBNDP (owner) ? scm_current_thread() : owner;
+  scm_i_thread *t =
+    scm_is_true (new_owner) ? SCM_I_THREAD_DATA (new_owner) : NULL;
   SCM err = SCM_BOOL_F;
 
   struct timeval current_time;
 
-  scm_i_scm_pthread_mutex_lock (&m->lock);
+#define LOCK                                   \
+  if (t != NULL)                               \
+    scm_i_pthread_mutex_lock (&t->admin_mutex);        \
+  scm_i_pthread_mutex_lock (&m->lock)
+
+#define UNLOCK                                 \
+  scm_i_pthread_mutex_unlock (&m->lock);       \
+  if (t != NULL)                               \
+    scm_i_pthread_mutex_unlock (&t->admin_mutex)
 
+
+  LOCK;
   while (1)
     {
       if (m->level == 0)
@@ -1367,22 +1379,12 @@ fat_mutex_lock (SCM mutex, scm_t_timespec *timeout, SCM 
owner, int *ret)
          m->level++;
 
          if (SCM_I_IS_THREAD (new_owner))
-           {
-             scm_i_thread *t = SCM_I_THREAD_DATA (new_owner);
-
-             scm_i_pthread_mutex_unlock (&m->lock);
-             scm_i_pthread_mutex_lock (&t->admin_mutex);
-
-             /* Only keep a weak reference to MUTEX so that it's not
-                retained when not referenced elsewhere (bug #27450).
-                The weak pair itself is eventually removed when MUTEX
-                is unlocked.  Note that `t->mutexes' lists mutexes
-                currently held by T, so it should be small.  */
-             t->mutexes = scm_weak_car_pair (mutex, t->mutexes);
-
-             scm_i_pthread_mutex_unlock (&t->admin_mutex);
-             scm_i_pthread_mutex_lock (&m->lock);
-           }
+           /* Only keep a weak reference to MUTEX so that it's not
+              retained when not referenced elsewhere (bug #27450).
+              The weak pair itself is eventually removed when MUTEX
+              is unlocked.  Note that `t->mutexes' lists mutexes
+              currently held by T, so it should be small.  */
+           t->mutexes = scm_weak_car_pair (mutex, t->mutexes);
          *ret = 1;
          break;
        }
@@ -1425,13 +1427,18 @@ fat_mutex_lock (SCM mutex, scm_t_timespec *timeout, SCM 
owner, int *ret)
                }
            }
          block_self (m->waiting, mutex, &m->lock, timeout);
-         scm_i_pthread_mutex_unlock (&m->lock);
-         SCM_TICK;
-         scm_i_scm_pthread_mutex_lock (&m->lock);
+
+         /* UNLOCK; */
+         /* SCM_TICK; */
+         /* LOCK; */
        }
     }
-  scm_i_pthread_mutex_unlock (&m->lock);
+
+  UNLOCK;
+
   return err;
+#undef LOCK
+#undef UNLOCK
 }
 
 SCM scm_lock_mutex (SCM mx)


--- End Message ---

-- 
http://wingolog.org/

--- End Message ---
--- Begin Message --- Subject: Re: bug#10225: Lock ordering mismatch Date: Thu, 23 Feb 2017 19:56:25 +0100 User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux)
> As seen in ccb80964cd7cd112e300c34d32f67125a6d6da9a, there’s a lock
> ordering mismatch between ‘do_thread exit’ and ‘fat_mutex_lock’
> wrt. ‘t->admin_mutex’ and ‘m->lock’.

Happily with the thread-safety rewrite in 2.1.5 this is fixed!

Andy


--- End Message ---

reply via email to

[Prev in Thread] Current Thread [Next in Thread]