bring back --quiet filtering of stdout and stderr, with deadlock fixed

I don't quite understand the cause of the deadlock. It only occurred
when git-annex-shell transferinfo was being spawned over ssh to feed
download transfer progress back. And if I removed this line from
feedprogressback, the deadlock didn't occur:
	bytes <- readSV v

The problem was not a leaked FD, as far as I could see. So what was it?
I don't know.

Anyway, this is a nice clean implementation, that avoids the deadlock.
Just fork off the async threads to handle filtering the stdout and stderr,
and let them clean up their handles whenever they decide to exit.

I've verified that the handles do get promptly closed, although a little
later than I would expect. Presumably that "little later" is what
was making waiting on the threads deadlock.

Despite the late exit, the last line of stdout and stderr appears where
I'd want it to, so I guess this is ok..
This commit is contained in:
Joey Hess 2015-04-06 20:18:57 -04:00
parent 667e16f1b9
commit 42281f12d6
2 changed files with 38 additions and 20 deletions

View file

@ -164,19 +164,15 @@ type ProgressParser = String -> (Maybe BytesProcessed, String)
- to update a meter. - to update a meter.
-} -}
commandMeter :: ProgressParser -> OutputHandler -> MeterUpdate -> FilePath -> [CommandParam] -> IO Bool commandMeter :: ProgressParser -> OutputHandler -> MeterUpdate -> FilePath -> [CommandParam] -> IO Bool
commandMeter progressparser oh meterupdate cmd params = catchBoolIO $ commandMeter progressparser oh meterupdate cmd params =
withHandle StdoutHandle createProcessSuccess p $ \outh -> do outputFilter cmd params Nothing
-- ep <- async $ handlestderr errh (feedprogress zeroBytesProcessed [])
op <- async $ feedprogress zeroBytesProcessed [] outh handlestderr
-- wait ep
wait op
where where
p = proc cmd (toCommand params)
feedprogress prev buf h = do feedprogress prev buf h = do
b <- S.hGetSome h 80 b <- S.hGetSome h 80
if S.null b if S.null b
then return True then return ()
else do else do
unless (quietMode oh) $ do unless (quietMode oh) $ do
S.hPut stdout b S.hPut stdout b
@ -203,18 +199,13 @@ demeterCommand :: OutputHandler -> FilePath -> [CommandParam] -> IO Bool
demeterCommand oh cmd params = demeterCommandEnv oh cmd params Nothing demeterCommand oh cmd params = demeterCommandEnv oh cmd params Nothing
demeterCommandEnv :: OutputHandler -> FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO Bool demeterCommandEnv :: OutputHandler -> FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO Bool
demeterCommandEnv oh cmd params environ = catchBoolIO $ demeterCommandEnv oh cmd params environ = outputFilter cmd params environ
withHandle StdoutHandle createProcessSuccess p $ \outh -> do (\outh -> avoidProgress True outh stdouthandler)
-- ep <- async $ avoidProgress True errh $ stderrHandler oh (\errh -> avoidProgress True errh $ stderrHandler oh)
op <- async $ avoidProgress True outh $ \l ->
unless (quietMode oh) $
putStrLn l
-- wait ep
wait op
return True
where where
p = (proc cmd (toCommand params)) stdouthandler l =
{ env = environ } unless (quietMode oh) $
putStrLn l
{- To suppress progress output, while displaying other messages, {- To suppress progress output, while displaying other messages,
- filter out lines that contain \r (typically used to reset to the - filter out lines that contain \r (typically used to reset to the
@ -226,3 +217,23 @@ avoidProgress doavoid h emitter = unlessM (hIsEOF h) $ do
unless (doavoid && '\r' `elem` s) $ unless (doavoid && '\r' `elem` s) $
emitter s emitter s
avoidProgress doavoid h emitter avoidProgress doavoid h emitter
outputFilter
:: FilePath
-> [CommandParam]
-> Maybe [(String, String)]
-> (Handle -> IO ())
-> (Handle -> IO ())
-> IO Bool
outputFilter cmd params environ outfilter errfilter = catchBoolIO $ do
(_, Just outh, Just errh, pid) <- createProcess p
{ std_out = CreatePipe
, std_err = CreatePipe
}
void $ async $ tryIO (outfilter outh) >> hClose outh
void $ async $ tryIO (errfilter errh) >> hClose errh
ret <- checkSuccessProcess pid
return ret
where
p = (proc cmd (toCommand params))
{ env = environ }

7
debian/changelog vendored
View file

@ -1,3 +1,10 @@
git-annex (5.20150406.2) UNRELEASED; urgency=medium
* --quiet now suppresses progress displays from eg, rsync.
(Second time's the charm..)
-- Joey Hess <id@joeyh.name> Mon, 06 Apr 2015 20:14:20 -0400
git-annex (5.20150406.1) unstable; urgency=medium git-annex (5.20150406.1) unstable; urgency=medium
* Fixes a bug in the last release that caused rsync and possibly * Fixes a bug in the last release that caused rsync and possibly