0

I have an SDL2 c++ program that generates an SDL_window, while also employing a socket server that receives data through recv. I noticed that whenever recv is blocking and expecting data, the SDL window actions like window motion with a mouse, or minimizing and closing the window by clicking the corner buttons are disabled. Of course I expect the program functions to be frozen while recv is blocking, but I am surprized about window motion being frozen as well, since I would expect that this would be handled in parallel by the OS. Is there anything I can do to retain SDL_window motion while recv blocks?

EDIT:

In terms of code, the window is created by a call to

gWindow = SDL_CreateWindow("Program", 0, 55, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALWAYS_ON_TOP);

within the SDL initialization call. The program runs in loops, and there is an SDL event handler

SDL_Event e;

which is used to catch e.g. a click to close the window

while (SDL_PollEvent(&e) != 0)
            {
                //User requests quit
                if (e.type == SDL_QUIT)
                {
                    quit = true;
                }
            }

I guess it makes sense that this functionality is disabled while recv is blocking. I just wonder if there is an extra layer one can add to let the OS take over this task, which would not yet be in my code at all.

Kagaratsch
  • 963
  • 8
  • 18
  • It really helps to show code rather than talk at length about the problem. We can reproduce the problem with the right code, but we can't with this. – tadman Aug 11 '20 at 21:27
  • 3
    The UI window operations you describe still require message processing. So you need to either move the socket operations to a separate worker thread, or else use non-blocking sockets. Either way will not block your UI thread from processing UI messages from the OS. – Remy Lebeau Aug 11 '20 at 21:30
  • 1
    Some useful options here: https://stackoverflow.com/questions/47146174/is-it-possible-to-use-select2-to-watch-for-sdl-text-input-events – user4581301 Aug 11 '20 at 21:32

1 Answers1

1

Turns out, the solution to my problem was simply to add a 100 millisecond timeout to recv

DWORD timeout = 100;// millisecond timeout for receiving data
setsockopt(ClientSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

then, in case if no data is received, I skip the part of the code that expects non-trivial data during this cycle

iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult == SOCKET_ERROR)
                        {
                            if (WSAGetLastError() == WSAETIMEDOUT) {
                                goto SKIP;
                            }
                        }

Now recv does not block indefinitely and all window functions remain intact to a human (whose reaction time is roughly 200 milliseconds).

Note that this is specific to Windows system. See this thread for similar solutions on other systems.

Kagaratsch
  • 963
  • 8
  • 18
  • I am glad you have got your solution and thanks for your sharing, I would appreciate it if you mark them as answer and this will be beneficial to other community. – Barrnet Chou Aug 14 '20 at 05:57