Commit Graph
4 Commits
Author SHA1 Message Date
Isaac ConnorandClaude Opus 5.5 42c37cdcbb fix: close the zms command socket as soon as the command thread stops
The command socket stayed bound until ~StreamBase(), which runs only after
the stream thread has finished. A zms that was shutting down but still busy
in the stream thread (blocked writing to a client that had gone away, for
instance) kept accepting commands it would never read. web/ajax/stream.php
then waited out its whole MSG_TIMEOUT on each one and logged "Timed out
waiting for msg ... after waiting 5000 milliseconds", where a missing socket
would have been reported as no_socket at once.

Call closeComms() when checkCommandQueue() leaves its loop. sd is only used
from the command thread, and closeComms() clears sd and lock_fd, so the
destructor's later call does nothing and cannot remove a socket bound by a
successor zms on the same connkey.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 17:12:27 -04:00
Jash 5e0d6afaf4 fix: send pre-scaled frames as built when scale or zoom changes refs #3681 2026-08-26 18:22:39 +05:30
Jash e48ae03275 perf: scale during colour conversion in zms playback fixes #3681 2026-08-26 11:15:19 +05:30
Isaac ConnorandClaude Opus 5 403b1cd982 fix: initialise StreamBase::lock_fd to -1 refs #5029
lock_fd was initialised to 0, but every other use in the class treats a
negative value as "no lock held": openComms() sets it to -1 when open() or
flock() fails, and closeComms() guards on `lock_fd >= 0` before closing.

The constructor's 0 passes that guard, so a StreamBase destructed without
openComms() having succeeded calls close(0) and closes stdin. Reaching it only
takes connkey > 0 plus a runStream() that returns before openComms(), and
MonitorStream::runStream() has two such returns: the STREAM_SINGLE branch and
the !monitor branch. mode=single URLs still carry a connkey, so both are
reachable in normal operation.

zms exits shortly afterwards and does little in between, so the practical
impact today is small. It is still closing a descriptor the class does not own,
and once fd 0 is free the next open() in the process silently lands on it.

Add a regression test covering destruction with and without a connkey. It saves
and restores fd 0 so a failure can't cascade into the rest of the suite.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 08:03:13 -04:00