-
Bug
-
Resolution: Fixed
-
P2
-
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.
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.