====== Pain isn't always in code ====== “Sciatic pain syndrome”. Three simple words, but I tell you, they can turn your world into a swamp of misery. Just like the code we have to endure sometimes. So bear with me if this post isn’t the same quality as the others. These days I had to refactor some code to make it thread-safe. Oh, it had [[https://computing.llnl.gov/tutorials/pthreads/ | POSIX Threads Library]] (pthread) mutexes in it allright, added by the original coder. Since the code was C++, and having to manually release a mutex is cumbersome if you can have destructors, he added a wrapper class for the mutexes. But later on, some other developer discovered that some code tried to re-lock a mutex already locked by the thread. (The bane of historically-grown software that gets extended beyond its initial conception.) As the default behaviour of pthread mutexes in this case is to deadlock (to save the additional clock-cycles required to test for the condition), this developer added a ''bool isLocked'' to the class. Needless to say, querying / setting the boolean and locking / unlocking the thread isn’t an atomic operation, so what we’ve got was a nice little race condition. Hey, no problemo, the pthread library offers a way to add error-checking to a mutex, which would be the solution to our problem. The problem being the completely braindead way pthread mutexes are initialized. Behold, a default pthread mutex, defined at global scope: pthread_mutex_t default_mutex = PTHREAD_MUTEX_INITIALIZER; There you go, a mutex, initialized with default attributes and ready to use. Now, how about having some error-checking to go with it? Erm… please allow me to write this without error handling, it’s long enough as it is: pthread_mutex_t errorchecking_mutex; pthread_once_t mutex_init_once = PTHREAD_ONCE_INIT; void init_mutex() { pthread_mutexattr_t mutexattr; pthread_mutexattr_init( &mutexattr ); pthread_mutexattr_settype( &mutexattr, PTHREAD_MUTEX_ERRORCHECK ); pthread_mutex_init( &errorchecking_mutex, &mutexattr ); pthread_mutexattr_destroy( &mutexattr ); } void init() { pthread_once( &mutex_init_once, mutex_init ); // ... } //Ye flipping gods//. I can understand that a mutex might be a difficult data structure that cannot be set up by OR-ing together some values as most other APIs do, but this is //insane//. You have to set up, init, and modify an “attribute object”, which is then passed (by reference, why?) to the init routine for the mutex. I added the ''destroy()'' function allthough the documentation doesn’t say I have to, but given the nature of POSIX documentation, who knows whether I would leak memory if I didn’t. It smells like it, anyway. And of course I have to protext the whole shebang against concurrent initialization, because I can’t do it statically, and as this is a library I don’t have control over ''int main()'' to do it there. I cannot help but stare in awe at this example of… I don’t even know what it’s an example //for//, but I am awed nevertheless. And here I am at a word count of almost 500, and I haven’t even told you about the odyssey of piecing together the code above from the manpages (''pthread_mutex_lock()'' mentioning ''PTHREAD_MUTEX_ERRORCHECK'' but not having a reference to ''pthread_mutex_init()'' not having a reference to ''pthread_mutexattr_init()'' not having a reference to ''pthread_mutexattr_settype()'')…