You should use an MVar if you want it to be thread safe.<br><br><div class="gmail_quote">On Jan 19, 2008 1:36 PM, David Roundy <<a href="mailto:droundy@darcs.net">droundy@darcs.net</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Using ghc 6.6, but I've since isolated the bug as being unrelated to the<br>IORefs and threading, it was in an FFI binding that somehow never died<br>until I was testing this new code.<br><font color="#888888"><br>David<br>
</font><div><div></div><div class="Wj3C7c"><br>On Sat, Jan 19, 2008 at 01:27:47PM +0100, Peter Verswyvelen wrote:<br>> Hi David,<br>><br>> Which version of GHC are you using?<br>><br>> I tried to recompile some GHC 6.6.1 progs using GHC 6.8.2 and I also got<br>
> segfaults. I haven't figured out yet if this is because my changes to<br>> make it work with GHC 6.8.2 are incorrect, or if this is an issue with<br>> 6.8.2.<br>><br>> Cheers,<br>> Peter<br>><br>
><br>> On Fri, 2008-01-18 at 18:22 -0500, David Roundy wrote:<br>> > Hi all,<br>> ><br>> > I'm working on some new progress-reporting code for darcs, and am getting<br>> > segmentation faults! :( The code uses threads + an IORef global variable<br>
> > to do this (with lots of unsafePerformIO). So my question for the gurus<br>> > who know more about this than I do: is this safe? I thought it would be,<br>> > because only one thread ever modifies the IORef, and the others only read<br>
> > it. I don't really care if they read a correct value, as long as they<br>> > don't segfault.<br>> ><br>> > The code (to summarize) looks like:<br>> ><br>> > {-# NOINLINE _progressData #-}<br>
> > _progressData :: IORef (Map String ProgressData)<br>> > _progressData = unsafePerformIO $ newIORef empty<br>> ><br>> > updateProgressData :: String -> (ProgressData -> ProgressData) -> IO ()<br>
> > updateProgressData k f = when (progressMode) $ modifyIORef _progressData (adjust f k)<br>> ><br>> > setProgressData :: String -> ProgressData -> IO ()<br>> > setProgressData k p = when (progressMode) $ modifyIORef _progressData (insert k p)<br>
> ><br>> > getProgressData :: String -> IO (Maybe ProgressData)<br>> > getProgressData k = if progressMode then lookup k `fmap` readIORef _progressData<br>> > else return Nothing<br>
> ><br>> > The key function is<br>> ><br>> > beginTedious :: String -> IO ()<br>> > beginTedious k = do tid <- forkIO $ handleProgress k<br>> > debugMessage $ "Beginning " ++ k<br>
> > setProgressData k $ ProgressData { sofar = 0,<br>> > latest = Nothing,<br>> > total = Nothing,<br>
> > handler = Just tid }<br>> ><br>> > which is called before an action that may be so tedious for our users that<br>> > they need their day brightened by messages such as "Applying patch<br>
> > 137/1436". The handleProgress function alternates between threadDelay and<br>> > reading the progress data to see whether any progress has been made and<br>> > printing messages. Meanwhile the main thread calls functions that update<br>
> > _progressData.<br>> ><br>> > Anyhow, the point is that I'm getting segfaults, even after recompiling<br>> > everything from scratch! Is this in fact that unsafe? Do I really need to<br>> > switch to MVars, even though no locking is required?<br>
><br>> _______________________________________________<br>> Haskell-Cafe mailing list<br>> <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>> <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br></div></div><div class="Ih2E3d">--<br>David Roundy<br>Department of Physics<br>Oregon State University<br>_______________________________________________<br></div><div><div></div><div class="Wj3C7c">Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br><a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br></div></div>
</blockquote></div><br>