Recursive TMutex locking patch for MacOS/Linux

Archives Forums/BlitzMax Bug Reports/Recursive TMutex locking patch for MacOS/Linux

N(Posted 2009) [#1]
Since mutexes under Windows seem to be recursive by default (and I couldn't figure out a way to change this), and I wanted recursive locking in BMax, I made a quick change to threads_CreateMutex:
diff --git a/threads.c b/threads.c
index 4936a72..d934cac 100644
--- a/threads.c
+++ b/threads.c
@@ -239,9 +239,21 @@ BBObject *threads_GetThreadData( BBThreadData *data ){
 	return p ? (BBObject*)p : &bbNullObject;
 }
 
+#ifndef PTHREAD_MUTEX_RECURSIVE
+#ifndef PTHREAD_MUTEX_RECURSIVE_NP
+#error PTHREAD_MUTEX_RECURSIVE_NP undefined
+#else
+#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
+#endif
+#endif
+
 BBMutex *threads_CreateMutex(){
 	BBMutex *mutex=(BBMutex*)GC_malloc( sizeof( BBMutex ) );
-	if( pthread_mutex_init( &mutex->handle,0 )<0 ) return 0;
+    pthread_mutexattr_t attr;
+    if ( pthread_mutexattr_init(&attr)<0 ||
+         pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE)<0 || 
+         pthread_mutex_init( &mutex->handle, &attr ) )
+        return 0;
 	return mutex;
 }
 

This should make threaded code behave the same under MacOS and Linux as it would under Windows, whereas previously Linux/MacOS locks were not recursive (which may have resulted in some odd behavior for some folks, I don't know - I never noticed this until I started porting the Java collections code to BMax).

Edit: I do wonder why pthread_mutex_lock isn't returning EDEADLK or another error when locking twice in the same thread using the default mutex type, though. Edit 2: Scratch that, the default mutex type doesn't do error checking, so you'd have to use PTHREAD_MUTEX_ERRORCHECK if you wanted to get an error..

(Note: would be nice to have both reentrant and regular mutexes)


N(Posted 2009) [#2]
Looks like Linux (or at least whatever Linux Mint comes with) doesn't define PTHREAD_MUTEX_RECURSIVE and instead uses PTHREAD_MUTEX_RECURSIVE_NP, so I added a define for it. It's somewhat ironic to me that the implementation of portable threads in Linux Mint (and probably other Linux distros) is not portable...


Otus(Posted 2009) [#3]
Thanks, this explains my weird results on Linux.

This needs to get included in the next release.

Edit: Should actually be a bug report?