Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lazy bug #4

Open
exFalso opened this issue Dec 11, 2011 · 0 comments
Open

lazy bug #4

exFalso opened this issue Dec 11, 2011 · 0 comments

Comments

@exFalso
Copy link

exFalso commented Dec 11, 2011

hslogger seems to deadlock when printing lazy bytestrings.

I am guessing this is because hslogger has a global lock which won't be released until the lazy string is fully evaluated. This will lead to a deadlock if another thread whose actions determine the evaluation of the string also tries to log.

Test case: (sorry i couldn't make up a smaller one)

(server.hs)
import System.Log.Logger
import System.IO
import Control.Concurrent
import Network
import Control.DeepSeq
import Control.Exception

import qualified Data.ByteString.Lazy as L

main = do
updateGlobalLogger "Main" (setLevel NOTICE)
socket <- listenOn (PortNumber 11111)

putStrLn "(SERVER) Waiting for client to connect"
(hndle, _, _) <- accept socket
hSetBuffering hndle NoBuffering
putStrLn "(SERVER) Client connected"

forkIO (thread hndle)

--toPrint <- evaluate . force . show =<< L.hGetContents hndle
toPrint <- return . show =<< L.hGetContents hndle

noticeM "Main" ("Deadlock! :) " ++ toPrint)
return ()

thread hndle = do
noticeM "Main" $ "Never to be seen"
hPutStrLn hndle "Some Message"

(client.hs)
import System.IO
import Network

import qualified Data.ByteString.Char8 as L

main = do
putStrLn "(CLIENT) Connecting..."
hndle <- connectTo "localhost" (PortNumber 11111)
hSetBuffering hndle NoBuffering
putStrLn "(CLIENT) Connected"
toEcho <- hGetLine hndle
putStrLn $ "(CLIENT) Echoing " ++ show toEcho ++ " back to server"
hFlush stdout
hPutStr hndle toEcho
putStrLn "(CLIENT) Message sent"

Compile, then run server.hs then client.hs - it will deadlock. Commenting/Uncommenting the "toPrint <-..." lines in server.hs will solve the issue.

A simple solution is to force evaluating the string before acquiring the global lock.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant