Столкнулся _возможно_ с багом функции pthread_mutex_unlock().
Вот код:
/*
* Compile:
* cc -Wall -O0 -g -ggdb -c -o pthunlk.o pthunlk.c
* cc -lpthread pthunlk.o -o pthunlk
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int main(int argc, char *argv[])
{
int err;/* unlock without lock */
err = pthread_mutex_unlock(&lock);
if (err != 0 )
fprintf(stderr, "mutex_unlock() failed -> errno #%d (%s)\n", err, strerror(err));err = pthread_mutex_destroy(&lock);
if ( err != 0 ) {
fprintf(stderr, "mutex_destroy() failed -> errno #%d (%s)\n", err, strerror(err));
}exit(EXIT_SUCCESS);
}$ ./pthunlk
mutex_destroy() failed -> errno #16 (Device or resource busy)$ getconf GNU_LIBC_VERSION
glibc 2.3.6
$ getconf GNU_LIBPTHREAD_VERSION
NPTL 2.3.6Самое интересное, если между unlock() и destroy() вызвать lock()/trylock(),
то destroy() не сообщает ошибок.Если бы мьютекс был бы рекурсивным, можно было бы предположить
что проблема в знаковом счётчике блокировок,
но мьютекс-то обычный.
>Если бы мьютекс был бы рекурсивным, можно было бы предположить
>что проблема в знаковом счётчике блокировок,
>но мьютекс-то обычный.Обычный, потому и не проверяет ошибки.
If the mutex type is PTHREAD_MUTEX_NORMAL, deadlock detection shall not be provided. Attempting to relock the mutex causes deadlock. If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, undefined behavior results.
Хочешь проверки — пользуйся PTHREAD_MUTEX_ERRORCHECK