Endangered I/O operations

kahl@heraklit.informatik.unibw-muenchen.de kahl@heraklit.informatik.unibw-muenchen.de
23 May 2001 19:21:19 -0000

Carl R. Witty <cwitty@newtonlabs.com> writes:
 > "Simon Marlow" <simonmar@microsoft.com> writes:
 > > You obtain the ordering properties by setting the handle to NoBuffering,
 > > otherwise you get buffered input/output.  Wouldn't it be deviating from
 > > the report to do extra flushing in the buffered case?  (this is
 > > something of a technicality, actually we already do non-report flushing
 > > in several cases and our line-buffered input isn't line-buffered at
 > > all).
 > If the report does not allow the implementation to flush buffers at
 > any time, I would call that a bug in the report.  I would much rather
 > use an implementation where stdout and stderr came out in the right
 > order, and reading from stdin flushed stdout.  (As another example, an
 > implementation might want to flush all buffers before doing a fork(),
 > to avoid duplicated output.)

A related wish I have is that a Haskell program receiving a HUP signal
should flush its buffers before terminating.

Or even better, flush on some other signal that does not terminate
the program.

I frequently have long-running (weeks, months ...) applications
that produce data (lists) with decreasing speed.
Since data may be sitting in unflushed buffers for days (weeks, ...),
I currently shy away from using Show instances for lists
and instead use the following ``printList'' function:

> hPutList :: String -> (a -> ShowS) -> Handle -> [a] -> IO ()
> hPutList sep shows h = mapM_ f
>  where f x = hPutStr h (shows x sep) >> hFlush h
> putList :: String -> (a -> ShowS) -> [a] -> IO ()
> putList sep shows = hPutList sep shows stdout
> printList :: Show a => String -> [a] -> IO ()
> printList sep = putList sep shows

It would be really nice to have other possibilities to force the program
to flush buffers!