I'm getting this error printed to stdout when I test run a Haskell program I'm working on. It happens sometimes, not all the time, on identical runs of the program.
forkOS_entry: interrupted
There is a line in the program that calls mask_ $ forkIO to start another thread. I think the error is coming from that thread. Is there a way I can get a better error message or somehow suppress this error message? What is going on? The program seems to run fine regardless.
_ <- mask_ $ forkIO $ mapSSL cafilePath (icSSLWrapPort c) (icHostname c) (icPort c)
I would check the async package for relevant functions. After stumbling upon the async package, I found the functions to be a bit more reliable to use for my tests. Specifically, the function that might help in this case would be
waitCatch :: Async a -> IO (Either SomeException a)
The Marlow book is a great reference for understanding the concurrency package. I hope that the reference helps.
If you can paste a small sample code that I can test with, I might be able to post tested code.
Related
I would like to run a program every n second and refresh the screen(certain lines) until i press the q key. How to achieve this?
I have checked the ansi-terminal package for refreshing certain part of the screen. I'm guessing that I should use haskeline to get the loop and user key press. Am I correct ?
If yes I can't find the function in haskeline.
You can do this pretty simply with nothing but the IO Monad with threadDelay from Control.Concurrent.
import Control.Concurrent
refreshInterval :: Int
refreshInterval = 10000 -- in microseconds
refreshAction :: IO ()
refreshAction = undefined
main :: IO ()
main = do refreshAction
threadDelay refreshInterval
main
With this structure, you can now incorporate a keyboard quit via any library that gives you keyboard input. For example, with haskeline, you can read input with getInputChar, compare it to your quit character, and exit if necessary. But doing it directly this way will leave you unable to read input while the thread sleeps with threadDelay. If your input library buffers reads, this might be ok -- the quit/break action will simply occur when the program gets around to checking for input. If you need more than that, you can either roll your own solution via forkIO as suggested in the comments, or move to a library that handles this sort of thing a bit better.
As an interesting side note, this is pretty easily solved within my OpenCV library using the parts of the library that wrap OpenCV's HighGUI functionality. I don't necessarily recommend pulling in that dependency just for this functionality, but it does technically solve your problem. I'll add that to this answer if anyone is interested.
I've got a program which uses several threads. As I understand it, when thread 0 exits, the entire program exits, regardless of any other threads which might still be running.
The thing is, these other threads may have files open. Naturally, this is wrapped in exception-handling code which cleanly closes the files in case of a problem. That also means that if I use killThread (which is implemented via throwTo), the file should also be closed before the thread exits.
My question is, if I just let thread 0 exit, without attempting to stop the other threads, will all the various file handles be closed nicely? Does any buffered output get flushed?
In short, can I just exit, or do I need to manually kill threads first?
You can use Control.Concurrent.MVar to achieve this. An MVar is essentially a flag which is either ''empty'' or "full". A thread can try to read an MVar and if it is empty it blocks the thread. Wherever you have a thread which performs file IO, create an MVar for it, and pass it that MVar as an argument. Put all the MVars you create into a list:
main = do
let mvars = sequence (replicate num_of_child_threads newEmptyMVar)
returnVals <- sequence (zipWith (\m f -> f m)
mvars
(list_of_child_threads :: [MVar -> IO a]))
Once a child thread has finished all file operations that you are worried about, write to the MVar. Instead of writing killThread you can do
mapM_ takeMVar mvars >> killThread
and where-ever your thread would exit otherwise, just take all the MVars.
See the documentation on GHC concurrency for more details.
From my testing, I have discovered a few things:
exitFailure and friends only work in thread 0. (The documentation actually says so, if you go to the trouble of reading it. These functions just throw exceptions, which are silently ignored in other threads.)
If an exception kills your thread, or your whole program, any open handles are not flushed. This is excruciatingly annoying when you're desperately trying to figure out exactly where your program crashed!
So it appears it if you want your stuff flushed before the program exits, then you have to implement this. Just letting thread 0 die doesn't flush stuff, doesn't throw any exception, just silently terminates all threads without running exception handlers.
I am currently writing a Haskell program that does some initialization work and then calls ncmpcpp. What I am trying to do is start ncmpcpp and terminate the Haskell program, so that only ncmpcpp is left (optionally, the program can keep running in the background, as long as it's unintrusive)
However, even though I am able to start ncmpcpp, I cannot interact with it. I see its output, but input appears to be impossible.
What I am currently doing is:
import System.Process (createProcess, proc)
...
spawnCurses :: [String] -> IO ()
spawnCurses params = do
_ <- createProcess (proc "ncmpcpp" params)
return ()
What am I doing wrong/What should I do differently?
What you are trying to achieve sounds like what the exec family of functions does. Take a look at the executeFile function.
If you want your parent Haskell process to be still running after the child process is started read about fork-exec and the forkProcess function.
A complete example of using forkProcess together with executeFile can be found at http://therning.org/magnus/archives/727.
I'm creating a small program to use with an irc bot that should take a string and then evaluate the string. For this I'm using the hint package, which work very well for my needs. The problem that I now have is that I want to be able to prevent evaluation of expressions that take a vary long to calculate e.g. 2^1000000000.
I tried using the System.Timeout package like this:
import Data.Maybe
import Language.Haskell.Interpreter
import System.Timeout
import System.Environment (getArgs)
main :: IO()
main = do
r <- timeout 500000 $ runInterpreter $ hEval arg
case r of
Nothing -> putStrLn "Timed out!"
Just x ->
case x of
Left err -> putStrLn (show err)
Right a -> putStrLn a
hEval e = do
setImportsQ [("Prelude", Nothing),("Data.List",Nothing)]
a <- eval e
return $ take 200 a
But it's not working, the timeout does not fire unless I put in such a short time that nothing can be evaluated. I read on the page for the Timeout package that it could have problems with some modules and have to let theme finish but my understanding is not good enough to know if Hint is such a module.
So any help on this would be appreciated, even if it's just to tell me that this isn't going to work.
GHC threads are cooperative. They can only yield or be terminated by asynchronous exceptions when they perform a memory allocation. This normally works fine, but someone malicious can write a tight loop that runs for a significant time without allocating.
The mueval package was created to deal with things like this. It's implemented in terms of hint, but with a lot of extra safety added in various ways.
I've worked my way through Don Stewart's Roll your own IRC bot tutorial, and am playing around with some extensions to it. My current code is essentially the same as the "The monadic, stateful, exception-handling bot in all its glory"; it's a bit too long to paste here unless someone requests it.
Being a Comcast subscriber, it's particularly important that the bot be able to reconnect after periods of poor connectivity. My approach is to simply time the PING requests from the server, and if it goes without seeing a PING for a certain time, to try reconnecting.
So far, the best solution I've found is to wrap the hGetLine in the listen loop with System.Timeout.timeout. However, this seems to require defining a custom exception so that the catch in main can call main again, rather than return (). It also seems quite fragile to specify a timeout value for each individual hGetLine.
Is there a better solution, perhaps something that wraps an IO a like bracket and catch so that the entire main can handle network timeouts without the overhead of a new exception type?
How about running a separate thread that performs all the reading and writing and takes care of periodically reconnecting the handle?
Something like this
input :: Chan Char
output :: Chan Char
putChar c = writeChan output c
keepAlive = forever $ do
h <- connectToServer
catch
(forever $
do c <- readChan output; timeout 4000 (hPutChar h c); return ())
(\_ -> return ())
The idea is to encapsulate all the difficulty with periodically reconnecting into a separate thread.