Skip to content

webhttrack waits forever at exit when no mirror was launched (off-by-one in htsthread_wait_n) #753

Description

@xroche

htsweb.c:310 ends the server with:

htsthread_wait_n(background_threads - 1);

background_threads counts the threads that must not be waited for: the client_ping pinger, plus one per launched mirror. Subtracting one from it asks the wait to leave one fewer thread outstanding than there are non-joinable ones, so with no mirror launched it degrades to htsthread_wait_n(0) while the pinger still holds a slot. client_ping() never returns on POSIX (it loops until the parent dies, then calls exit()), so the wait cannot be satisfied.

Normally this is invisible: the pinger kills the process when the launcher script goes away. It shows on the error path, where help_server() fails fast and there is no mirror to excuse the off-by-one:

$ python3 -c "import socket,os,time; s=socket.socket(); s.bind(('127.0.0.1',18747)); s.listen(1); print(os.getpid()); time.sleep(300)" &
$ htsserver /usr/share/httrack/ --port 18747 --ppid <that pid>
Unable to initialize a temporary server (no remaining port)
EXITED
<hangs>

Master hangs there in 4 runs out of 10 (it is a race with the pinger's own start). Rebuilding with background_threads instead of background_threads - 1 hangs in 0 out of 10.

Found while working on #747. That fix counts a thread from the moment it is spawned rather than when it starts running, which closes the window the pinger was slipping through, and takes this from 4 in 10 to 10 in 10. The off-by-one is the actual defect and predates it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions