diff --git a/src/main/java/net/ladenthin/streambuffer/StreamBuffer.java b/src/main/java/net/ladenthin/streambuffer/StreamBuffer.java index 78d3f21..e70d71f 100644 --- a/src/main/java/net/ladenthin/streambuffer/StreamBuffer.java +++ b/src/main/java/net/ladenthin/streambuffer/StreamBuffer.java @@ -796,6 +796,7 @@ public int read() throws IOException { } } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new IOException(e); } @@ -852,6 +853,7 @@ public int read(final byte b[], final int off, final int len) throws IOException try { maximumAvailableBytes = tryWaitForEnoughBytes(missingBytes); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new IOException(e); } diff --git a/src/test/java/net/ladenthin/streambuffer/StreamBufferTest.java b/src/test/java/net/ladenthin/streambuffer/StreamBufferTest.java index 590504c..11d2042 100644 --- a/src/test/java/net/ladenthin/streambuffer/StreamBufferTest.java +++ b/src/test/java/net/ladenthin/streambuffer/StreamBufferTest.java @@ -2409,6 +2409,7 @@ public void read_threadInterrupted_throwsIOException() throws Exception { final InputStream is = sb.getInputStream(); final Semaphore started = new Semaphore(0); final Throwable[] caught = new Throwable[1]; + final AtomicBoolean interruptFlagAfterCatch = new AtomicBoolean(false); Thread reader = new Thread(() -> { try { @@ -2416,6 +2417,7 @@ public void read_threadInterrupted_throwsIOException() throws Exception { is.read(); // will block — no data, not closed } catch (IOException e) { caught[0] = e; + interruptFlagAfterCatch.set(Thread.currentThread().isInterrupted()); } }); @@ -2429,6 +2431,8 @@ public void read_threadInterrupted_throwsIOException() throws Exception { // assert assertThat("IOException should be thrown wrapping InterruptedException", caught[0] instanceof IOException, is(true)); + assertThat("Thread interrupt flag must be preserved after wrapping InterruptedException", + interruptFlagAfterCatch.get(), is(true)); } @DisplayName("read(): array thread interrupted while waiting for second byte — throws io exception") @@ -2440,6 +2444,7 @@ public void read_arrayThreadInterruptedWhileWaitingForSecondByte_throwsIOExcepti final OutputStream os = sb.getOutputStream(); final Semaphore started = new Semaphore(0); final Throwable[] caught = new Throwable[1]; + final AtomicBoolean interruptFlagAfterCatch = new AtomicBoolean(false); // write exactly 1 byte so the internal read() at the start of read(b,off,len) // succeeds immediately, then tryWaitForEnoughBytes blocks waiting for the second byte @@ -2451,6 +2456,7 @@ public void read_arrayThreadInterruptedWhileWaitingForSecondByte_throwsIOExcepti is.read(new byte[2], 0, 2); } catch (IOException e) { caught[0] = e; + interruptFlagAfterCatch.set(Thread.currentThread().isInterrupted()); } }); @@ -2464,6 +2470,8 @@ public void read_arrayThreadInterruptedWhileWaitingForSecondByte_throwsIOExcepti // assert assertThat("IOException should be thrown wrapping InterruptedException", caught[0] instanceof IOException, is(true)); + assertThat("Thread interrupt flag must be preserved after wrapping InterruptedException", + interruptFlagAfterCatch.get(), is(true)); } }