Textually #included by:
vc-camera.setl (Section A.4 [vc-camera.setl])
vc-do.setl (Section A.11 [vc-do.setl])
vc-event.setl (Section A.12 [vc-event.setl])
vc-giver.setl (Section A.17 [vc-giver.setl])
vc-httpd.setl (Section A.19 [vc-httpd.setl])
vc-image.setl (Section A.20 [vc-image.setl])
vc-javent.setl (Section A.23 [vc-javent.setl])
vc-model.setl (Section A.27 [vc-model.setl])
vc-mouse.setl (Section A.28 [vc-mouse.setl])
vc-ptz.setl (Section A.33 [vc-ptz.setl])
vc-push.setl (Section A.34 [vc-push.setl])
vc-recv.setl (Section A.36 [vc-recv.setl])
vc-seq.setl (Section A.39 [vc-seq.setl])
vc-simpler.setl (Section A.40 [vc-simpler.setl])
vc-snap.setl (Section A.41 [vc-snap.setl])
Source code: *
-- Send SIGTERM signals to all processes listed in name_fd_pairs
-- asking them to quit, and then quit the current process via stop.
-- First we ask politely, and if that doesn't work, we force the issue.
proc exit_gracefully (name_fd_pairs);
var sigchld_fd, name, fd, id, wid, moniker, ready, line, exited;
sigchld_fd := open (`SIGCHLD', `signal'); -- catch CHLD signals
exited := {};
for [name, fd] in name_fd_pairs loop
if fdom then
id := pid (fd);
moniker := name + ` (pid ' + str id + `)';
msg (`TERMinating ' + moniker);
clear_error;
kill (id); -- send SIGTERM
if last_error = no_error then
-- The subprocess either existed or was already a zombie.
-- First try to clear it quickly. If the process existed
-- when the signal was sent, we will receive a SIGCHLD as
-- soon as it manages to exit, and the following select
-- will then unblock. If the process was already a zombie,
-- this select will only hold up the show for 50 ms, as it
-- will if the process exists but does not exit that quickly:
[ready] := select ([{sigchld_fd}], 50);
if sigchld_fd in ready then
line := getline sigchld_fd;
end if;
-- If the process has exited (and is therefore now a zombie
-- unless it has already been waited for), it can be cleared
-- from the process table and added to our exited set:
while (wid := wait (false)) > 0 loop
exited with:= wid;
end loop;
if id in exited then
-- The subprocess has exited, so we can safely call close
-- on its file descriptor without blocking, and carry on.
close (fd);
continue for [name, fd] in name_fd_pairs loop; -- next!
end if;
if sigchld_fd notin ready then
-- We have no indication of the subprocess having exited yet.
-- Give it a bit more time. We didn't want to start out
-- this way, because if the subprocess had already been a
-- zombie, we would have waited the full 1414 ms:
[ready] := select ([{sigchld_fd}], 1414);
if sigchld_fd in ready then
line := getline sigchld_fd;
end if;
while (wid := wait (false)) > 0 loop
exited with:= wid;
end loop;
if id in exited then
close (fd);
continue for [name, fd] in name_fd_pairs loop; -- next!
end if;
end if;
-- The subprocess seems reluctant to exit. Hit it harder.
msg (`KILLing ' + moniker);
kill (id, `KILL'); -- send SIGKILL
[ready] := select ([{sigchld_fd}], 100);
if sigchld_fd in ready then
line := getline sigchld_fd;
end if;
while (wid := wait (false)) > 0 loop
exited with:= wid;
end loop;
if id in exited then
close (fd);
continue for [name, fd] in name_fd_pairs loop; -- next!
end if;
-- This probably indicates a bug in the host OS
msg (`*** ' + moniker + ` failed to exit on KILL signal');
else
msg (`*** ' + moniker + ` not found');
end if;
end if;
end loop;
close (sigchld_fd);
msg (yhwh + ` (' + str pid + `) exiting');
stop;
end proc;