[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gnulib-bug
Subject:    Re: [PATCH]: gl_recursive_lock_init issue with pthread backend
From:       Bruno Haible <bruno () clisp ! org>
Date:       2007-11-30 15:41:20
Message-ID: 200711301641.20503.bruno () clisp ! org
[Download RAW message or body]

Yoann Vandoorselaere wrote:
> The gl_recursive_lock_init() macro used for the pthread backend never
> set the mutex attribute to be recursive. The end result is that a
> 'standard' mutex is created, which will deadlock on recursive use. A
> patch is attached that fixes this issue.

Indeed. Thanks for the patch. Instead of a macro with a large expansion,
let me create an auxiliary function in lock.c. I'm applying the patch below.

> Additionally, lock.h make use of the abort() function, which can be a
> problem if the application / library handle pthread error in a specific
> way. Is that done on purpose, or are you interested in a patch?

It was done out of laziness, and because I don't know what a better handling
of pthread_* function failures could look like. What do you propose?

Bruno


2007-11-30  Bruno Haible  <bruno@clisp.org>

	* lib/lock.h (gl_recursive_lock_init) [PTHREAD &&
	PTHREAD_RECURSIVE_MUTEX_INITIALIZER]: Call
	glthread_recursive_lock_init.
	* lib/lock.c (glthread_recursive_lock_init)
	[PTHREAD_RECURSIVE_MUTEX_INITIALIZER]: New function.
	Reported by Yoann Vandoorselaere <yoann.v@prelude-ids.com>.

--- lib/lock.h
+++ lib/lock.h
@@ -361,11 +361,11 @@ typedef pthread_mutex_t gl_recursive_lock_t;
        PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 #   endif
 #   define gl_recursive_lock_init(NAME) \
-      do                                                                  \
-        {                                                                 \
-          if (pthread_in_use () && pthread_mutex_init (&NAME, NULL) != 0) \
-            abort ();                                                     \
-        }                                                                 \
+      do                                          \
+        {                                         \
+          if (pthread_in_use ())                  \
+            glthread_recursive_lock_init (&NAME); \
+        }                                         \
       while (0)
 #   define gl_recursive_lock_lock(NAME) \
       do                                                            \
@@ -388,6 +388,7 @@ typedef pthread_mutex_t gl_recursive_lock_t;
             abort ();                                                  \
         }                                                              \
       while (0)
+extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
 
 #  else
 
--- lib/lock.c
+++ lib/lock.c
@@ -1,5 +1,5 @@
 /* Locking in multithreaded situations.
-   Copyright (C) 2005-2006 Free Software Foundation, Inc.
+   Copyright (C) 2005-2007 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -250,7 +250,24 @@ glthread_rwlock_destroy (gl_rwlock_t *lock)
 
 # if HAVE_PTHREAD_MUTEX_RECURSIVE
 
-#  if !(defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
+#  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+
+void
+glthread_recursive_lock_init (gl_recursive_lock_t *lock)
+{
+  pthread_mutexattr_t attributes;
+
+  if (pthread_mutexattr_init (&attributes) != 0)
+    abort ();
+  if (pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE) != 0)
+    abort ();
+  if (pthread_mutex_init (lock, &attributes) != 0)
+    abort ();
+  if (pthread_mutexattr_destroy (&attributes) != 0)
+    abort ();
+}
+
+#  else
 
 void
 glthread_recursive_lock_init (gl_recursive_lock_t *lock)



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic