Re: [Haskell-cafe] Can't figure out source of race condition when using System.Process

2008-11-03 Thread Rafal Kolanski


David Roundy wrote:

On Sun, Nov 02, 2008 at 09:15:25PM +0100, Marc Weber wrote:

On Mon, Nov 03, 2008 at 01:02:12AM +1100, Rafal Kolanski wrote:

 Rafal Kolanski.
[...]

Why do you use forkIO here? It's not necessary. The process will run in
background on its own. ?


It looks to me like this code requires a forkIO, not in the writing to inp,
but rather in the reading of out and err.  Otherwise, those buffers may
fill up and your process will hang...


It seems to be as you say. Trying for a single-threaded solution to this 
problem always locked up the program, until I found someone's code 
snippet online using forkIO and extrapolated from that.


Sincerely,

Rafal Kolanski.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Can't figure out source of race condition when using System.Process

2008-11-03 Thread Janis Voigtlaender

Rafal Kolanski wrote:
..., until I found someone's code 
snippet online ... and extrapolated from that.


Oh yes, I love that kind of programming. Hardly possible in other
languages than Haskell. :-)

--
Dr. Janis Voigtlaender
http://wwwtcs.inf.tu-dresden.de/~voigt/
mailto:[EMAIL PROTECTED]
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Can't figure out source of race condition when using System.Process

2008-11-03 Thread Rafal Kolanski


Bryan O'Sullivan wrote:

What is the it that segfaults? The Haskell program shouldn't, at least.


The Haskell program. It does so rarely, however, and I'm unable to 
reproduce it with any consistency, only enough to notice something is 
wrong with what I've written.
Upon closer examination my code also returns an error exit code for 
subprocesses that should've succeeded (pdflatex, but once in a blue moon 
also pstoedit) similarly rarely.


That said, your code for reading from child processes is wrong. You 
should read all of a child's output strictly (i.e. hGetContents alone 
will not do the trick) before you wait for its exit status. Your current 
scheme reverses this order, and there is hence no guarantee that it will 
read anything from the defunct child process. There's some possibility 
that this might be the cause of your segfault, which to me would suggest 
the presence of a bug in the runtime system.


Well, if there's a bug in the runtime system, I'll try to make sure I 
can reproduce it before filing a report.


Meanwhile, you are absolutely right. How would you propose I properly 
perform that sort of interaction? It's often useful to use external 
programs to do things for you by throwing data at them and reading (or 
ignoring) the result until they die. Is there a Haskell idiom for this?


Overall, I find Haskell to be very nice. I just keep getting bitten by 
laziness, at least until I get used to it.


Sincerely,

Rafal Kolanski.

PS. The file I attached is the only real place where concurrency happens 
in my code. The rest of the uses are simple ... when rendering a slide 
using cairo:


slideNaive = do
...
paintLatex \\textbf{datatype} ref = Ref int $\\mid$ Null 50 0
...

which calls:

paintLatex text x y = do
svg - liftIO $ updateSVG text
paintSVG svg 3 x y

updateSVG is defined in SVGLatex.hs which I attached earlier, and the rest:

paintSVG :: FilePath - Double - Double - Double - Render ()
paintSVG file scale' x y = do
save
svg - liftIO $ svgNewFromFile file
let (w,h) = svgGetSize svg
translate x y
scale scale' scale'
moveTo 0 0
svgRender svg
restore

which invokes functions defined in:
import Graphics.Rendering.Cairo
import Graphics.Rendering.Cairo.SVG
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Can't figure out source of race condition when using System.Process

2008-11-02 Thread Rafal Kolanski

Greetings Gentlemen (and Ladies),

