From c56a1f6866b3861526a43e27e1c9e9912b2b4b48 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 22 Apr 2020 13:30:40 -0400 Subject: [PATCH] Fix: Java agent: handle partial payload read When reading from a TCP socket, there is no guarantee that the read will return all the requested data. We need to loop and continue reading until we gather all the expected data. This fixes flakiness of the lttng-ust-java-tests. Signed-off-by: Mathieu Desnoyers --- .../agent/client/LttngTcpSessiondClient.java | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java index c035e5e2..d42bc9af 100644 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java @@ -364,10 +364,17 @@ public class LttngTcpSessiondClient implements Runnable { */ private SessiondCommandHeader recvHeader() throws IOException { byte data[] = new byte[SessiondCommandHeader.HEADER_SIZE]; + int bytesLeft = data.length; + int bytesOffset = 0; - int readLen = this.inFromSessiond.read(data, 0, data.length); - if (readLen != data.length) { - throw new IOException(); + while (bytesLeft >= 0) { + int bytesRead = this.inFromSessiond.read(data, bytesOffset, bytesLeft); + + if (bytesRead < 0) { + throw new IOException(); + } + bytesLeft -= bytesRead; + bytesOffset += bytesRead; } return new SessiondCommandHeader(data); } @@ -381,15 +388,22 @@ public class LttngTcpSessiondClient implements Runnable { */ private byte[] recvPayload(SessiondCommandHeader headerCmd) throws IOException { byte payload[] = new byte[(int) headerCmd.getDataSize()]; + int bytesLeft = payload.length; + int bytesOffset = 0; /* Failsafe check so we don't waste our time reading 0 bytes. */ - if (payload.length == 0) { + if (bytesLeft == 0) { return null; } - int read = inFromSessiond.read(payload, 0, payload.length); - if (read != payload.length) { - throw new IOException("Unexpected number of bytes read in sessiond command payload"); + while (bytesLeft >= 0) { + int bytesRead = inFromSessiond.read(payload, bytesOffset, bytesLeft); + + if (bytesRead < 0) { + throw new IOException(); + } + bytesLeft -= bytesRead; + bytesOffset += bytesRead; } return payload; } -- 2.34.1