 
 : mailbox-put ( obj mailbox -- )
     [ mailbox-data dlist-push-end ] keep
-    [ mailbox-threads ] keep 0 <vector> swap set-mailbox-threads
-    [ schedule-thread ] each yield ;
-
-<PRIVATE
-: (mailbox-block-unless-pred) ( pred mailbox -- )
-    2dup mailbox-data dlist-contains? [
-        2drop
-    ] [
-        [ swap mailbox-threads push stop ] callcc0
+    [ mailbox-threads ] keep
+    V{ } clone swap set-mailbox-threads
+    [ thread-continuation schedule-thread ] each yield ;
+
+<PRIVATE
+: (mailbox-block-unless-pred) ( pred mailbox timeout -- )
+    2over mailbox-data dlist-contains? [
+        3drop
+    ] [
+        [ <thread> swap mailbox-threads push stop ] callcc0
         (mailbox-block-unless-pred)
     ] if ; inline
 
-: (mailbox-block-if-empty) ( mailbox -- mailbox2 )
-    dup mailbox-empty? [
-        [ swap mailbox-threads push stop ] callcc0
+: (mailbox-block-if-empty) ( mailbox timeout -- mailbox2 )
+    over mailbox-empty? [
+        [ <thread> swap mailbox-threads push stop ] callcc0
+        "(mailbox-block-if-empty)" print flush
         (mailbox-block-if-empty)
-    ] when ;
-PRIVATE>
-: mailbox-get ( mailbox -- obj )
+    ] [
+        drop
+    ] if ;
+PRIVATE>
+: mailbox-get* ( mailbox timeout -- obj )
     (mailbox-block-if-empty)
     mailbox-data dlist-pop-front ;
 
-: mailbox-get-all ( mailbox -- array )
+: mailbox-get ( mailbox -- obj )
+    f mailbox-get* ;
+
+: mailbox-get-all* ( mailbox timeout -- array )
     (mailbox-block-if-empty)
     [ dup mailbox-empty? ]
     [ dup mailbox-data dlist-pop-front ]
     { } unfold ;
 
+: mailbox-get-all ( mailbox -- array )
+    f mailbox-get-all* ;
+
 : while-mailbox-empty ( mailbox quot -- )
     over mailbox-empty? [
         dup >r swap slip r> while-mailbox-empty

        2drop
    ] if ; inline

: mailbox-get? ( pred mailbox -- obj )
    2dup (mailbox-block-unless-pred)
    mailbox-data dlist-remove ;
    inline

TUPLE: process links pid mailbox ;


        [ set-promise-value ] keep
        [ t swap set-promise-fulfilled? ] keep
        [ promise-processes ] keep
        V{ } clone swap set-promise-processes
        [ thread-continuation schedule-thread ] each yield
    ] if ;

<PRIVATE
 : (maybe-block-promise) ( promise timeout -- promise )
    #! Block the process if the promise is unfulfilled. This is different from
    #! (mailbox-block-if-empty) in that when a promise is fulfilled, all threads
    #! need to be resumed, rather than just one.
    over promise-fulfilled? [
        drop
    ] [
        [ <thread> swap promise-processes push stop ] callcc0
        drop
    ] if ;
PRIVATE>

: ?promise* ( promise timeout -- result )
    (maybe-block-promise) promise-value ;

: ?promise ( promise -- result )
    f ?promise* ;

! ******************************
! Experimental code below
