next up previous
Next: A.24 vc-jmaster.cgi Up: A. WEBeye Source Code Previous: A.22 vc-input.setl

  
A.23 vc-javent.setl

Textually #included by:
vc-evjump.setl     (Section A.13 [vc-evjump.setl])
vc-evzoom.setl     (Section A.14 [vc-evzoom.setl])

Textually #includes:
vc-exit.setl     (Section A.15 [vc-exit.setl])
vc-getname.setl     (Section A.16 [vc-getname.setl])
vc-msg.setl     (Section A.30 [vc-msg.setl])
vc-obtain.setl     (Section A.31 [vc-obtain.setl])
vc-provide.setl     (Section A.32 [vc-provide.setl])

Source code: *

-- This file is meant to be #included by others, after they define:
--
-- yhwh  -  the name of the program that #includes this code
-- event_type  -  the name of the service being provided
-- of_interest  -  the command tokens we look for
-- n_parms  -  how many parameters after the command tokens to expect
 
const n = #of_interest;
 
const notice_fd = fileno obtain_service (`notice');
const sigterm_fd = open (`SIGTERM', `signal');  -- catch TERM signals
const server_fd = fileno provide_service (event_type);
 
var clients := {};
var current_event := om;
 
open (`SIGPIPE', `ignore');  -- as when we write to closed observers
 
loop
 
  [ready] := select ([{sigterm_fdserver_fdnotice_fd} +
                                                     domain clients]);
 
  if sigterm_fd in ready then
    msg (yhwh + ` (' + str pid + `) caught SIGTERM');
    quit_gracefully;
  end if;
 
  for client = clients(pump_fd) | pump_fd in ready loop
    ack := getline pump_fd;
    if eof then
      done_client (pump_fd);
    else
      if client.last_event /= current_event then
        tell_client (pump_fdcurrent_event);
      else
        clients(pump_fd).hungry := true;
      end if;
    end if;
  end loop;
 
  if server_fd in ready then
    fd := accept (server_fd);
    if fd /= om then
      name := getname fd;
      msg (name+` accepted');
      pump_fd := pump();
      if pump_fd = -1 then
        -- child
        while (event := getline stdin/= om loop
          printa (fdevent);
          if (ack := getline fd) = om then
            stop;
          end if;
          print;
        end loop;
        stop;
      end if;
      -- parent continues here
      close (fd);
      client := {};
      client.name := name;
      client.hungry := true;
      clients(pump_fd) := client;
      -- send initial event if any
      if current_event /= om then
        tell_client (pump_fdcurrent_event);
      end if;
    end if;
  end if;
 
  if notice_fd in ready then
    reada (notice_fdraw_event);
    if is_string raw_event then
      t := split (raw_event);
      if t(1..n) = of_interest and #t-n = n_parms then
        tell_observers ((+/[` '+x : x in t(n+1..)])(2..));
      end if;
    end if;
  end if;
 
end loop;
 
proc tell_observers (event);
  for client = clients(pump_fdloop
    if client.hungry then
      tell_client (pump_fdevent);
    end if;
  end loop;
  current_event := event;
end proc tell_observers;
 
proc tell_client (pump_fdevent);
  printa (pump_fdevent);
  flush (pump_fd);
  if last_error /= no_error then
    done_client (pump_fd);
  else
    client := clients(pump_fd);
    client.hungry := false;
    client.last_event := event;
    clients(pump_fd) := client;
  end if;
end proc tell_client;
 
proc done_client (pump_fd);
  msg (clients(pump_fd).name + ` done');
  close (pump_fd);
  clients(pump_fd) := om;
end proc done_client;
 
proc quit_gracefully;
  exit_gracefully ([[`pump for client ' + client.namepump_fd] :
                                          client = clients(pump_fd)]);
end proc;
 
#include ``vc-provide.setl''
#include ``vc-obtain.setl''
#include ``vc-getname.setl''
#include ``vc-exit.setl''
#include ``vc-msg.setl''


next up previous
Next: A.24 vc-jmaster.cgi Up: A. WEBeye Source Code Previous: A.22 vc-input.setl
David Bacon
1999-12-10