Tetigi
Tetigi

Reputation: 614

Haskell Gtk : mainGUI function blocking other threads

I'm having a little bit of trouble with threading (using STM) and combining that with GTK (http://hackage.haskell.org/package/gtk-0.12.3).

I have a function that loops indefinitely, ticking every 2 seconds, which prints the contents of a list, then clears the list, defined like

data VirtualHelicopter = VirtualHelicopter { getOrders :: TVar [(Option, Int)] }

run :: VirtualHelicopter -> IO ()
run h = do
  forever ( (putStrLn . show =<< (atomRead orders))
            >> clearOrders orders
            >> milliSleep 2000)
  where
    orders = getOrders h
    atomRead = atomically . readTVar
    clearOrders x = atomically $ writeTVar x []
    milliSleep = threadDelay . (*) 1000

Additionally, I have a GUI function, defined as

runGUI :: VirtualHelicopter -> IO ()
runGUI flyer = do
  Gtk.initGUI
  ~ GUI set up stuff, some key listeners that write to the TVar inside flyer ~
  forkIO $ run flyer
  Gtk.mainGUI

If I forkIO the "run" function from inside GHCI, everything works fine - it ticks every 2 seconds, printing to the console and updating the queue with anything I add into it using the TVar from the flyer.

However, when I try to forkIO from within the GUI, it no longer ticks every two seconds - it just kind of hangs until I put in some input, then gives unreliable outputs.

Anyone have any idea why this happens? You can see the whole project this is from, with full context at https://github.com/tetigi/majom, which is a Haskell extension of this project idea http://procrastineering.blogspot.co.uk/2011/11/computer-controlling-syma-helicopter.html. The threading implementation is on the "threadingForVHeli" branch.

Upvotes: 0

Views: 223

Answers (1)

Tetigi
Tetigi

Reputation: 614

As hammar said, adding -threaded to the build options solved it. I didn't realise there was a compiler option for threaded things!

I'll also work on clearing up the race condition that was mentioned :)

Upvotes: 1

Related Questions