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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CANy33qnFo1hYcasdNm%2BN29bW3HbqtuYG8X-cCkgoZpJw%3DqKDWw%40mail.gmail.com.

Reply via email to