I'm trying to figure out how to use ffi/unsafe/os-thread to call a
long-running foreign function in an OS thread to avoid blocking other
Racket threads. I want to communicate the result of the foreign call to the
original Racket thread and have it wake up when the call completes.
Normally I could use a channel, but OS threads are not allowed to use
Racket synchronization primitives (channels, semaphores, etc). I can't use
a spinlock, because the docs for call-in-os-thread say that mutations are
allowed but their visibility is unspecified except as synchronized by
os-semaphores. The docs for os-semaphore-wait say that if it is called by a
Racket thread (ie, not a restricted OS thread), then waiting blocks all
Racket threads, which I want to avoid.
Places already have to solve the problem of bridging OS threads and Racket
synchronization. So here's my best idea so far: use a variable (or box)
protected by an os-semaphore for communicating the result, but use a place
channel for the synchronization. The code looks like this:
(define result #f)
(define os-sema (make-os-semaphore))
(define-values (c1 c2) (place-channel))
(call-in-os-thread
(lambda ()
(set! result (...))
(os-semaphore-post os-sema)
(place-channel-put c1 'ready)))
(void (sync c2))
(os-semaphore-wait os-sema)
result
This "works", but is it reliably safe to use place-channel-put from an OS
thread? Or is there a better way to do this?
Ryan
--
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/racket-users/CANy33qnFo1hYcasdNm%2BN29bW3HbqtuYG8X-cCkgoZpJw%3DqKDWw%40mail.gmail.com.