forked from takano-akio/filelock
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Minimized test case to demonstrate issue writing to locked file.
See takano-akio#2.
- Loading branch information
Showing
1 changed file
with
16 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |