mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-20 04:26:16 +02:00
fix signal-unsafe call inside of a signal
This commit is contained in:
parent
f045602915
commit
1690f5ccc1
3 changed files with 41 additions and 48 deletions
|
@ -16,6 +16,7 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace popl;
|
using namespace popl;
|
||||||
|
|
||||||
volatile sig_atomic_t g_terminated = false;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
PcmDevice getPcmDevice(const std::string& soundcard)
|
PcmDevice getPcmDevice(const std::string& soundcard)
|
||||||
{
|
{
|
||||||
|
@ -172,11 +173,6 @@ int main(int argc, char** argv)
|
||||||
AixLog::Log::instance().add_logsink<AixLog::SinkCout>(AixLog::Severity::info, AixLog::Type::all, "%Y-%m-%d %H-%M-%S [#severity]");
|
AixLog::Log::instance().add_logsink<AixLog::SinkCout>(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
|
#ifdef HAS_DAEMON
|
||||||
std::unique_ptr<Daemon> daemon;
|
std::unique_ptr<Daemon> daemon;
|
||||||
if (daemonOption->is_set())
|
if (daemonOption->is_set())
|
||||||
|
@ -218,13 +214,24 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
auto signal_handler = install_signal_handler({SIGHUP, SIGTERM, SIGINT});
|
||||||
|
bool active = true;
|
||||||
if (host.empty())
|
if (host.empty())
|
||||||
{
|
{
|
||||||
#if defined(HAS_AVAHI) || defined(HAS_BONJOUR)
|
#if defined(HAS_AVAHI) || defined(HAS_BONJOUR)
|
||||||
BrowseZeroConf browser;
|
BrowseZeroConf browser;
|
||||||
mDNSResult avahiResult;
|
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
|
try
|
||||||
{
|
{
|
||||||
if (browser.browse("_snapcast._tcp", avahiResult, 5000))
|
if (browser.browse("_snapcast._tcp", avahiResult, 5000))
|
||||||
|
@ -241,24 +248,25 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
SLOG(ERROR) << "Exception: " << e.what() << std::endl;
|
SLOG(ERROR) << "Exception: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
chronos::sleep(500);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup metadata handling
|
if (active)
|
||||||
std::shared_ptr<MetadataAdapter> meta;
|
|
||||||
meta.reset(new MetadataAdapter);
|
|
||||||
if (metaStderr)
|
|
||||||
meta.reset(new MetaStderrAdapter);
|
|
||||||
|
|
||||||
std::unique_ptr<Controller> controller(new Controller(hostIdValue->value(), instance, meta));
|
|
||||||
if (!g_terminated)
|
|
||||||
{
|
{
|
||||||
|
// Setup metadata handling
|
||||||
|
std::shared_ptr<MetadataAdapter> meta;
|
||||||
|
meta.reset(new MetadataAdapter);
|
||||||
|
if (metaStderr)
|
||||||
|
meta.reset(new MetaStderrAdapter);
|
||||||
|
|
||||||
|
std::unique_ptr<Controller> controller(new Controller(hostIdValue->value(), instance, meta));
|
||||||
LOG(INFO) << "Latency: " << latency << "\n";
|
LOG(INFO) << "Latency: " << latency << "\n";
|
||||||
controller->start(pcmDevice, host, port, latency);
|
controller->start(pcmDevice, host, port, latency);
|
||||||
while (!g_terminated)
|
signal_handler.wait();
|
||||||
chronos::sleep(100);
|
int sig = signal_handler.get();
|
||||||
|
SLOG(INFO) << "Received signal " << sig << ": " << strsignal(sig) << "\n";
|
||||||
|
|
||||||
controller->stop();
|
controller->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,34 +16,27 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#ifndef SIGNAL_HANDLER_H
|
#ifndef SIGNAL_HANDLER_HPP
|
||||||
#define SIGNAL_HANDLER_H
|
#define SIGNAL_HANDLER_HPP
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <set>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
extern volatile sig_atomic_t g_terminated;
|
|
||||||
|
|
||||||
void signal_handler(int sig)
|
static std::future<int> install_signal_handler(std::set<int> signals)
|
||||||
{
|
{
|
||||||
|
static std::promise<int> promise;
|
||||||
|
std::future<int> future = promise.get_future();
|
||||||
|
|
||||||
switch (sig)
|
for (auto signal : signals)
|
||||||
{
|
{
|
||||||
case SIGHUP:
|
::signal(signal, [](int sig) {
|
||||||
syslog(LOG_WARNING, "Received SIGHUP signal.");
|
std::cerr << "signal: " << sig << "\n";
|
||||||
break;
|
promise.set_value(sig);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -40,9 +40,6 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
volatile sig_atomic_t g_terminated = false;
|
|
||||||
std::condition_variable terminateSignaled;
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace popl;
|
using namespace popl;
|
||||||
|
|
||||||
|
@ -201,10 +198,6 @@ int main(int argc, char* argv[])
|
||||||
settings.stream.pcmStreams.push_back(streamValue->value(n));
|
settings.stream.pcmStreams.push_back(streamValue->value(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGHUP, signal_handler);
|
|
||||||
signal(SIGTERM, signal_handler);
|
|
||||||
signal(SIGINT, signal_handler);
|
|
||||||
|
|
||||||
#ifdef HAS_DAEMON
|
#ifdef HAS_DAEMON
|
||||||
std::unique_ptr<Daemon> daemon;
|
std::unique_ptr<Daemon> daemon;
|
||||||
if (daemonOption->is_set())
|
if (daemonOption->is_set())
|
||||||
|
@ -270,9 +263,8 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
std::thread t([&] { io_context.run(); });
|
std::thread t([&] { io_context.run(); });
|
||||||
|
|
||||||
while (!g_terminated)
|
auto sig = install_signal_handler({SIGHUP, SIGTERM, SIGINT}).get();
|
||||||
chronos::sleep(100);
|
SLOG(INFO) << "Received signal " << sig << ": " << strsignal(sig) << "\n";
|
||||||
|
|
||||||
io_context.stop();
|
io_context.stop();
|
||||||
t.join();
|
t.join();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue