What about using queues as proxy for your mailbox? Basically and naively:
(let loop () (read-a) (read-b) (read-c)))
and
(define (read-a) (let ((msg (dequeue! queue-a #f))) (if msg msg (let ((msg (thread-receive))) (cond ((is-a? msg) msg) ((is-b? msg) (enqueue! queue-b msg) (read-a)) ((is-c? msg) (enqueue! queue-c msg) (read-a)))))))
The two others are similar. Doing this, you keep the order you wanted, and it doesn't take much more memory: in the worse case, you just dispatch your whole mailbox into three queues, preserving the order in each of them.
Doesn't this solve your problem?
P!