Re: [Haskell-cafe] Double free-ing (was: Reading from a process)
Hi! On Fri, Dec 18, 2009 at 8:16 AM, Jason Dusek jason.du...@gmail.com wrote: Concatenating two `ByteString`s is O(n)? This is what it is written here: http://haskell.org/ghc/docs/latest/html/libraries/bytestring-0.9.1.5/Data-ByteString.html#v%3Aappend Mitar ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Double free-ing
Hi! On Fri, Dec 18, 2009 at 8:29 AM, Ketil Malde ke...@malde.org wrote: Lazy ByteStrings should be able to append with O(1). (Or use strict BS hGetNonBlocking, and Lazy ByteString fromChunks.) Oh, true. Thanks! But ... lazy ByteString's hGetNonBlocking is probably not lazy? Could it be? It has to read at that moment whatever it can? But appending is really better. Why are lazy ByteStrings not default? Thanks again. Mitar ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Double free-ing
Hi! On Fri, Dec 18, 2009 at 6:54 PM, Mitar mmi...@gmail.com wrote: On Fri, Dec 18, 2009 at 8:29 AM, Ketil Malde ke...@malde.org wrote: Lazy ByteStrings should be able to append with O(1). (Or use strict BS hGetNonBlocking, and Lazy ByteString fromChunks.) Oh, true. Thanks! But ... lazy ByteString's hGetNonBlocking is probably not lazy? Could it be? It has to read at that moment whatever it can? But appending is really better. Why are lazy ByteStrings not default? Tried it and it really works great! Thanks to all. Mitar ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Double free-ing (was: Reading from a process)
Hi! On Thu, Dec 17, 2009 at 5:28 AM, Jason Dusek jason.du...@gmail.com wrote: It seems like the message delimiter to me because you keep buffering till you receive it. Hm, true. I have changed code to this: getLastMyData :: MySate (Maybe MyData) getLastMyData = do p - gets process case p of Nothing - fail No process Just (MyProcess processOut processPid processBuffer) - do processRunning - io $ getProcessExitCode processPid case processRunning of Just _ - processExited _ - do ret - io $ tryJust (guard . isEOFError) $ slurpMyData processOut processBuffer case ret of Left _ - processExited -- EOF Right (datalist, currentBuffer) - do modify (\s - s { process = Just (MyProcess processOut processPid currentBuffer) }) if null datalist then return Nothing else return $ Just $ head datalist -- MyData is stored in the reverse order so head is the last MyData from the process slurpMyData :: Handle - DataBuffer - IO ([MyData], DataBuffer) slurpMyData = slurpMyData' [] where slurpMyData' datalist h buffer@(DataBuffer capacity array bytecount) = do ready - hReady h if not ready then return (datalist, buffer) else do let array' = advancePtr array bytecount count - hGetBufNonBlocking h array' (capacity - bytecount) let bytecount' = bytecount + count chars - peekArray bytecount' array let (d, rest) = readData . dataToString $ chars rest' = stringToData rest if null d then if length rest' == capacity then error Invalid data from the process else return (datalist, buffer) else do assert (length rest' = capacity) $ pokeArray array rest' let buffer' = DataBuffer capacity array (length rest') slurpMyData' (d ++ datalist) h buffer' readData :: String - ([MyData], String) readData = readData' [] where readData' datalist = (datalist, ) readData' datalist string = case reads string of [(x, rest)] - readData' ((head x):datalist) rest -- x is a list and currently it has only one element [] - (datalist, string) -- we probably do not have enough data to read MyData properly _ - error Ambiguous parse from the process And now it works. I just do not like using malloc and free. And talking about free, I have now a problem of double freeing this buffer. I am getting it after I send ctrl-c to the main process (with underlying process I am communicating with). I am freeing it in processExited: processExited :: MyState a processExited = do terminateDataProcess fail Process exited terminateDataProcess :: MyState () terminateDataProcess = do p - gets process case p of Just (MyProcess _ processPid (DataBuffer _ array _)) - do modify (\s - s { process = Nothing }) io $ free array io $ terminateProcess processPid _ - return () So I run processExited if there is EOF from underlying process. But I also run terminateDataProcess in a bracket I am calling getLastMyData. Code is like this: bracket initDataProcess terminateDataProcess (... read getLastMyData repeatedly and process it ...) Why I am getting this double free-ing errors? Should I introduce some locks on terminateDataProcess? I am using Linux 2.6.30 amd64 and 6.10.4. Mitar ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Double free-ing (was: Reading from a process)
You shouldn't have to use `malloc` and `free` to accumulate input. Just append to a list or a ByteString, which is to say, add a byte to a ByteString to get a new ByteString. Yes, really. Maybe there is something I am missing here; but I can't see any reason to adopt this unnatural (for Haskell) approach. -- Jason Dusek ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Double free-ing (was: Reading from a process)
Hi! On Fri, Dec 18, 2009 at 1:53 AM, Jason Dusek jason.du...@gmail.com wrote: You shouldn't have to use `malloc` and `free` to accumulate input. Just append to a list or a ByteString, which is to say, add a byte to a ByteString to get a new ByteString. Yes, really. Oh, I did not know that ByteString has hGetNonBlocking. When I see that System.IO's hGetBufNonBlocking uses Ptr I started crying and kept crying while coding with it. It was really strange for me to use Foreign.* modules for code which should be clean Haskell. Maybe there is something I am missing here; but I can't see any reason to adopt this unnatural (for Haskell) approach. I checked ByteString's hGetNonBlocking now and I do see why it is still better to use System.IO's hGetBufNonBlocking. I would like to have a buffer of fixed length and just fill it until it is full. With hGetBufNonBlocking this is possible as I can just give different starting positions in the buffer while retaining data already read where it is (so I do not to copy anything around). But with hGetNonBlocking I would have to append two different buffers to get a resulting buffer, what is completely unnecessary O(n). Why would I read data into some other buffer just to be able to append it to main buffer later. Any suggestion how can I do that in Haskell why? Mitar ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Double free-ing (was: Reading from a process)
Concatenating two `ByteString`s is O(n)? -- Jason Dusek ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Double free-ing
Mitar mmi...@gmail.com writes: I checked ByteString's hGetNonBlocking now and I do see why it is still better to use System.IO's hGetBufNonBlocking. [...] But with hGetNonBlocking I would have to append two different buffers to get a resulting buffer, what is completely unnecessary O(n). Lazy ByteStrings should be able to append with O(1). (Or use strict BS hGetNonBlocking, and Lazy ByteString fromChunks.) -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe