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