2015-03-23 9 views
0

Я реализовал крошечный веб-сервер в отдельном потоке, используя красивую библиотеку libevent. Веб-сервер запускает event_base_dispatch() для обработки всех событий. Мне нужен способ вырвать этот цикл отправки из основного потока.Как разбить цикл отправки libevent

Она сводится к следующему C++ код:

#include <stdlib.h> 
#include <signal.h> 
#include <thread> 
#include <evhttp.h> 

struct event_base *eb; 
std::thread t; 

static volatile sig_atomic_t bailout = false; 

void my_signal_handler(int) { 
    bailout = true; 
} 

void onRequest(evhttp_request *req, void *) { 
    struct evbuffer *OutBuf = evhttp_request_get_output_buffer(req); 
    evbuffer_add_printf(OutBuf, "<html><body>Testing 1-2-3</body></html>"); 
    evhttp_send_reply(req, HTTP_OK, "OK", OutBuf); 
} 

void dispatch() { 
    eb = event_base_new(); 
    struct evhttp *http = evhttp_new(eb); 
    evhttp_set_gencb(http, &onRequest, NULL); 
    evhttp_bind_socket_with_handle(http, "0.0.0.0", 5555); 
    event_base_dispatch(eb); 
} 

int main() { 

    struct sigaction sigIntHandler; 
    sigIntHandler.sa_handler = my_signal_handler; 
    sigemptyset(&sigIntHandler.sa_mask); 
    sigIntHandler.sa_flags = 0; 
    sigaction(SIGINT, &sigIntHandler, NULL); 

    t = std::thread { &dispatch }; 

    while (! bailout) { 
     std::this_thread::sleep_for(std::chrono::seconds(1)); 
    } 

    event_base_loopexit(eb, NULL); 

    t.join(); 
} 

поведение является то, что если вы запустите программу, запросить страницу, прервать программу по Ctrl-C, то event_base_dispatch() не продолжает работать до вы получаете другую веб-страницу. Только тогда цикл прерывается, и программа завершается.

ответ

0

В конце концов я внедрено вспыхиваю из цикла диспетчеризации, добавив таймер, который в основном опросы катапультирования переменная:

struct event *ev; 
const struct timeval one_sec = { 1, 0 }; // sec, usec 

void cb_timer_func(evutil_socket_t, short, void) { 

    if (bailout) { 
    event_base_loopbreak(eb); 
    } 
    else if (! evtimer_pending(ev, NULL)) { 
    evtimer_del(ev); 
    evtimer_add(ev, &one_sec); 
    } 
} 

И в цикл диспетчеризации, я добавил:

ev = evtimer_new(eb, cb_timer_func); 
evtimer_add(ev, &one_sec); 
0

Еще один подход - поставить event_base_loopbreak() в обработчик сигналов.

 Смежные вопросы

  • Нет связанных вопросов^_^