Package: hpodder Version: 1.1.5.0 Severity: normal I run hpodder in a cronjob to download podcasts overnight. About once a week or so, I notice that hpodder is hanging forever. I don't know for sure what causes these hangs, but I can produce the same behavior by running "killall curl" while "hpodder update" is running. It looks like what happens is this: when curl fails, the download process (in DownloadQueue.hs) notices this fact and invokes update's callback with the result information from the download. The update callback proceeds to call exitFailure, and according to the ghc documentation:
==== exitWith :: ExitCode -> IO a Computation exitWith code throws ExitException code. Normally this terminates the program, returning code to the program's caller. Before the program terminates, any open or semi-closed handles are first closed. A program that fails in any other way is treated as if it had called exitFailure. A program that terminates successfully without calling exitWith explicitly is treated as it it had called exitWith ExitSuccess. As an ExitException is not an IOError, exitWith bypasses the error handling in the IO monad and cannot be intercepted by catch from the Prelude. However it is an Exception, and can be caught using the functions of Control.Exception. This means that cleanup computations added with Control.Exception.bracket (from Control.Exception) are also executed properly on exitWith. exitFailure :: IO a The computation exitFailure is equivalent to exitWith (ExitFailure exitfail), where exitfail is implementation-dependent. ==== My guess is that either something is catching the ExitError and throwing it away. It could also be that a cleanup computation is deadlocking, but I don't think so. Either way, the result is that the program doesn't exit, but the semaphore is never signaled, so the main thread just hangs. I found a fix that papers over this problem: it breaks the "exit with failure on failure" semantics, but at least it avoids hanging forever. Moreover, it fixes a number of similar potential bugs. I apologize for the lack of a patch, but I don't have time atm to strip out my debugging code and get a clean copy of hpodder, so I'll just describe it. Import Control.Exception(finally) in DownloadQueue. Instead of relying on childthread to tail out and call signalQSem, use Control.Exception.finally to do it: semaphore <- newQSem 0 -- Used by threads to signal they're done mapM_ (\_ -> forkIO (handleSqlError $ finally (childthread dqmvar) (signalQSem semaphore))) [1..maxthreads] mapM_ (\_ -> waitQSem semaphore) [1..maxthreads] and childthread :: MVar (DownloadQueue a) -> IO () childthread dqmvar = do workdata <- getworkdata if length(workdata) == 0 then return () else do processChildWorkData workdata childthread dqmvar -- And look for more hosts where getworkdata = modifyMVar dqmvar $ \dq -> This ensures that no matter how childthread exits, the semaphore is signaled (so exceptions / errors that occur in it don't hang hpodder). On my system, this means that "update" exits successfully and "fetch" proceeds to download any new episodes that it found, which I'm fine with. Daniel -- System Information: Debian Release: 5.0 APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.26-1-686 (SMP w/2 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages hpodder depends on: ii curl 7.18.2-7 Get a file from an HTTP, HTTPS or ii id3v2 0.1.11-3 A command line id3v2 tag editor ii libc6 2.7-16 GNU C Library: Shared libraries ii libgmp3c2 2:4.2.2+dfsg-3 Multiprecision arithmetic library ii libsqlite3-0 3.5.9-6 SQLite 3 shared library hpodder recommends no packages. hpodder suggests no packages. -- no debconf information -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]