Penging IpcIo requests are now stored in two alternating maps: "old" and
"new". Every T seconds, any requests remaining in the "old" map are treated
as timed out. After that check, the current "new" and (now empty) "old" map
pointers are swapped so that the previously "new" requests can now age for T
seconds. New requests are always added to the "new" map. Responses are
always checked against both maps.
This approach gives us access to pending request information and allows to
report errors to the right I/O requestors without creating additional
per-request state attached to a per-request timeout event. The price is (a)
two instead of one map lookups when the response comes and (b) timeout
precision decrease from "about T" to "anywhere from T to 2*T".