Skip to content

Commit

Permalink
Minimized test case to demonstrate issue writing to locked file.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmitchell committed Jan 25, 2017
1 parent 4a850dd commit ce03f14
Showing 1 changed file with 16 additions and 60 deletions.
76 changes: 16 additions & 60 deletions tests/test.hs
Original file line number Diff line number Diff line change
@@ -1,65 +1,21 @@
{-# LANGUAGE ViewPatterns #-}

import Control.Monad
import Control.Concurrent
import Control.Concurrent.Async
import Debug.Trace (trace)
import System.Environment
import System.Exit
import System.Process

import System.FileLock

main :: IO ()
main = do
args <- getArgs
case args of
["shared", read -> duration]
-> holdLock "shared" Shared duration
["exclusive", read -> duration]
-> holdLock "exclusive" Exclusive duration
["try"]
-> tryTakingLock
_ -> void $ mapConcurrently id
[ callSelf ["shared", "300"]
, callSelf ["shared", "200"]
, msleep 10 >> callSelf ["exclusive", "500"]
, msleep 20 >> callSelf ["try"]
, msleep 50 >> callSelf ["shared", "500"]
, msleep 700 >> callSelf ["shared", "10"]
, msleep 1500 >> callSelf ["try"]
]

callSelf :: [String] -> IO ()
callSelf args = do
result <- trace "Attempting to call self" $ rawSystem ".\\bin\\test-filelock.exe" args
case result of
ExitSuccess -> putStrLn "callSelf succeeded"
x -> putStrLn $ "callSelf encountered unexpected exit code: " ++ show x
return ()

msleep :: Int -> IO ()
msleep = threadDelay . (*1000)

holdLock :: String -> SharedExclusive -> Int -> IO ()
holdLock ty sex duration = do
withFileLock lockfile sex $ \_ -> do
putStrLn $ "took " ++ desc
if sex == Exclusive then testWrite else return ()
msleep duration
putStrLn $ "released " ++ desc
where
desc = ty ++ " lock"
testWrite = trace "attempting write..." $ writeFile lockfile "testing"

tryTakingLock :: IO ()
tryTakingLock = do
ml <- tryLockFile lockfile Exclusive
case ml of
Nothing -> putStrLn "lock not available"
Just l -> do
putStrLn "lock was available"
unlockFile l

lockfile :: String
lockfile = "lock"
main = lockAndWriteFile "testLockFile.txt" "testing, testing; 1, 2, 3"

lockAndWriteFile :: String -> String -> IO ()
lockAndWriteFile fname contents = do
withFileLock fname Exclusive $ \_ -> do
putStrLn "took exclusive lock; attempting write..."

-- Following line fails, printing "test-filelock.exe: testLockFile.txt:
-- hClose: permission denied (Permission denied)" and process exits
-- prematurely with exit code 1.
--
-- However, there are no issues when it's commented out.
writeFile fname contents

-- Never prints (unless writeFile line is commented out).
putStrLn "released exclusive lock"

0 comments on commit ce03f14

Please sign in to comment.