From: Marc A. Z. <co...@gm...> - 2007-01-26 03:14:26
|
we have missed each other's mails. your mail: Thu, 25 Jan 2007 14:18:57 +0100 my mail: Thu, 25 Jan 2007 14:16:24 +0100 Am Donnerstag, 25. Januar 2007 14:18 schrieb Duncan Coutts: > On Thu, 2007-01-25 at 09:00 +0000, Axel Simon wrote: > > On Thu, 2007-01-25 at 05:15 +0100, Marc A. Ziegert wrote: > > threaded RTS? > > I had some bug reports ... > (people don't always tell you things like that up > front!). understandable. should have written more about all this in my first mail. btw. :/ > So I'm considering making initGUI print a warning instead but continue. > Do you think that'd be a good idea? no. it is already the accurate solution... no one (especially those who use the threaded rts correctly) want those messages whenever the code compiles or runs. aborting in compile phase is the best solution, in test phase the second best. ...iff the programmer is allowed to estimate his own competence. while programming with threadedRTS+gui, he should be aware of the circumstances. so IMHO an alternative to initGUI should aditionally be given, combining the name with that awareness: sth nasty like unsafeInitGtk_I_am_aware_of_the_fact_that_all_gui_calls_need_to_be_made_exclusively_in_not_more_than_one_single_thread_ever :: IO () > It is possible to use the threaded RTS with Gtk2Hs, however it's very > difficult. You have to make sure that all GUI calls happen on a single > OS thread. So any other Haskell threads apart from the one that calls > mainGUI cannot make GUI calls. If they want to do GUI stuff they have to > arrange to 'post' actions to the main GUI thread (eg using idle or timer > based callbacks). if you replace "cannot" with "don't": already done that funny posting-actions stuff. see other mail. ;) > I have no confidence that people will not shoot themselves in the foot > when using the threaded RTS. Perhaps as a temporary solution we could > have a unsafeInitGUIForThreads or something that people could use if > they really really thought they were doing everything ok (eg only using > multiple threads for non-GUI stuff). ... [it took 10 minutes to think about this:] what is the point in writing this email? we write our mails at the same time, miss each other... we discuss this with the same point of view... and whenever i read further through your mail, my direct answers become obsolete. > > c) Convey to the Haskell runtime that it should make all Gtk calls > > through the same OS thread. > > At the recent Haskell hackathon I talked to Simon Marlow about this > issue. Currently there is now way to bind multiple Haskell threads to a > single OS thread and implementing such a feature would not be easy. Even > if we had that we'd still need the ability to transparently migrate > Haskell threads to the right OS thread when they make a GUI call. never thought about that. well, i don't like to use userland-(/posix-/haskell-)threads that much, because they may be blocking the rest of the program. i never needed multiple threads before, except while hacking with hopengl or gtk2hs in ghci. > > The most practical solution we came up with looked something like this: > > Launch a bound thread which then calls mainGUI. This OS thread will be > the GUI thread from then on. > > Have a GUI monad. Code running in the context of the GUI monad would > happen only in the GUI OS thread. Entry from IO to GUI would switch OS > thread if necessary by posting the whole action to the glib main loop. > IO actions could be lifted into the GUI monad however they may not block > or they'd block the GUI. It'd be fine however to forkIO more unbound > threads. If they wanted to do more GUI stuff then they'd have to > transition into the GUI monad (and OS thread) again. > > Callbacks would be ok since they'd happen on the GUI OS thread anyway. > already thought about that. the questions are: how costly is it to get the current thread-id? how costly is it to send/receive one byte through a posix-pipe to/from another thread? (Gtk uses select <http://www.messinalug.org/cgi-bin/man/man2html?2+select>, that should be better to abuse than a polling timer.) how costly is it to use a (non-)blocking Control.Concurrent.Chan+MVar? > > So as you can see, it'd not be simple to transition from the current > Gtk2Hs api which uses the IO monad to something that used a GUI monad. > how about this? to not break compatibility: widgetShowAll :: WidgetClass self => self -> IO () widgetShowAll = old_widgetShowAll ==> widgetShowAll :: (WidgetClass self,GuiMonad gui) => self -> gui () widgetShowAll = liftIO . old_widgetShowAll --forall modules: class (MonadIO gui) => GuiMonad gui where -- should be exported to the user ungui_internal :: gui a -> IO a -- should only be exported to other gtk modules --backwards compatible module: initGTK :: IO () type Gui a = IO a rungui :: Gui a -> IO a rungui = id instance GuiMonad IO where ungui_internal = id --replacement module: initGtkThread :: IO () newtype Gui a = Gui_ (IO a) deriving (Functor,Monad,MonadIO) rungui :: Gui a -> IO a rungui (Gui_ f) = inGTK $ f -- inGTK: see other mail instance GuiMonad Gui where ungui_internal (Gui_ f) = f > It'd be interesting to prototype at least and see if it really works. and it'd be cool to easily program never-lagging gui programms with this. :) > > > Anyway, I'd like to know people's opinions on what we should do in the > short term, ie for this release. > > Duncan > in the short term: that initGTK_shootinthefoot alternative. :) - marc |