+
+;; @@: So in order for this to work, we're going to have to add
+;; another channel to actors, which is resumable i/o. We'll have to
+;; spawn a fiber that wakes up a thunk on the actor when its port is
+;; available. Funky...
+
+(define (%suspend-io-to-actor resume-method get-wait-fd-method)
+ (lambda (port)
+ (define prompt (*actor-prompt*))
+ (define resume-channel (*resume-io-channel*))
+ (define (run-at-prompt k)
+ (spawn-fiber
+ (lambda ()
+ (suspend-current-fiber
+ (lambda (fiber)
+ (resume-on-readable-fd (port-read-wait-fd port) fiber)))
+ ;; okay, we're awake again, tell the actor to resume this
+ ;; continuation
+ (put-message resume-channel k))
+ #:parallel? #f))
+ (when (not prompt)
+ (error "Attempt to abort to actor prompt outside of actor"))
+ (abort-to-prompt (*actor-prompt*)
+ 'run-me run-at-prompt)))
+
+(define suspend-read-to-actor
+ (%suspend-io-to-actor resume-on-readable-fd port-read-wait-fd))
+
+(define suspend-write-to-actor
+ (%suspend-io-to-actor resume-on-writable-fd port-write-wait-fd))
+
+(define (with-actor-nonblocking-ports thunk)
+ "Runs THUNK in dynamic context in which attempting to read/write
+from a port that would otherwise block an actor's correspondence with
+other actors (note that reading from a nonblocking port should never
+block other fibers) will instead permit reading other messages while
+I/O is waiting to complete.
+
+Note that currently "
+ (parameterize ((current-read-waiter suspend-read-to-actor)
+ (current-write-waiter suspend-write-to-actor))
+ (thunk)))
+
+(define (actor-spawn-fiber thunk . args)
+ "Spawn a fiber from an actor but unset actor-machinery-specific
+dynamic context."
+ (apply spawn-fiber
+ (lambda ()
+ (*current-actor* #f)
+ (*resume-io-channel* #f)
+ (*actor-prompt* #f)
+ (thunk))
+ args))
+
+