Стандартный способ полного завершения работы с помощью Boost.Asio

Я пишу кроссплатформенную серверную программу на C ++ с использованием Boost.Asio. Следуя примеру HTTP-сервера на этой странице, я хотел бы обрабатывать запрос на завершение работы пользователя без использования API, зависящих от реализации. Я' Сначала мы пытались использовать стандартную библиотеку сигналов C, но не смогли найти шаблон проектирования, подходящий для Asio. Пример Windows , кажется, похож на ближайшую библиотеку сигналов, но есть состояние гонки, при котором обработчик ctrl консоли может быть вызван после того, как объект сервера был уничтожен. Я пытаюсь избежать неопределенного поведения, как указано в стандарте C ++.

Есть ли стандартный (и правильный) способ остановки сервера?

Чтобы проиллюстрировать проблемы с использованием библиотеки сигналов C:

#include 
#include 
#include 

using std::signal;
using boost::asio::io_service;

namespace
{
    std::function sighandler;
}

extern "C"
{
    static void handle_signal(int);
}

void handle_signal(int)
{
    // error - undefined behavior
    sighandler();
}

int main()
{
    io_service s;
    sighandler = std::bind(&io_service::stop, &s);
    auto old_sigint = signal(SIGINT, &handle_signal);
    if (old_sigint == SIG_IGN)
        // race condition?  raise SIGINT before I can set ignore back
        signal(SIGINT, SIG_IGN);
    auto old_sigterm = signal(SIGTERM, &handle_signal);
    if (old_sigterm == SIG_IGN)
        // race condition?  raise SIGTERM before I can set ignore back
        signal(SIGTERM, SIG_IGN);
    s.run();
    // reset signals so I can clear reference to io_service
    if (old_sigterm != SIG_IGN)
        signal(SIGTERM, SIG_DFL);
    if (old_sigint != SIG_IGN)
        signal(SIGINT, SIG_DFL);
    // clear reference to io_service, but can I be sure that handle_signal
    // isn't being executed?
    sighandler = nullptr;
    // io_service is destroyed
}

14
задан Deanie 31 May 2016 в 18:04
поделиться