import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; /* Trying to reproduce the scenario when Glide got blocked trying to close a socket because it called read() with timeout but got stuck trying to acquire the read lock in JDK library. Run with: javac SocketTimeoutNotRespected.java && java SocketTimeoutNotRespected The output: server started on port 3434 blocker thread started on port 3434 thread2 is reading from port 3434 with timeout 500 ... waiting forever ... "blocker" thread stack: read0:-1, SocketDispatcher (sun.nio.ch) read:47, SocketDispatcher (sun.nio.ch) tryRead:266, NioSocketImpl (sun.nio.ch) implRead:317, NioSocketImpl (sun.nio.ch) read:355, NioSocketImpl (sun.nio.ch) read:808, NioSocketImpl$1 (sun.nio.ch) read:966, Socket$SocketInputStream (java.net) read:961, Socket$SocketInputStream (java.net) lambda$main$1:71, SocketTimeoutNotRespected run:-1, SocketTimeoutNotRespected$$Lambda$18/0x000000014d000c28 run:840, Thread (java.lang) "main" thread stack: park:-1, Unsafe (jdk.internal.misc) park:211, LockSupport (java.util.concurrent.locks) acquire:715, AbstractQueuedSynchronizer (java.util.concurrent.locks) acquire:938, AbstractQueuedSynchronizer (java.util.concurrent.locks) lock:153, ReentrantLock$Sync (java.util.concurrent.locks) lock:322, ReentrantLock (java.util.concurrent.locks) read:348, NioSocketImpl (sun.nio.ch) read:808, NioSocketImpl$1 (sun.nio.ch) read:966, Socket$SocketInputStream (java.net) read:961, Socket$SocketInputStream (java.net) main:91, SocketTimeoutNotRespected */ public class SocketTimeoutNotRespected { private static final int PORT = 3434; // Anu open port of your choice public static void main(String[] args) throws Exception { Thread server = new Thread(() -> { try (ServerSocket serverSocket = new ServerSocket(PORT)) { final Socket connectedSocket = serverSocket.accept(); int c = connectedSocket.getInputStream().read(); System.err.printf("Not expected: the server has received data: %d ('%c')\n", c, c); } catch (IOException e) { System.err.println("unexpected server exception: " + e.getMessage()); e.printStackTrace(); } }); server.setName("server"); server.setDaemon(true); server.start(); System.out.println("server started on port " + PORT); // client threads share the socket Socket clientSocket = new Socket("localhost", PORT); // The blocker thread blocks is reading data forever. It is holding readLock while waiting Thread blocker = new Thread(() -> { try { int c = clientSocket.getInputStream().read(); System.err.printf("Not expected: the blocker thread has received data: %d ('%c')\n", c, c); } catch (IOException e) { System.err.println("unexpected blocker thread exception: " + e.getMessage()); e.printStackTrace(); } }); blocker.setName("blocker"); blocker.setDaemon(true); blocker.start(); System.out.println("blocker thread started on port " + PORT); // Sleep a bit to let "blocker" start the read Thread.sleep(100); // We should exit with timeout, but since the "blocker" thread is holding the reentrantLock // and the JDK tries to acquire it unconditionally, the socket timeout is not respected try { clientSocket.setSoTimeout(500); System.out.println("thread2 is reading from port " + PORT + " with timeout " + clientSocket.getSoTimeout()); int c = clientSocket.getInputStream().read(); // <<<<<<<<<< gets stuck trying to obtain a reentrant lock w/o timeout System.err.printf("thread2 has unexpectedly received data: %d ('%c')\n", c, c); } catch (SocketTimeoutException e) { System.out.println("thread2 has failed with timeout, good"); } } }