# SDL\_WaitEvent not waking up properly?

**URL:** <https://discourse.libsdl.org/t/sdl-waitevent-not-waking-up-properly/21783>\
**Category:** SDL Development\
**Created:** [May 21, 2016, 10:26pm UTC](https://discourse.libsdl.org/t/sdl-waitevent-not-waking-up-properly/21783 "2016-05-21T22:26:30Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mark\_Sibly](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/mark_sibly/32/2672_2.png) [@Mark\_Sibly](https://discourse.libsdl.org/u/Mark_Sibly)\
**Post date:** [May 21, 2016, 10:26pm UTC](https://discourse.libsdl.org/t/sdl-waitevent-not-waking-up-properly/21783/1 "2016-05-21T22:26:30Z")

</div>

Hi,

Windows 10 SDL2 user here!

I’m using an SDL timer to SDL\_PushEvent a user event to the event queue,  
but this does not appear to be ‘waking up’ SDL\_WaitEvent immediately -  
there’s some weird delay between when I push the event (from the timer  
thread) and when SDL\_WaitEvent wakes up.

However, if I replace this:

SDL\_WaitEvent( Null );  
ProcessEvents(); //polls/pops events

…with this…

SDL\_Delay(1);  
ProcessEvents();

It all starts to work properly, ie: timer user events are processed  
immediately.

With SDL\_WaitEvent, the delivery of the user event gets ‘delayed’ by some  
amount of time - or more precisely, appears to be ‘quantized’ to 10ms-ish.

I have tried both SDL\_PushEvent and SDL\_PeepEvents from the timer thread,  
same result.

Is this expected behaviour of SDL\_WaitEvent? Does it always wait at least  
10ms or something? Can it not be interrupted by pushing an event?

Bye!  
Mark

---

<div class="post-metadata">

**Author:** ![Mark\_Sibly](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/mark_sibly/32/2672_2.png) [@Mark\_Sibly](https://discourse.libsdl.org/u/Mark_Sibly)\
**Post date:** [May 21, 2016, 10:40pm UTC](https://discourse.libsdl.org/t/sdl-waitevent-not-waking-up-properly/21783/2 "2016-05-21T22:40:58Z")

</div>

Ok, just found the SDL\_Delay(10) in SDL\_WaitEventTimeout()!

This is a bit disappointing. I had assumed all the event queue stuff was  
properly synchronized, but this throws a big nasty 10ms spanner in the  
works!

Oh well, at least I know what’s going on now.On Sun, May 22, 2016 at 10:26 AM, Mark Sibly \<@Mark\_Sibly\> wrote:

> Hi,
> 
> Windows 10 SDL2 user here!
> 
> I’m using an SDL timer to SDL\_PushEvent a user event to the event queue,  
> but this does not appear to be ‘waking up’ SDL\_WaitEvent immediately -  
> there’s some weird delay between when I push the event (from the timer  
> thread) and when SDL\_WaitEvent wakes up.
> 
> However, if I replace this:
> 
> SDL\_WaitEvent( Null );  
> ProcessEvents(); //polls/pops events
> 
> …with this…
> 
> SDL\_Delay(1);  
> ProcessEvents();
> 
> It all starts to work properly, ie: timer user events are processed  
> immediately.
> 
> With SDL\_WaitEvent, the delivery of the user event gets ‘delayed’ by some  
> amount of time - or more precisely, appears to be ‘quantized’ to 10ms-ish.
> 
> I have tried both SDL\_PushEvent and SDL\_PeepEvents from the timer thread,  
> same result.
> 
> Is this expected behaviour of SDL\_WaitEvent? Does it always wait at least  
> 10ms or something? Can it not be interrupted by pushing an event?
> 
> Bye!  
> Mark

---

<div class="post-metadata">

**Author:** ![rtrussell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/rtrussell/32/4768_2.png) [@rtrussell](https://discourse.libsdl.org/u/rtrussell)\
**Post date:** [May 22, 2016, 9:46am UTC](https://discourse.libsdl.org/t/sdl-waitevent-not-waking-up-properly/21783/3 "2016-05-22T09:46:23Z")

</div>

marksibly wrote:

> This is a bit disappointing. I had assumed all the event queue stuff was properly synchronized, but this throws a big nasty 10ms spanner in the works!

I second that! I really miss ‘proper’ thread synchronization capabilities; my event-polling loop wastes a lot of CPU time spinning with no delay to achieve an acceptable latency. Would it not be possible for SDL to call WaitForSingleObject() in Windows or pthread\_cond\_timedwait() in Linux?

Richard.

---

<div class="post-metadata">

**Author:** ![Mark\_Sibly](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/mark_sibly/32/2672_2.png) [@Mark\_Sibly](https://discourse.libsdl.org/u/Mark_Sibly)\
**Post date:** [May 23, 2016, 2:55am UTC](https://discourse.libsdl.org/t/sdl-waitevent-not-waking-up-properly/21783/4 "2016-05-23T02:55:23Z")

</div>

Actually, I sort of got this going using a semaphore - it’s as ugly as hell  
but seems to work in my code. Can share the code if you want, but it might  
be a bit dodgy.

There also appears to be a bug in the timer logic - it ‘skips’ every now  
and then if a tick happens at a certain place in the timer thread loop.

Perhaps the timer aren’t designed to be that accurate, but this prevented  
me implementing a 60hz timer via the timer returning 16,17,17,16,17,17 etc.  
intervals.

I’ve got a quick ‘n’ dirty fix for this too, but it probably needs  
attention from someone who knows what they’re doing (if it is in fact a  
bug).On Sun, May 22, 2016 at 9:46 PM, rtrussell wrote:

> marksibly wrote:
> 
> This is a bit disappointing. I had assumed all the event queue stuff was  
> properly synchronized, but this throws a big nasty 10ms spanner in the  
> works!
> 
> I second that! I really miss ‘proper’ thread synchronization capabilities;  
> my event-polling loop wastes a lot of CPU time spinning with no delay to  
> achieve an acceptable latency. Would it not be possible for SDL to call  
> WaitForSingleObject() in Windows or pthread\_cond\_timedwait() in Linux?
> 
> Richard.
> 
> * * *
> 
> SDL mailing list  
> SDL at [lists.libsdl.org](http://lists.libsdl.org)  
> [http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org](http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org)

---

<div class="post-metadata">

**Author:** ![rtrussell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/rtrussell/32/4768_2.png) [@rtrussell](https://discourse.libsdl.org/u/rtrussell)\
**Post date:** [May 23, 2016, 8:14am UTC](https://discourse.libsdl.org/t/sdl-waitevent-not-waking-up-properly/21783/5 "2016-05-23T08:14:16Z")

</div>

marksibly wrote:

> Actually, I sort of got this going using a semaphore

I use a semaphore too, but only as a means of signalling back to the ‘sending’ thread that the event has been read (I need a functionality like SendMessage in Windows).

I suppose the key question is whether SDL\_SemWaitTimeout uses a more efficient waiting mechanism (in terms of latency and CPU usage) than SDL\_WaitEventTimeout. If it does then I might be able to improve on my existing approach, but in that case why wouldn’t SDL do the same itself?

Richard.

---

<div class="post-metadata">

**Author:** ![Mark\_Sibly](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/mark_sibly/32/2672_2.png) [@Mark\_Sibly](https://discourse.libsdl.org/u/Mark_Sibly)\
**Post date:** [May 23, 2016, 9:09am UTC](https://discourse.libsdl.org/t/sdl-waitevent-not-waking-up-properly/21783/6 "2016-05-23T09:09:04Z")

</div>

> I use a semaphore too, but only as a means of signalling back to the  
> ‘sending’ thread that the event has been read

My goal was basically to make WaitEvent block properly instead of ‘spin’. I  
still like to do all my coding on the ‘main’ thread, so the timer callbacks  
just push a user event and return very quickly. But this does mean  
WaitEvent needs to be precise and not just delay(10) arbitrarily.

I got this going by posting to a semaphore in peepevents just after any  
events are added, and doing a wait on this semaphore in WaitEvent instead  
of the delay(10) when there are no events. The semaphore wait will often  
return immediately here because I’m posting in peepevents more than I need  
to, but that’s OK because it’ll eventually ‘flush’ the semaphore and block  
for real. Not 100% nice, but better than just thrashing delay(0).

The real fix is probably to only post when an event as added to an empty  
queue. The semaphore will still probably spin sometimes depending on how  
events are being pulled from the queue, but it should be generally better.

> I suppose the key question is whether SDL\_SemWaitTimeout uses a more  
> efficient waiting mechanism

Good question. Looking at the code, the windows one does, but the linux one  
only does if you have #defined HAVE\_SEM\_TIMEDWAIT - which I haven’t done  
(yet)!

But the above fix doesn’t even need a timed semaphore now that I think  
about it…On Mon, May 23, 2016 at 8:14 PM, rtrussell wrote:

> marksibly wrote:
> 
> Actually, I sort of got this going using a semaphore
> 
> I use a semaphore too, but only as a means of signalling back to the  
> ‘sending’ thread that the event has been read (I need a functionality like  
> SendMessage in Windows).
> 
> I suppose the key question is whether SDL\_SemWaitTimeout uses a more  
> efficient waiting mechanism (in terms of latency and CPU usage) than  
> SDL\_WaitEventTimeout. If it does then I might be able to improve on my  
> existing approach, but in that case why wouldn’t SDL do the same itself?
> 
> Richard.
> 
> * * *
> 
> SDL mailing list  
> SDL at [lists.libsdl.org](http://lists.libsdl.org)  
> [http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org](http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org)

---

<div class="post-metadata">

**Author:** ![rtrussell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/rtrussell/32/4768_2.png) [@rtrussell](https://discourse.libsdl.org/u/rtrussell)\
**Post date:** [May 23, 2016, 9:58am UTC](https://discourse.libsdl.org/t/sdl-waitevent-not-waking-up-properly/21783/7 "2016-05-23T09:58:03Z")

</div>

marksibly wrote:

> Looking at the code, the windows one does, but the linux one only does if you have #defined HAVE\_SEM\_TIMEDWAIT - which I haven’t done (yet)!

Presumably the HAVE\_SEM\_TIMEDWAIT is only useful if you’re rebuilding SDL from the source. Normally I will be using the pre-built SDL2.DLL in Windows and libsdl2.so in Linux. So I guess whether I can take advantage of a more efficient wait in SDL\_SemWaitTimeout depends on how the standard Linux packages are compiled, and indeed what the reason for the #define is in the first place. Do you know?

> But the above fix doesn’t even need a timed semaphore now that I think about it…

It would in my case because I’m creating my renderer with SDL\_RENDERER\_PRESENTVSYNC so once a frame I need it to spin in SDL\_RenderPresent rather than waiting for an event to arrive. If there was some way of posting a user event synchronously with (and slightly before) the Vsync it would be different, but I don’t think there is.

Richard.
