0

I have implemented a multithreaded application using pthread. In this application there are two threads:

  • The first polls a tap port in order to read the available data and write it to a serial port to which a radio is connected.
  • The second vice versa polls the serial port and then writes the data to the tap port.

To avoid data race problems before accessing a port (serial or tap) I use a pthread_mutex_t. On https://man7.org/linux/man-pages/man7/pthreads.7.html I read that read() and write() are cancellation points, that is, they are points where a thread can potentially be canceled.

Pseudo-Code Example:

pthread_mutex_t serial_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t tap_mutex = PTHREAD_MUTEX_INITIALIZER;
atomic_bool continue = true;
//T1
void* run(void* vargp)
{
    int poll_timeout = 1000;
    while (continue)
    {
        int poll_result = poll(&tap_fd, 1, poll_timeout);
        if (poll_result != -1 && poll_result != 0)
        {
            if (tap_fd.revents & POLLIN)
            {
                pthread_mutex_lock(&tap_mutex);
                int tap_len = read(tap, tap_buffer, sizeof(tap_buffer));
                pthread_mutex_unlock(&tap_mutex);
                if(tap_len >= MIN_SIZE)
                {
                    /*
                    In reality, the contents of the tap buffer are preprocessed and the 
                    contents of another buffer are written to the serial 
                     */
                    pthread_mutex_lock(&serial_mutex);
                    int r = write(serial, tap_buffer, tap_len);
                    pthread_mutex_unlock(&serial_mutex);
                }
            }

        }
}
//T2 is completely analogous to the previous one

Since read and write are both performed in a critical section, would the mutex be automatically released if the thread were to be canceled? And if not, how can I guarantee the release of the relative mutex?

cicciob95
  • 1
  • 1

1 Answers1

0

would the mutex be automatically released if the thread were to be canceled?

No.

And if not, how can I guarantee the release of the relative mutex?

The best way is to follow the first rule of pthread_cancel(): never call pthread_cancel(). Really, don't cancel threads. It's bad news.

Another thing you could do is use pthread_setcancelstate() before and after the critical section to disable thread cancellation within.

But also, POSIX does have a facility for handling cleanup from thread cancellations. You can use pthread_cleanup_push() to register a callback to perform the needed cleanup, and pthread_cleanup_pop() after the critical section to remove it again. For this mechanism to adequately protect you, the thread's cancellation type must (always) be 'deferred', and you must take great care to consistently manage the cleanup handler stack. If that sounds like a lot of work, that's because it is. Refer to the first rule of pthread_cancel().

John Bollinger
  • 160,171
  • 8
  • 81
  • 157