harmonize signal handling

This commit is contained in:
Michael Davidsaver
2020-02-21 00:29:32 -08:00
parent 1edeab8a39
commit af973bea66
6 changed files with 103 additions and 69 deletions
+7 -43
View File
@@ -4,12 +4,6 @@
* in file LICENSE that is included with this distribution.
*/
#if defined(_WIN32)
# include <windows.h>
#elif !defined(__rtems__) && !defined(vxWorks)
# include <sys/types.h>
# include <unistd.h>
#endif
#include <list>
#include <map>
@@ -177,52 +171,22 @@ Server& Server::stop()
return *this;
}
static std::atomic<Server::Pvt*> sig_target{nullptr};
static void sig_handle(int sig)
{
auto serv = sig_target.load();
if(serv)
serv->done.signal();
}
Server& Server::run()
{
if(!pvt)
throw std::logic_error("NULL Server");
Server::Pvt* expect = nullptr;
pvt->start();
std::function<void()> cleanup;
if(sig_target.compare_exchange_weak(expect, pvt.get())) {
// we claimed the signal handler slot.
// save previous handlers
auto prevINT = signal(SIGINT , &sig_handle);
auto prevTERM = signal(SIGTERM, &sig_handle);
cleanup = [this, prevINT, prevTERM]() {
Server::Pvt* expect = pvt.get();
if(sig_target.compare_exchange_weak(expect, nullptr)) {
signal(SIGINT , prevINT);
signal(SIGTERM, prevTERM);
}
};
}
try {
pvt->start();
{
SigInt handler([this](){
pvt->done.signal();
});
pvt->done.wait();
pvt->stop();
} catch(...) {
if(cleanup)
cleanup();
throw;
}
if(cleanup)
cleanup();
pvt->stop();
return *this;
}