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 18:20:12 +0000 (14:20 -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..d42bc9af4ee112c105ee48605b58c1c98843ba09 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.026608 seconds and 4 git commands to generate.