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]

Reply via email to