async-apply in FFI not being called

27 views
Skip to first unread message

Андрей Кравчук

unread,
May 9, 2019, 9:19:19 AM5/9/19
to Racket Users
Hello.
I'm trying to fix SDL2 library bindings for Racket. The library includes the function SDL_AddTimer, which, according to documentation, takes callback and runs it in another thread. Without #:async-apply keyword on FFI callback definition the call to SDL_AddTimer segfaults, which is to be expected. Adding #:async-apply fixes the crash, but in that case it seems that the callback is not being called (and even async-apply helper itself).
Here's the code:

(define (async-apply thunk)
    (displayln "in async-apply")  ;; never gets called
    (thunk))

(define _SDL_TimerCallback (_fun #:async-apply async-apply _uint32 _pointer -> _uint32))

(define-sdl2 SDL_AddTimer (_fun _uint32 _SDL_TimerCallback _pointer -> _int))

(SDL_AddTimer
  1000
 (lambda (interval dummy)
     (displayln "in callback")  ;; never gets called
     1000)
 #f)

(sleep 10)

Could someone please point me at what am I doing wrong?

Matthew Flatt

unread,
May 9, 2019, 9:42:47 AM5/9/19
to Андрей Кравчук, Racket Users
This code work for me on macOS from the command line. It does not work
in DrRacket, and that's because an async callback is not allowed to do
anything that has to synchronize with a Racket thread. DrRacket's
output requires thread synchronization, while it happens that stdout in
a terminal usually doesn't have to synchronize. In short, don't use
ports in an async callback.

Try using `log-error` instead of `displayln`, since it's safe to log a
message in an async callback. If I make that change, I see logging when
running in DrRacket --- but also a crash soon after, because nothing
keeps the callback live.

Changing to

(define callback
(lambda (interval dummy)
(log-error "in callback") ;; never gets called
1000))

(SDL_AddTimer
1000
callback
#f)

keeps the callback live and avoids a crash.
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/0cc49a07-c070-4636-8901-a13ae5a4
> 7e6d%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Andrew Kravchuk

unread,
May 9, 2019, 10:48:43 AM5/9/19
to Racket Users
That did the trick, thanks a lot, Matthew!
Reply all
Reply to author
Forward
0 new messages