Search code examples
c++windowssocketsvisual-studio-2017sdl-2

Maintain window motion and close actions while socket recv is blocking awaiting data?


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.


Solution

  • 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.