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();