Skip to content

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information