de manière standard pour effectuer un arrêt propre à Stimuler.Asio

Je suis en train d'écrire une croix-plate-forme de serveur programme en C++ à l'aide de coup de pouce.Asio. Suivant le Serveur HTTP exemple sur cette page, j'aimerais gérer un utilisateur demande de résiliation sans l'aide de la mise en œuvre des Api spécifiques. J'ai d'abord tenté d'utiliser la norme C signal de la bibliothèque, mais ont été incapables de trouver un modèle approprié pour l'Asio. Le Windows exemple de l' conception semble ressembler le signal de la bibliothèque la plus proche, mais il y a une situation de concurrence où la console ctrl gestionnaire pourrait être appelée après que le serveur de l'objet a été détruit. J'essaie d'éviter un comportement indéfini, comme spécifié par la norme C++.

Est-il une norme (et corriger) de manière à arrêter le serveur?

Pour illustrer les problèmes avec l'aide de la C signal de la bibliothèque:

#include <csignal>
#include <functional>
#include <boost/asio.hpp>

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

namespace
{
    std::function<void ()> 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
}
demandez-vous comment faire pour installer un gestionnaire de signal d'un signal comme SIGINT? Ou, quoi faire à ce gestionnaire de signal à l'arrêt de votre serveur HTTP?
ajout d'un csignal exemple de conception d'un
vous ne pouvez pas invoquer en toute sécurité io_service::stop à partir de votre gestionnaire de signal, même si elle est enveloppée dans un boost::function. Cette opération aboutit à un comportement indéfini. Regardez ma réponse pour obtenir une liste des fonctions que vous pouvez appeler à partir de l'intérieur d'un gestionnaire de signal.
J'ai utilisé votre question c++0x depuis on dirait que vous êtes à l'aide de la auto mot-clé.
ajout de commentaires pour montrer que l'UB, merci

OriginalL'auteur Timothy003 | 2011-01-09