Thank you for the report. I would say that normally, it is questionable to initialize and acquire thd->ctrl_mutex in the same function. If the acquisition is really necessary for correctness, it feels like there would be a race condition for the time window before the mutex was acquired.
In fact, all thd->ctrl_mutex should be unreachable to other threads except those that are being created by pthread_create() in create_worker_threads(). That is because the pointer to the array threads is local to the function create_worker_threads() until it is returned to the caller.
In fact, there is a double-unlock of the mutex in case any of the goto err is invoked.
Neither thd->ctrl_cond, thd->ctrl_mutex, nor thd->started are needed at all. We already clear thd->data_avail and thd->cancelled before calling pthread_create(). The logic around thd->data_mutex and thd->data_cond should suffice.
I spotted also a resource leak in the error handling code path: we would fail to stop already created threads and free the memory buffer.
Thank you for the report. I would say that normally, it is questionable to initialize and acquire thd->ctrl_mutex in the same function. If the acquisition is really necessary for correctness, it feels like there would be a race condition for the time window before the mutex was acquired.
In fact, all thd->ctrl_mutex should be unreachable to other threads except those that are being created by pthread_create() in create_worker_threads(). That is because the pointer to the array threads is local to the function create_worker_threads() until it is returned to the caller.
In fact, there is a double-unlock of the mutex in case any of the goto err is invoked.
Neither thd->ctrl_cond, thd->ctrl_mutex, nor thd->started are needed at all. We already clear thd->data_avail and thd->cancelled before calling pthread_create(). The logic around thd->data_mutex and thd->data_cond should suffice.
I spotted also a resource leak in the error handling code path: we would fail to stop already created threads and free the memory buffer.