Killing a thread will block if there is another process reading from a handle
When trying to kill a thread, the program (which uses a thread) hangs if there is another process trying to read from a handle. This bug can be reproduced with using this sample code. I'll explain the relevant details below.
I have the following Haskell code:
someFuncWithChans :: IO ()
someFuncWithChans = withSocketsDo $ do
h <- connectTo "localhost" (PortNumber 9090)
hSetBuffering h NoBuffering
ch <- newChan
putStrLn "Starting the handler reader"
readerTid <- forkIO $ handleReader h ch
cmdsHandler h ch
putStrLn "Killing the handler reader"
killThread readerTid
putStrLn "Closing the handle"
hClose h
cmdsHandler :: Handle -> Chan Action -> IO ()
cmdsHandler h ch = do
act <- readChan ch
case act of
Quit -> putStrLn "Bye bye"
Line line -> do
hPutStrLn h (reverse line)
cmdsHandler h ch
handleReader :: Handle -> Chan Action -> IO ()
handleReader h ch = forever $ do
line <- strip <$> hGetLine h
case line of
"quit" -> writeChan ch Quit
_ -> writeChan ch (Line line)
data Action = Quit | Line String
Is the function someFuncWithChans
is run along with the following Java program, then the former will block while killing the handler reader (readerTid
).
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket serverSock = new ServerSocket(9090);
Socket sock = serverSock.accept();
InputStream inStream = sock.getInputStream();
BufferedReader sockIn = new BufferedReader(new InputStreamReader(inStream));
OutputStream outStream = sock.getOutputStream();
PrintWriter sockOut = new PrintWriter(new OutputStreamWriter(outStream));
while (true) {
Thread.sleep(1000);
System.out.println("Sending foo");
sockOut.println("foo");
sockOut.flush();
String s = sockIn.readLine();
System.out.println("Got " + s );
Thread.sleep(1000);
System.out.println("Sending bar");
sockOut.println("bar");
sockOut.flush();
s = sockIn.readLine();
System.out.println("Got " + s );
Thread.sleep(1000);
System.out.println("Sending quit");
sockOut.println("quit");
sockOut.flush();
// This will cause someFuncWithChans to block when killing the
// reader thread.
s = sockIn.readLine();
System.out.println("Got " + s );
}
}
If the sockIn.readLine()
is commented out, then killing the thread will succeed. This problem appears only on my Windows machine (at work), whereas it does not on my personal Linux machine.
Trac metadata
Trac field | Value |
---|---|
Version | 8.0.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |