Uploaded image for project: 'Device I/O '
  1. Device I/O
  2. DIO-18

Race condition inside UART.write() driven by pthread_cond_wait spurious wakeups

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P2 P2
    • jdk.dio.uart
    • None

      There are two points where race condition can occur:

      1. JNIEXPORT jint JNICALL Java_com_oracle_dio_uart_impl_UARTImpl_write0
      is doing consequently:

                      result = javacall_uart_write_start(handle,
                                                         (unsigned char*)(directArray + pos + off),
                                                         lim - pos,
                                                         &bytesWritten,
                                                         &context);
      ...
              result = waitForSignal(COMM_WRITE_SIGNAL, getDeviceHandle(device), &status, 0);
      ...
                          result = javacall_uart_write_finish(handle,
                                                              (unsigned char*)(directArray + pos + off),
                                                              lim - pos,
                                                              &bytesWritten,
                                                              context);

      The problem is that waitForSignal() is implemented through pthread_cond_wait() that doesn't always
      wait until condition is reached, and the thread can wake up spuriously.

      As the consequence,

      javacall_result jc_serial_write_common(serial_handle handle,
              unsigned char *buffer, int size, int* bytesWritten) {

      may overwrite (serial_handle)handle->out_buffer for the buffer that wasn't yet processed
      by write_thread request done by javacall_uart_write_start



      2.
      2.1 jc_serial_write_common() does the following
           - prepares new out_buffer of the handle
           - Runs the sequence
              pthread_mutex_lock(&p->write_lock);
              pthread_cond_signal(&p->out_buffer_ready);
              pthread_mutex_unlock(&p->write_lock);

      2.2 while write_thread does the following:
         - copies out_buffer to temp buffer
         - writes temp buffer
         - pthread_cond_wait(&p->out_buffer_ready, &p->write_lock);
           Now it is expected to be unblocked by

      The problem here is:
        - pthread_cond_wait can unblock the thread not due to pthread_cond_signal,
          but in any amount of time. As the consequence, we will observe a race condition
          like e.g., freeing the buffer (next jc_serial_write_common calls to cleanup_write_buffer() due to
          out_total_written is involved into a race condition etc.)
          that is curently being written to the UART by another thread etc.

            onazarkina Olga Nazarkina (Inactive)
            onazarkina Olga Nazarkina (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: