At Sun, 21 Apr 2013 18:30:44 +0200, Laurent wrote: > Is it possible to use scheme_call_enable_break [1] with a non-primitive > Racket procedure?
No. That C function is merely (define (call/enable-break f) (parameterize-break #t (f))) but in a more convenient form to call from C. More generally, scheme_call_enable_break() works with a kind of C function that is implicitly atomic except when explicitly yielding, and that model doesn't really fit with Racket functions (including ones that use the FFI). > In particular, I'd like to use it with shawnpresser's unix domain socket > package [2] and its `accept' function, but I'm not sure how to make one > work with the other. If I'm reading that code correctly, the implementation of `accept' uses accept() in a way that's going to block the Racket process (unless the given socket is configured as non-blocking). If a break is delivered to the process via Ctl-C or otherwise as an OS signal, accept() will return with EINTR, but that's independent of whether Racket breaks are allowed for the thread. I think you want to use scheme_fd_to_semaphore() [oops, not documented --- I'll fix that] to get a synchronizable event. Then, you can wait until a connection is ready; then, in atomic mode, double-check that a connection is still ready and accept it. Enable breaks while waiting on the semaphore iff breaks where enabled on entry, but otherwise disable breaks. Something like this (untested): (define MZFD_CHECK_READ 3) (define scheme_fd_to_semaphore (get-ffi-obj 'scheme_fd_to_semaphore#f (_fun _intptr _int _bool -> _racket))) (define (nice-accept fd break-ok?) (parameterize-break #f (lambda () (let loop () ;; wait, with breaks possibly enabled: (parameterize-break break-ok? (lambda () (sync (scheme_fd_to_semaphore fd MZFD_CHECK_READ #t)))) ((call-as-atomic (lambda () ;; in atomic mode to avoid a race between the accept test and ;; actually accepting; works as long as no other OS thread ;; or process accepts from the same socket. It may be better ;; to put the socket in non-blocking mode and handle EWOULDBLOCK, ;; instead. (if ....connection-ready? on s ... ;; Ready, accept it: (let ([v (accept s)]) (lambda () v)) ;; not ready, try again: loop)))))))) ____________________ Racket Users list: http://lists.racket-lang.org/users