SDL_PumpEvents uses long time sometimes [solved]

Hello there,

I’m having some trouble with SDL_PumpEvents. Sometimes (not always) it needs a very long time to return (>500000 Performance counts). For this to happen, I’m running the whole SDL Video Subsystem in it’s own thread, there’s no access to the renderer/window/events outside this thread. In my project, I only call SDL_PumpEvents() to update the current keyboard state (before calling SDL_GetKeyboardState()). It doesn’t matter if there’s a delay between the calls to it, it happens any way.

System Info:
I’m developing on Windows 7x64 using Msys2/ Mingw_w64 (gcc version 8.2.1 20181214) and SDL v2.0.9 (downloaded/installed via msys2). The Project is compiled 64-bit aswell.

cflags: gcc.exe -Wall -IC:/msys64/mingw64/include/SDL2 -O2 -m64 -c main.c -o main.o
lflags: g++.exe -o PumpEventsTest.exe main.o -LC:/msys64/mingw64/lib -lmingw32 -lSDL2main -lSDL2 -s -m64

Example code to reproduce the issue:

#include <stdio.h>
#include <stdlib.h>

#define SDL_MAIN_HANDLED /* Use normal main */
#include <SDL2/SDL.h>

#define  MAX_TIMEDIFF_ALLOWED 500 /* Change this value for testing */

int threadFunc(void *arg);

int main (void)
{
  SDL_Init(0);
  SDL_Thread *thr;

  thr=SDL_CreateThread(threadFunc,"TestThread",NULL);
  if(!thr)
  {
    fputs("SDL_CreateThread() failed",stderr);
    return(EXIT_FAILURE);
  }
  SDL_WaitThread(thr,NULL);
  SDL_Quit();
  return(EXIT_SUCCESS);
}

int threadFunc(void *arg)
{
  SDL_Window *window;
  SDL_Renderer *renderer;
  Uint64 timePerf[2];
  Uint64 timeDiff;
  SDL_InitSubSystem(SDL_INIT_VIDEO);
  window=SDL_CreateWindow("TestWindow",
                          SDL_WINDOWPOS_CENTERED,
                          SDL_WINDOWPOS_CENTERED,
                          640,
                          320,
                          0);
  renderer=SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED);
  SDL_RenderClear(renderer);
  while(1)
  {
    timePerf[0]=SDL_GetPerformanceCounter();
    SDL_PumpEvents();
    timePerf[1]=SDL_GetPerformanceCounter();
    timeDiff=timePerf[1]-timePerf[0];

    SDL_Delay(10); /* Use this delay or not, doesn't matter */
    printf("Time diff: %"SDL_PRIu64"\n",timeDiff);
    if(timeDiff>MAX_TIMEDIFF_ALLOWED) /* change value here for testing! */
    {
      printf("Timediff greater than max (%"SDL_PRIu64"), Frequency/s=%"SDL_PRIu64"\n",timeDiff,SDL_GetPerformanceFrequency());
      getchar();
    }
  }
  /* Quit subsystem here again, not implemented/needed for this test */
  return(0);

My sample output is like:

Time diff: 49
Time diff: 24
Time diff: 24
Time diff: 26
Time diff: 23
Time diff: 23
Time diff: 24
Time diff: 30
Time diff: 22
Time diff: 523945
Timediff greater than max (523945), Frequency/s=3512207

Tell me if you need more information to reproduce, and if I should open a bug report for this, or there’s a known workaround.

Greetings,

XXXBold

This is a bug in 2.0.9
The workaround is to add SDL_INIT_JOYSTICK to the SDL_Init() call (or build SDL2 yourself from latest hg)

1 Like

Wow, thank you for the quick answer. Yes, it’s fixed when applying your hint (Sometimes it still takes around ~1000 counts, but that’s absolutely okay), thank you very much! Guess it’s fine to add it as a workaround for now :slight_smile:

A related question for the experts: is it always safe to run the video subsystem in its own thread, or must it be in the ‘main’ thread on some platforms (I’m thinking maybe Android)?