From 8d2a22ef9fed6843aa7c77f79984a4e3f69fcfe9 Mon Sep 17 00:00:00 2001
From: simonmar <unknown>
Date: Tue, 25 Jul 2000 15:20:10 +0000
Subject: [PATCH] [project @ 2000-07-25 15:20:10 by simonmar] Fix bug reported
 by Hannah Schroeter: reading a file lazily using hGetContents and then
 closing it using hClose can cause the program to fall over with a deadlock.

The reason is that when closing the file in lazyRead{Block,Line,Char},
we set the foreign object in the handle to nullFile__, which causes
the finalizer to run (at some point in the future).  The finalizer
takes the MVar in the handle, frees the contents, but never puts the
MVar back.  hClose then tries to take the MVar, and deadlocks.

The solution is not to set the foreign object to nullFile__ in the
first place; I'm not sure why it was done this way, and in fact it
leads to a memory leak.  hClose itself has a similar problem, leading
to a leak of the fileObject.
---
 ghc/lib/std/PrelHandle.lhs |  3 +--
 ghc/lib/std/PrelIO.lhs     | 14 ++++----------
 2 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/ghc/lib/std/PrelHandle.lhs b/ghc/lib/std/PrelHandle.lhs
index f5d51b889779..2e46e84a0de9 100644
--- a/ghc/lib/std/PrelHandle.lhs
+++ b/ghc/lib/std/PrelHandle.lhs
@@ -1,5 +1,5 @@
 % ------------------------------------------------------------------------------
-% $Id: PrelHandle.lhs,v 1.59 2000/07/07 11:03:58 simonmar Exp $
+% $Id: PrelHandle.lhs,v 1.60 2000/07/25 15:20:10 simonmar Exp $
 %
 % (c) The AQUA Project, Glasgow University, 1994-2000
 %
@@ -416,7 +416,6 @@ hClose handle =
 		  -- associated with this handle.
 	   else do freeBuffers (haBuffers__ handle_)
 		   return (handle_{ haType__    = ClosedHandle,
-			            haFO__      = nullFile__,
 				    haBuffers__ = [] })
 \end{code}
 
diff --git a/ghc/lib/std/PrelIO.lhs b/ghc/lib/std/PrelIO.lhs
index 944ed196393a..e93410ffd133 100644
--- a/ghc/lib/std/PrelIO.lhs
+++ b/ghc/lib/std/PrelIO.lhs
@@ -1,5 +1,5 @@
 % ------------------------------------------------------------------------------
-% $Id: PrelIO.lhs,v 1.14 2000/07/07 11:03:58 simonmar Exp $
+% $Id: PrelIO.lhs,v 1.15 2000/07/25 15:20:10 simonmar Exp $
 %
 % (c) The University of Glasgow, 1992-2000
 %
@@ -282,9 +282,7 @@ lazyReadBlock handle fo = do
      -1 -> -- an error occurred, close the handle
 	  withHandle handle $ \ handle_ -> do
           closeFile (haFO__ handle_) 0{-don't bother flushing-}  -- ConcHask: SAFE, won't block.
-	  return (handle_ { haType__    = ClosedHandle,
-			    haFO__      = nullFile__ }, 
-		  "")
+	  return (handle_ { haType__    = ClosedHandle }, "")
      _ -> do
       more <- unsafeInterleaveIO (lazyReadBlock handle fo)
       stToIO (unpackNBytesAccST buf bytes more)
@@ -298,9 +296,7 @@ lazyReadLine handle fo = do
        -1 -> -- an error occurred, close the handle
   	     withHandle handle $ \ handle_ -> do
              closeFile (haFO__ handle_) 0{- don't bother flushing-}  -- ConcHask: SAFE, won't block
-	     return (handle_ { haType__    = ClosedHandle,
-			       haFO__      = nullFile__ },
-		     "")
+	     return (handle_ { haType__    = ClosedHandle }, "")
        _ -> do
           more <- unsafeInterleaveIO (lazyReadLine handle fo)
           buf  <- getBufStart fo bytes  -- ConcHask: won't block
@@ -318,9 +314,7 @@ lazyReadChar handle fo = do
       -1 -> -- error, silently close handle.
  	 withHandle handle $ \ handle_ -> do
          closeFile (haFO__ handle_) 0{-don't bother flusing-}  -- ConcHask: SAFE, won't block
-	 return (handle_{ haType__  = ClosedHandle,
-			  haFO__    = nullFile__ },
-		 "")
+	 return (handle_{ haType__  = ClosedHandle }, "")
       _ -> do
 	 more <- unsafeInterleaveIO (lazyReadChar handle fo)
          return (chr char : more)
-- 
GitLab