As part of my small and simple framework for making presentations in 
Haskell I have a module which, given some text, makes a .tex file and 
then converts it to .svg for loading into a cairo canvas.
It features simple caching (performs md5 on the contents of the .tex 
file and uses that as the file name... if an .svg by that name exists, 
it'll get loaded rather than regenerated).


Unfortunately, it also segfaults once in a while, probably indicating I 
have some kind of race condition ... but I can't figure out why. This is 
the only point in my code that I think I'm using any concurrency, 
although I'm compiling with ghc --make -threaded. Compiling without 
-threaded results in a deadlock.


Ubuntu 8.10, 64-bit, GHC 6.8.2.

Any advice? I'm attaching the module in question (79 lines).

Sincerely,

Rafal Kolanski.
module LatexSVG (updateSVG, updateSVG') where

import System.Process
import Control.Concurrent (forkIO)
import Control.Monad (when)
import System.IO
import System.Directory (doesFileExist)
import System.Exit

workingDir = tex/

prefix = unlines $
   [\\documentclass{minimal} ,
\\usepackage{graphicx,latexsym,amsmath,url,color},
\\usepackage{amssymb,amsmath,wasysym, pst-node, color},
\\usepackage{url},
\\usepackage{isabelle,isabellesym},
%\\usepackage{mathpartir},
\\definecolor{dblue}{rgb}{0,0,0.4},
\\definecolor{blue}{rgb}{0,0,0.6},
\\definecolor{green}{rgb}{0,0.6,0},
\\definecolor{gray}{rgb}{0.7,0.7,0.7},
\\definecolor{dblue}{rgb}{0,0,0.6},
\\definecolor{darkgray}{rgb}{0.4,0.4,0.4},
\\definecolor{red}{rgb}{0.6,0,0},
\\begin{document}]

suffix = \n\\end{document}

-- Pass text to md5sum and drop the final   - when returning
hashMD5 text = do
(inp,out,err,pid) - runInteractiveProcess md5sum [] Nothing Nothing
forkIO $ do 
hPutStrLn inp text
hClose inp
exit - waitForProcess pid
case exit of ExitFailure _ - error md5sum fail 
 _ - return ()
md5hash - hGetContents out
return $ takeWhile (\x - x /= ' ') md5hash

blindExecWithFail cmd args dir = do
(inp,out,err,pid) - runInteractiveProcess cmd args (Just dir) Nothing
exit - waitForProcess pid
case exit of ExitFailure _ - error $ cmd ++   ++ (show args) ++ fail 
 _ - return ()

generateSVG text filebase = do
-- Create a .tex file
writeFile (workingDir ++ filebase ++ .tex) text
-- Run pdflatex over it
blindExecWithFail pdflatex [filebase] workingDir
-- Run pstoedit on resulting .pdf
blindExecWithFail pstoedit 
  [-page 1,-dt,-psarg,-r9600x9600, 
   filebase ++ .pdf, filebase ++ .sk] 
  workingDir
-- Run skconvert on resulting .sk
blindExecWithFail skconvert 
  [filebase ++ .sk, filebase ++ .svg]
  workingDir

updateSVG' :: [Char] - [Char] - [Char] - IO [Char]
updateSVG' prefix suffix text = do
-- Hash the tex
let tex = prefix ++ text ++ suffix
md5hash - hashMD5 tex
-- Filenames are the hash prefixed with hash and ending with extension
let filebase = hash ++ md5hash
-- See if an svg file by that name exists
svge - doesFileExist $ workingDir ++ filebase ++ .svg
when (not svge) $! do
putStrLn $ filebase ++ .svg does not exist, creating
generateSVG tex filebase
return $ workingDir ++ filebase ++ .svg

updateSVG :: [Char] - IO [Char]
updateSVG = updateSVG' prefix suffix

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Can't figure out source of race condition when using System.Process

2008-11-02 Thread Bryan O'Sullivan
2008/11/2 Rafal Kolanski [EMAIL PROTECTED]


 Unfortunately, it also segfaults once in a while, probably indicating I
 have some kind of race condition ... but I can't figure out why.


What is the it that segfaults? The Haskell program shouldn't, at least.

That said, your code for reading from child processes is wrong. You should
read all of a child's output strictly (i.e. hGetContents alone will not do
the trick) before you wait for its exit status. Your current scheme reverses
this order, and there is hence no guarantee that it will read anything from
the defunct child process. There's some possibility that this might be the
cause of your segfault, which to me would suggest the presence of a bug in
the runtime system.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Can't figure out source of race condition when using System.Process

2008-11-02 Thread Marc Weber
On Mon, Nov 03, 2008 at 01:02:12AM +1100, Rafal Kolanski wrote:
  Rafal Kolanski.
 -- Pass text to md5sum and drop the final   - when returning
 hashMD5 text = do
 (inp,out,err,pid) - runInteractiveProcess md5sum [] Nothing Nothing
 forkIO $ do 
 hPutStrLn inp text
 hClose inp
 exit - waitForProcess pid
 case exit of ExitFailure _ - error md5sum fail 
  _ - return ()
 [...]

Why do you use forkIO here? It's not necessary. The process will run in
background on its own. ?

It would help me tracking the problem down having a full compilable
example..

Sincerly
Marc Weber
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Can't figure out source of race condition when using System.Process

2008-11-02 Thread David Roundy
On Sun, Nov 02, 2008 at 09:15:25PM +0100, Marc Weber wrote:
 On Mon, Nov 03, 2008 at 01:02:12AM +1100, Rafal Kolanski wrote:
   Rafal Kolanski.
  -- Pass text to md5sum and drop the final   - when returning
  hashMD5 text = do
  (inp,out,err,pid) - runInteractiveProcess md5sum [] Nothing Nothing
  forkIO $ do 
  hPutStrLn inp text
  hClose inp
  exit - waitForProcess pid
  case exit of ExitFailure _ - error md5sum fail 
   _ - return ()
  [...]
 
 Why do you use forkIO here? It's not necessary. The process will run in
 background on its own. ?

It looks to me like this code requires a forkIO, not in the writing to inp,
but rather in the reading of out and err.  Otherwise, those buffers may
fill up and your process will hang...
-- 
David Roundy
http://www.darcs.net
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe