Многопоточный http-сервер libevent: невозможно успешно ответить evhttp_request в подпотоках - PullRequest
0 голосов
/ 11 сентября 2018

Проблема в том, что клиент не может получить ответ http с ответом «evhttp_send_reply» в подпотоке на стороне сервера.

Я пробовал модель для настройки многопоточного http-сервера с libevent evhttp, ниже приведены коды, выполняющиеся в основном потоке:

    struct event_base *mpEventBase = event_base_new();
    struct evhttp *pHttp = evhttp_new(mpEventBase);
    evhttp_bind_socket(pHttp, "0.0.0.0", port);
    evhttp_set_gencb(pHttp, HttpGenericCallback, (void *)this);
    event_base_dispatch(mpEventBase);

Затем http-сервер настраивается и начинает принимать соединения от клиента. Но для общей ситуации с обработкой долго выполняющегося кода я пересылаю все запросы http во вспомогательный поток и отправляю ответ http также во вспомогательном потоке.

    void HttpGenericCallback(struct evhttp_request *pRequest, void* arg) {
        Class *thiz = (Class *)arg;
        // run in sub thread in thread pool
        thiz->mpThreadPool->Run([thiz](struct evhttp_request *pReq){
            struct evbuffer* pEvbuf = evbuffer_new();
            if (!pEvbuf) {
                std::cout << "create evbuffer failed!\n";
                return ;
            }

            const char *pUrl = evhttp_request_get_uri(pRequest);
            evbuffer_add_printf(pEvbuf, "Server response. Your request url is %s", pUrl);
            evhttp_send_reply(pRequest, HTTP_OK, "OK", pEvbuf);
            evbuffer_free(pEvbuf);
        }, pRequest);
    }

НО, я обнаружил, что после "evhttp_send_reply" клиент НЕ получил никакого ответа. Я не уверен, какой шаг не так? Кроме того, если я переместлю код, работающий в подпотоке, в HttpGenericCallback, он будет работать!

Любой совет с благодарностью!

1 Ответ

0 голосов
/ 18 октября 2018

Ваш HttpGenericCallback вызван, и вы передаете struct evhttp_request* своей ветке. HttpGenericCallback завершается и, вероятно, уничтожает ваш struct evhttp_request*, в то время как ваш поток продолжает работать с уже недействительным указателем.

...