diff --git a/client/snapclient.cpp b/client/snapclient.cpp index ecf0a369..68e1b677 100644 --- a/client/snapclient.cpp +++ b/client/snapclient.cpp @@ -16,6 +16,7 @@ along with this program. If not, see . ***/ +#include #include #include @@ -39,7 +40,7 @@ using namespace std; using namespace popl; -volatile sig_atomic_t g_terminated = false; +using namespace std::chrono_literals; PcmDevice getPcmDevice(const std::string& soundcard) { @@ -172,11 +173,6 @@ int main(int argc, char** argv) AixLog::Log::instance().add_logsink(AixLog::Severity::info, AixLog::Type::all, "%Y-%m-%d %H-%M-%S [#severity]"); } - - signal(SIGHUP, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); - #ifdef HAS_DAEMON std::unique_ptr daemon; if (daemonOption->is_set()) @@ -218,13 +214,24 @@ int main(int argc, char** argv) } #endif + auto signal_handler = install_signal_handler({SIGHUP, SIGTERM, SIGINT}); + bool active = true; if (host.empty()) { #if defined(HAS_AVAHI) || defined(HAS_BONJOUR) BrowseZeroConf browser; mDNSResult avahiResult; - while (!g_terminated) + while (true) { + auto status = signal_handler.wait_for(500ms); + if (status == future_status::ready) + { + active = false; + int sig = signal_handler.get(); + SLOG(INFO) << "Received signal " << sig << ": " << strsignal(sig) << "\n"; + break; + } + cerr << "valid: " << signal_handler.valid() << ", status: " << (int)status << "\n"; try { if (browser.browse("_snapcast._tcp", avahiResult, 5000)) @@ -241,24 +248,25 @@ int main(int argc, char** argv) { SLOG(ERROR) << "Exception: " << e.what() << std::endl; } - chronos::sleep(500); } #endif } - // Setup metadata handling - std::shared_ptr meta; - meta.reset(new MetadataAdapter); - if (metaStderr) - meta.reset(new MetaStderrAdapter); - - std::unique_ptr controller(new Controller(hostIdValue->value(), instance, meta)); - if (!g_terminated) + if (active) { + // Setup metadata handling + std::shared_ptr meta; + meta.reset(new MetadataAdapter); + if (metaStderr) + meta.reset(new MetaStderrAdapter); + + std::unique_ptr controller(new Controller(hostIdValue->value(), instance, meta)); LOG(INFO) << "Latency: " << latency << "\n"; controller->start(pcmDevice, host, port, latency); - while (!g_terminated) - chronos::sleep(100); + signal_handler.wait(); + int sig = signal_handler.get(); + SLOG(INFO) << "Received signal " << sig << ": " << strsignal(sig) << "\n"; + controller->stop(); } } diff --git a/common/signal_handler.hpp b/common/signal_handler.hpp index 81031c8c..55d69d67 100644 --- a/common/signal_handler.hpp +++ b/common/signal_handler.hpp @@ -16,34 +16,27 @@ along with this program. If not, see . ***/ -#ifndef SIGNAL_HANDLER_H -#define SIGNAL_HANDLER_H +#ifndef SIGNAL_HANDLER_HPP +#define SIGNAL_HANDLER_HPP +#include +#include #include -#include -extern volatile sig_atomic_t g_terminated; -void signal_handler(int sig) +static std::future install_signal_handler(std::set signals) { + static std::promise promise; + std::future future = promise.get_future(); - switch (sig) + for (auto signal : signals) { - case SIGHUP: - syslog(LOG_WARNING, "Received SIGHUP signal."); - break; - case SIGTERM: - syslog(LOG_WARNING, "Received SIGTERM signal."); - g_terminated = true; - break; - case SIGINT: - syslog(LOG_WARNING, "Received SIGINT signal."); - g_terminated = true; - break; - default: - syslog(LOG_WARNING, "Unhandled signal "); - break; + ::signal(signal, [](int sig) { + std::cerr << "signal: " << sig << "\n"; + promise.set_value(sig); + }); } + return future; } #endif diff --git a/server/snapserver.cpp b/server/snapserver.cpp index 5898a887..2fc0788c 100644 --- a/server/snapserver.cpp +++ b/server/snapserver.cpp @@ -40,9 +40,6 @@ #include "config.h" -volatile sig_atomic_t g_terminated = false; -std::condition_variable terminateSignaled; - using namespace std; using namespace popl; @@ -201,10 +198,6 @@ int main(int argc, char* argv[]) settings.stream.pcmStreams.push_back(streamValue->value(n)); } - signal(SIGHUP, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); - #ifdef HAS_DAEMON std::unique_ptr daemon; if (daemonOption->is_set()) @@ -270,9 +263,8 @@ int main(int argc, char* argv[]) std::thread t([&] { io_context.run(); }); - while (!g_terminated) - chronos::sleep(100); - + auto sig = install_signal_handler({SIGHUP, SIGTERM, SIGINT}).get(); + SLOG(INFO) << "Received signal " << sig << ": " << strsignal(sig) << "\n"; io_context.stop(); t.join();