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