> (de main (N)
> (ifn (fork)
> (setq *Monitor @)
> (push '*Bye '(kill *Monitor)) )
> (setq *Philosophers # Build a list of PIDs
good point, thanks!
>> I am wondering how/when picolisp calls the asynchronous handler? Is
> This happens in the functions 'wait', 'sync', 'listen' and 'key', or
> when waiting for user input at the console.
>> I imagine that the problem is that 'defer' called from the IPC
>> handler changes '*Pending' queue while the 'while' loop is
> I don't think so. Deferred expressions only contain 'giveNow', which
> in turn only calls 'handOver' -> 'changed' -> 'philState'. Nowhere
> in this chain is a call to one of the above functions. I didn't take
> the time yet to directly debug or trace it, though.
It looks like it also happens during 'tell' and/or (any?) I/O which
might be the problem here because giveNow hands over the chopstick
using 'tell' which then handles any new signals during write.
Which makes me think that if a handler uses IPC or calls any of the
above functions, it might get recursive. I should probably avoid that
and only queue things to do in a handler and do them in the main loop
> For database synchronization, for example, this is done in 'dbSync'
> (lib/db.l:750). A transaction on a db that is accessed by more than one
> process is always surrounded by (dbSync) and (commit 'upd), or done
> implicitly by the 'put!>' etc. methods of the '+Entity' class.
And for that it uses locks, doesn't it? I wanted to avoid locks in
phil.l because that was the whole point of Chandy / Misra solution;-)
> BTW, wouldn't be the handling of '*State' a good candidate for the
> 'state' function?
It could be, but it seems to me that the state machine is only a
simple sequence so it would not be more readable than this:
(finish) ) )