Data.ByteStirng.Lazy.hGetContents doesn't unlock i-node
I found that Data.ByteStirng.Lazy.hGetContents doesn't unlock i-node even after retreiving whole contents. Because of this and the fact that file locking mechanism of GHC uses i-node, sometimes it causes a problem whose cause is hard to find.
See this example assuming file 'a' already exists:
testB = forM [1..] $ \_ -> do
r <- B.readFile "a" >>= \r -> return $! B.length r `seq` r
B.writeFile "b" (B8.pack "abc")
renameFile "b" "a"
When I run this test on GHCi, it shows this error:
- Main> testB
- ** Exception: b: openBinaryFile: resource busy (file is locked)
I presume that this error happened because:
- readFile locks the i-node of 'a' and continues to lock after reading whole contents
- writeFile writes contents to 'b'
- Maybe GC runs and closes the handle but doesn't unlock i-node
- renaming 'b' to 'a' causes free the i-node of 'a'
- readFile locks another i-node of 'a'
- writeFile reuses the first i-node of 'a' which is still locked
It is very difficult to find that readFile causes a problem, because an error occures in writeFile.
I'm not sure this is a problem of ByteString or GC, but this problem doesn't occur when I use System.IO.hGetContents because it closes the handle and unlocks the i-node after retrieving whole contents.
Trac metadata
Trac field | Value |
---|---|
Version | 6.8.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | libraries (other) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | snak@snak.org |
Operating system | |
Architecture | x86 |