lundi 7 janvier 2019

Portably exit readline from C++11 thread with SDL2

Consider a simple program: (require -std=c++11 -lpthread -lreadline -lSDL2 when compile with g++ with pthread)

#include <iostream>
#include <thread>
#include <SDL2/SDL.h>
#include <cstdlib>
extern "C" {
#include <readline/readline.h>
}

int main(int argc, char *argv[])
{
    SDL_Init(SDL_INIT_VIDEO);
    auto window = SDL_CreateWindow("title", 0, 0, 200, 200, SDL_WINDOW_SHOWN);

    std::thread console([](){
        while (true) {
            char *console_input_c_str = readline("> ");
            if (console_input_c_str == NULL)
                break;
            std::cout << "line: " << console_input_c_str << '\n';
            std::free(console_input_c_str);
        }
    });

    while (true) {
        SDL_Event event;
        SDL_WaitEvent(&event);
        std::cerr << "received event type "<<event.type<<'\n';
        if(event.type == SDL_WINDOWEVENT &&
                event.window.event == SDL_WINDOWEVENT_CLOSE)
            break;
    }

    SDL_DestroyWindow(window);
    SDL_Quit();
    console.join();
}

The main thread creates a window window with SDL2, enter a SDL event loop, while the thread console repeatedly read from the console using readline. When the window is exited, it waits for the console thread to finish then exit.

The program works fine; however, how can I make the console thread to stop when the window is exited?

It's fine if the program only use a single thread. It's also fine if exiting the console readline quits the program.


Exit readline is easy, but there is a problem with all the answers there - pthread_kill or reset -Q is not portable.

Terminating a thread is easy (using std::terminate or .detach()), but the console is left in a bad state because readline don't terminate normally. To reset the console it's possible to use reset -Q, but that's not portable.

Using readline's alternative (async) interface doesn't work because SDL don't listen for events on the console. Using select is also not portable.

Aucun commentaire:

Enregistrer un commentaire