# IPC

```Hi Alex,

I am struggling to understand picolisp IPC functions (hear, tell, rpc,
sync...).  I have attached code for the Dining Philosophers problem
which gets stuck after calling 'hear' in the philosopher (child)
process.  The idea is that each philosopher is a process which opens a
fifo and all philosophers talk to their neighbours via those fifos.```
```
'hear' in the following snippet seems to block the whole process:

...
(log 'before)
(hear (mailbox I))
(log 'after)
...

outputs

\$ ~/picolisp/p phil.l
0 -1 0 before
1 -1 0 before
2 -1 0 before
3 -1 0 before
4 -1 0 before
:

..only and does nothing afterwards.  I would expect 'hear' to install
some kind of event handler which would evaluate incoming messages and
then carry on immediately with the next (log 'after) line.  Is my
understanding correct?  I though that 'hear' was working in the
background so why the code blocks?

Thank you,

Tomas

```
```# ~/picolisp/p phil.l
# http://en.wikipedia.org/wiki/Dining_philosophers_problem
# Chandy / Misra solution
# philosophers: N = total, I = current, P = other
# forks: L = left, R = right; lt0 ~ dirty, =0 none, gt0 ~ clean

(de log @
(pass println I L R)
(flush) )

(de idle ()
(wait (rand 1000 3000)) )

(de left ()
(% (+ N (- I 1)) N) )

(de right ()
(% (+ I 1) N) )

(de mailbox (P)
(pack "phil" P) )

(de obtain (P)
(log 'obtain P)
(when (= P (left))
(if (=0 L)
(setq L 1)
(quit "Already have the left fork") ) )
(when (= P (right))
(if (=0 R)
(setq R 1)
(quit "Already have the right fork") ) ) )

(de give (P)
(log 'give P)
(when (and (= P (left)) (lt0 L))
(out (mailbox P)
(rpc 'obtain I) )
(setq L 0) )
(when (and (= P (right)) (lt0 R))
(out (mailbox P)
(rpc 'obtain I) )
(setq R 0) ) )

(de grab ()
(while (or (=0 L) (=0 R))
(when (lt0 L)
(setq L 1) )
(when (lt0 R)
(setq R 1) )
(when (=0 L)
(out (mailbox (left))
(rpc 'give I) ) )
(when (=0 R)
(out (mailbox (right))
(rpc 'give I) ) )
(wait 500) ) )

(de phil (I N L R)
(unless (info (mailbox I))
(call 'mkfifo (mailbox I)) )
(log 'before)
(hear (mailbox I))
(log 'after)
(loop
(log 'thinking)
(idle) # think
(log 'hungry)
(grab)
(log 'eating)
(idle) # eat
(setq L -1 R -1) ) ) # dirty

(de main (N)
(push '*Bye '(mapc 'kill *C))
(for (I 0 (< I N) (inc I))
(if (fork)
(push '*C @)
(phil I N -1 0) ) ) )

(main 5)
```