Fix: Java agent: handle partial payload read
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 22 Apr 2020 17:30:40 +0000 (13:30 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 22 Apr 2020 17:32:57 +0000 (13:32 -0400)
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 <mathieu.desnoyers@efficios.com>
liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java

index c035e5e2e31043d4899ba2dc1bf1ee940ad249e7..0f979a4f88da7d7fa97da19c6786f0dcc9fe1e90 100644 (file)
@@ -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;
        }
This page took 0.025381 seconds and 4 git commands to generate.