I think it's possible if you have a single shared mutex protecting access (both read and write) to the is_blocked variables and make the sending program clear the counterpart's is_blocked variable, but I haven't run through all of the scenarios. I'll see if I can implement it myself with perl's threads (with and without a mutex) and try and replicate the undefined behaviour.
Yep, as expected.
Without a mutex it randomly detects an early deadlock (at a whole load of values below the actual answer, not just 127). It works correctly about 1 in 10 times for me.
If I clear the is_blocked variable when sending (without mutex protection) it never detects a deadlock.
With a mutex, and protecting the send/receive code with that mutex, it works fine.
The horror:
http://www.greenbank.org/misc/aoc/2017_18t_mutex.txt(I should really minimise the snd/rcv stuff done inside the mutex lock.)
I hate perl threads/mutexes.