1
0
mirror of https://github.com/mik3y/usb-serial-for-android synced 2025-06-07 16:06:10 +00:00

Merge pull request #351 from lambdapioneer/master

Use monotonic clock for timeouts
This commit is contained in:
kai-morich 2021-03-18 08:11:26 +01:00 committed by GitHub
commit 2d4d2f78a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 11 deletions

View File

@ -12,6 +12,8 @@ import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbRequest; import android.hardware.usb.UsbRequest;
import android.util.Log; import android.util.Log;
import com.hoho.android.usbserial.util.MonotonicClock;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.EnumSet; import java.util.EnumSet;
@ -178,11 +180,11 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
// /system/lib64/libusbhost.so (usb_request_wait+192) // /system/lib64/libusbhost.so (usb_request_wait+192)
// /system/lib64/libandroid_runtime.so (android_hardware_UsbDeviceConnection_request_wait(_JNIEnv*, _jobject*, long)+84) // /system/lib64/libandroid_runtime.so (android_hardware_UsbDeviceConnection_request_wait(_JNIEnv*, _jobject*, long)+84)
// data loss / crashes were observed with timeout up to 200 msec // data loss / crashes were observed with timeout up to 200 msec
long endTime = testConnection ? System.currentTimeMillis() + timeout : 0; long endTime = testConnection ? MonotonicClock.millis() + timeout : 0;
int readMax = Math.min(dest.length, MAX_READ_SIZE); int readMax = Math.min(dest.length, MAX_READ_SIZE);
nread = mConnection.bulkTransfer(mReadEndpoint, dest, readMax, timeout); nread = mConnection.bulkTransfer(mReadEndpoint, dest, readMax, timeout);
// Android error propagation is improvable, nread == -1 can be: timeout, connection lost, buffer undersized, ... // Android error propagation is improvable, nread == -1 can be: timeout, connection lost, buffer undersized, ...
if(nread == -1 && testConnection && System.currentTimeMillis() < endTime) if(nread == -1 && testConnection && MonotonicClock.millis() < endTime)
testConnection(); testConnection();
} else { } else {
@ -205,7 +207,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
@Override @Override
public void write(final byte[] src, final int timeout) throws IOException { public void write(final byte[] src, final int timeout) throws IOException {
int offset = 0; int offset = 0;
final long endTime = (timeout == 0) ? 0 : (System.currentTimeMillis() + timeout); final long endTime = (timeout == 0) ? 0 : (MonotonicClock.millis() + timeout);
if(mConnection == null) { if(mConnection == null) {
throw new IOException("Connection closed"); throw new IOException("Connection closed");
@ -229,7 +231,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
if (timeout == 0 || offset == 0) { if (timeout == 0 || offset == 0) {
requestTimeout = timeout; requestTimeout = timeout;
} else { } else {
requestTimeout = (int)(endTime - System.currentTimeMillis()); requestTimeout = (int)(endTime - MonotonicClock.millis());
if(requestTimeout == 0) if(requestTimeout == 0)
requestTimeout = -1; requestTimeout = -1;
} }
@ -241,7 +243,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
} }
Log.d(TAG, "Wrote " + actualLength + "/" + requestLength + " offset " + offset + "/" + src.length + " timeout " + requestTimeout); Log.d(TAG, "Wrote " + actualLength + "/" + requestLength + " offset " + offset + "/" + src.length + " timeout " + requestTimeout);
if (actualLength <= 0) { if (actualLength <= 0) {
if (timeout != 0 && System.currentTimeMillis() >= endTime) { if (timeout != 0 && MonotonicClock.millis() >= endTime) {
SerialTimeoutException ex = new SerialTimeoutException("Error writing " + requestLength + " bytes at offset " + offset + " of total " + src.length + ", rc=" + actualLength); SerialTimeoutException ex = new SerialTimeoutException("Error writing " + requestLength + " bytes at offset " + offset + " of total " + src.length + ", rc=" + actualLength);
ex.bytesTransferred = offset; ex.bytesTransferred = offset;
throw ex; throw ex;

View File

@ -12,6 +12,8 @@ import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbDeviceConnection;
import android.util.Log; import android.util.Log;
import com.hoho.android.usbserial.util.MonotonicClock;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
@ -146,11 +148,11 @@ public class FtdiSerialDriver implements UsbSerialDriver {
} }
int nread; int nread;
if (timeout != 0) { if (timeout != 0) {
long endTime = System.currentTimeMillis() + timeout; long endTime = MonotonicClock.millis() + timeout;
do { do {
nread = super.read(dest, Math.max(1, (int)(endTime - System.currentTimeMillis())), false); nread = super.read(dest, Math.max(1, (int)(endTime - MonotonicClock.millis())), false);
} while (nread == READ_HEADER_LENGTH && System.currentTimeMillis() < endTime); } while (nread == READ_HEADER_LENGTH && MonotonicClock.millis() < endTime);
if(nread <= 0 && System.currentTimeMillis() < endTime) if(nread <= 0 && MonotonicClock.millis() < endTime)
testConnection(); testConnection();
} else { } else {
do { do {

View File

@ -17,6 +17,7 @@ import android.hardware.usb.UsbInterface;
import android.util.Log; import android.util.Log;
import com.hoho.android.usbserial.BuildConfig; import com.hoho.android.usbserial.BuildConfig;
import com.hoho.android.usbserial.util.MonotonicClock;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
@ -174,9 +175,9 @@ public class ProlificSerialDriver implements UsbSerialDriver {
try { try {
while (!mStopReadStatusThread) { while (!mStopReadStatusThread) {
byte[] buffer = new byte[STATUS_BUFFER_SIZE]; byte[] buffer = new byte[STATUS_BUFFER_SIZE];
long endTime = System.currentTimeMillis() + 500; long endTime = MonotonicClock.millis() + 500;
int readBytesCount = mConnection.bulkTransfer(mInterruptEndpoint, buffer, STATUS_BUFFER_SIZE, 500); int readBytesCount = mConnection.bulkTransfer(mInterruptEndpoint, buffer, STATUS_BUFFER_SIZE, 500);
if(readBytesCount == -1 && System.currentTimeMillis() < endTime) if(readBytesCount == -1 && MonotonicClock.millis() < endTime)
testConnection(); testConnection();
if (readBytesCount > 0) { if (readBytesCount > 0) {
if (readBytesCount != STATUS_BUFFER_SIZE) { if (readBytesCount != STATUS_BUFFER_SIZE) {

View File

@ -0,0 +1,14 @@
package com.hoho.android.usbserial.util;
public final class MonotonicClock {
private static final long NS_PER_MS = 1_000_000;
private MonotonicClock() {
}
public static long millis() {
return System.nanoTime() / NS_PER_MS;
}
}