Main dispatch queue in Linux/SDL app?

I've got a pretty decent little macOS/Linux cross-platform app working with SDL2 now, but I just ran into an issue where using DispatchQueue.main.async {} doesn't work on Linux; the block never executes. It does, however, execute on macOS.

The main part of my program is a loop that waits on the SDL event queue at the start of each loop. It then handles the events (which are mostly timers firing) that usually initiate network requests.

My guess is SDL’s macOS implementation of SDL_WaitEvent() is allowing the main queue to run other blocks, but not the Linux implementation. Is there a call I can make to let my main loop yield to GCD so other blocks can run? Any suggestion on how to go idle until an SDL event is available?

Thanks.

1 Like

I think you need to call dispatchMain() to get the main queue running. I’m guessing the Mac version has something calling it implicitly.

1 Like

Any suggestion on how to go idle until an SDL event is available?

On Apple platforms, the main thread’s run loop services the main dispatch queue. Search swift-corelibs-foundation for _dispatch_main_queue_callback_4CF to see how this works. Looking at the code, it seems to be set up to function on Linux, leaving you with one of two possibilities:

  • There’s some sort of bug.

  • SDL’s main loop is not running the run loop on Linux

It’s seems likely it’s the latter.


As to how you fix this, there’s a bunch of potential approaches you can take, but the most important thing is how you integrate with SDL’s abstractions. I think you should dig into SDL_WaitEvent to see how it works on Apple platforms. Given that Swift’s Foundation brings run loop along with it, it’s possible you could just switch it over to using run loops on Linux.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

2 Likes

I haven’t been able to figure out what SDL does on macOS if you don’t instantiate SDLApplication (a subclass of NSApplication), which I don’t. Grepping through the code I haven’t been able to find calls to dispatchMain() or an obvious NSRunLoop setup (there are run loops in some HID and audio code, and calls to get the global dispatch queue, but nothing obvious).

The event handling for Cocoa (which I’m not at all sure is what’s at play in a macOS build) calls [NSApp nextEventMatchingMask:…], and [NSApp sendEvent:], but since I'm not instantiating NSApplication, I don't think that’s involved. Not at all sure, though.

I’ve thought of a way to just call dispatchMain() in Linux-only portions of my code, looping on SDL_WaitEvent() on a separate queue and dispatching those back to the main queue. I haven’t tried it yet, but I think it’ll work.

I haven’t been able to figure out what SDL does on macOS if you don’t
instantiate SDLApplication …. Grepping through the code I haven’t
been able to find calls to dispatchMain or an obvious NSRunLoop
setup

One trick for uncovering this mechanism is to set a breakpoint on one of your event handlers and then look at the backtrace.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like

Alas, one typically calls into SDL to request the next event. However, there is an event watcher mechanism that might shed light on the situation. Thanks!