Java Question Blocking/non-blocking wait

divinglog

Member
Licensed User
Longtime User
Sorry for the confusing title, but this is a confusing and tricky topic for me. I'm wrapping a native code library which is constantly calling a "Read" function in my code until data arrives from a USB serial device. I have to block the read function until data arrives or a timeout happens but without blocking the remaining app code.

B4X:
//Java code called from native code library:
private int Read(long userdata, byte[] data, int size, int[] actual) {
    return ba.raiseEvent(this, eventName + "_read", userdata, data, size, actual);
}

B4X:
'Event raised from Java:
Private Sub LibDC_Read(Userdata As Long, Data() As Byte, Size As Int, Actual() As Int) As ResumableSub
    Dim bc As ByteConverter
    Dim actsize As Int = 0
    
    Do Until BytesBuilder.Length > ReadIdx
        Sleep(100)
    Loop
        
    If ReadIdx + Size < BytesBuilder.Length Then
        actsize = Size
    Else
        actsize = BytesBuilder.Length - ReadIdx
    End If
    
    Dim TempArr(actsize) As Byte = BytesBuilder.SubArray2(ReadIdx, ReadIdx + actsize)
    bc.ArrayCopy(TempArr, 0, Data, 0, actsize)
    Actual(0) = actsize
    ReadIdx = ReadIdx + actsize
    
    Return LibDC.DC_STATUS_SUCCESS
    
End Sub

'Raised from USBSerial library
Private Sub USBSerial_DataAvailable(Buffer() As Byte)
    BytesBuilder.Append(Buffer)
End Sub

So, I'm receiving data from the USB Serial device and put that into a byte buffer which is then returned back to native code in the "Read" event. The code works but there is one problem. The USBSerial_DataAvailable event is not called because the LibDC_Read event is constantly called from native code as soon as it returns.

So I have to block the LibDC_Read code from returning until data is available, which should be done in the Do Until loop. But this is not working as I would expect. I've also tried jo.InitializeStatic("java.lang.Thread").RunMethod("sleep", Array(100)) instead of Sleep(100), but it does not work either.

I need a way to block the LibDC_Read function from returning without blocking the remaing app code, so the USBSerial_DataAvailable event is still called to fetch the data. Any ideas how to achive that? Maybe with the threading library?
 

divinglog

Member
Licensed User
Longtime User
I've just found this tutorial and it looks like I have to do the sleep loop in Java in a different thread. This should avoid blocking the UI thread.
 
Top