next up previous
Next: A.16 vc-getname.setl Up: A. WEBeye Source Code Previous: A.14 vc-evzoom.setl

  
A.15 vc-exit.setl

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_fdnamefdidwidmonikerreadylineexited;
  sigchld_fd := open (`SIGCHLD', `signal');  -- catch CHLD signals
  exited := {};
  for [namefdin name_fd_pairs loop
    if fd /= om 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 [namefdin 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 [namefdin 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 [namefdin 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;


next up previous
Next: A.16 vc-getname.setl Up: A. WEBeye Source Code Previous: A.14 vc-evzoom.setl
David Bacon
1999-12-10