Race condition prevents UART "write" call from returning
Curran D. Muhlberger
curran at muhlbergerweb.com
Sat Sep 13 20:49:46 UTC 2014
One minor correction to my previous email: Contrary to my claim, the
`waitForSignal` method doesn't quite handle the case when a signal already
exists (though it looks like it was meant to). It neglects to assign to
`sig` the result of its `findTarget` call (leading to a null-pointer
dereference if the signal does exist). Adding this assignment lets my
patch work as expected, at least in my limited testing.
- Curran
On Sat, Sep 13, 2014 at 1:11 PM, Curran D. Muhlberger <
curran at muhlbergerweb.com> wrote:
> Hello again DIO developers,
>
> There appears to be a bug in how completed writes are signaled that can
> prevent the UART `write` method from returning if a race condition is
> satisfied. Worse, the race condition seems to be satisfied most of the
> time.
>
> The relevant function is `Java_com_oracle_dio_uart_impl_UARTImpl_write0`
> in "jni_uart.cpp". Basically, the code copies the data into a
> newly-allocated buffer, signals a separate "write thread" that the buffer
> is ready, then waits for a signal indicating that the write has completed.
> However, after waking the "write thread", it is possible for that thread
> to finish its work and send the "write complete" signal before the JNI
> thread has had a chance to start listening. The JNI thread will the wait
> forever for a signal that has already been sent, causing the program to
> hang.
>
> To reproduce this problem reliably, simply add a `sleep` call at line 242
> of "jni_uart.cpp" (just before it calls `waitForSignal`), then try to
> invoke the `write` method on a UART device. The method will never return.
>
> I'm not sure how the DIO signaling infrastructure is designed to work, so
> I defer to the core developers on how best to fix this problem. However, I
> did find a patch that seems to do the job. In the `generateSignal`
> function in "dio_common.cpp", if `findTarget` returns NULL, then
> `generateSignal` can create a new signal and add it to the list, so that a
> call to `javacall_os_cond_signal` is made regardless of whether a signal
> already existed or not. It turns out that the `waitForSignal` method
> already handles this case - if a signal for the target already exists, it
> simply waits on it instead of creating a new one. With this small patch, I
> can make multiple `write` calls to a UART device without problems.
>
> Thank you for taking a look at this issue.
>
> - Curran
>
More information about the dio-dev
mailing list