PDA

View Full Version : slimproto has pthread issues on NetBSD



leuzi
2007-09-13, 15:49
Hi!

I managed to build squeezeslave on NetBSD. However, there seem to be some pthread issues with the slimproto library and NetBSD's pthread library (which seems to be a bit picky).

Running squeezeslave results in a core dump:



chris@charon:~/SlimProtoLib$ ./bin/squeezeslave
Output devices:
0: /dev/audio
squeezeslave: Error detected by libpthread: Unlocking mutex owned by another thread.
Detected by file "/home/builds/ab/netbsd-4/src/lib/libpthread/pthread_mutex.c", line 365, function "pthread_mutex_unlock".
See pthread(3) for information.
Abort trap (core dumped)


I'm not familiar with POSIX threads, so I'm a bit at a loss here. Any hints?

Cheers,
Christoph

leuzi
2007-09-14, 03:21
Some printf() debugging shows that the (first) problem is the call to pthread_cond_wait() in proto_thread() (I think):



case PROTO_CLOSED:
r = pthread_cond_wait(&p->slimproto_cond, &p->slimproto_mutex);
break;

If I got the docs right, this call means that the calling thread releases the mutex and waits for the condition to become true. It then tries to obtain the mutex again, right?

So the "Unlocking mutex owned by another thread." message maybe is related to the release of the mutex? I don't understand this though, because the proto_thread actually has obtained the mutex first thing in proto_thread() ...

I'm confused. :-/

Christoph

awy
2007-09-14, 03:30
I think that the following code may be relevant:


int slimaudio_output_open(slimaudio_t *audio) {
pthread_mutex_init(&(audio->output_mutex), NULL);
pthread_cond_init(&(audio->output_cond), NULL);

/*
* We take the mutex here and release it in the output thread to prevent
* other threads from using the audio output information while it is
* being initialized.
*/
pthread_mutex_lock(&audio->output_mutex);

audio->output_state = STOPPED;

if (pthread_create( &audio->output_thread, NULL, output_thread, (void*) audio) != 0) {


I noticed this a few days ago and thought it looked a bit suspicious. It is clearly wrong.

Alan.

Dominique
2007-10-02, 22:30
/*
* We take the mutex here and release it in the output thread to prevent
* other threads from using the audio output information while it is
* being initialized.
*/
pthread_mutex_lock(&audio->output_mutex);


I noticed this a few days ago and thought it looked a bit suspicious. It is clearly wrong.

Alan.

This code and comment are my doing.

It may be wrong in terms of mutex ownership, but it does prevent the described race condition, at least on Linux. Any rework of this should make sure that no other thread can acquire the output_mutex before the initialization is completed and the output thread has reached the pthread_cond_wait/timedwait in output_thread.

I have been accidentally relying on the fact that, on Linux, pthread mutexes are not error-checking, which seems to not be the case for NetBSD. On Linux, mutexes are by default 'fast' which means non-error-checking (which is documented to be non-portable, as I have just learned). I was using this fact to simulate that the mutex was locked upon creation.

One way to fix this would be to perform all the output stream config from slimaudio_output_open. One less elegant way would be to explicitly set this mutex to be 'fast'.

Let me know if I can be of any help. I guess to prevent further problems we could explicitly set all mutexes to be error-checking, so the Linux would also be reporting the errors.

Hope I have not repeated this pattern elsewhere...

Dominique