summaryrefslogtreecommitdiff
path: root/src/syncevo/SuspendFlags.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/syncevo/SuspendFlags.cpp')
-rw-r--r--src/syncevo/SuspendFlags.cpp79
1 files changed, 53 insertions, 26 deletions
diff --git a/src/syncevo/SuspendFlags.cpp b/src/syncevo/SuspendFlags.cpp
index b47a8524..0f46bc49 100644
--- a/src/syncevo/SuspendFlags.cpp
+++ b/src/syncevo/SuspendFlags.cpp
@@ -36,9 +36,11 @@ SE_BEGIN_CXX
SuspendFlags::SuspendFlags() :
m_level(Logger::INFO),
m_state(NORMAL),
+ m_receivedSignals(0),
m_lastSuspend(0),
m_senderFD(-1),
- m_receiverFD(-1)
+ m_receiverFD(-1),
+ m_activeSignals(0)
{
}
@@ -148,10 +150,14 @@ boost::shared_ptr<SuspendFlags::StateBlocker> SuspendFlags::block(boost::weak_pt
return res;
}
-boost::shared_ptr<SuspendFlags::Guard> SuspendFlags::activate()
+boost::shared_ptr<SuspendFlags::Guard> SuspendFlags::activate(uint32_t sigmask)
{
SE_LOG_DEBUG(NULL, "SuspendFlags: (re)activating, currently %s",
m_senderFD > 0 ? "active" : "inactive");
+ if (m_senderFD > 0) {
+ return m_guard.lock();
+ }
+
int fds[2];
if (pipe(fds)) {
SE_THROW(StringPrintf("allocating pipe for signals failed: %s", strerror(errno)));
@@ -163,8 +169,11 @@ boost::shared_ptr<SuspendFlags::Guard> SuspendFlags::activate()
m_receiverFD = fds[0];
SE_LOG_DEBUG(NULL, "SuspendFlags: activating signal handler(s) with fds %d->%d",
m_senderFD, m_receiverFD);
- sigaction(SIGINT, NULL, &m_oldSigInt);
- sigaction(SIGTERM, NULL, &m_oldSigTerm);
+ for (int sig = 0; sig < 32; sig++) {
+ if (sigmask & (1<<sig)) {
+ sigaction(sig, NULL, m_oldSignalHandlers + sig);
+ }
+ }
struct sigaction new_action;
memset(&new_action, 0, sizeof(new_action));
@@ -173,22 +182,27 @@ boost::shared_ptr<SuspendFlags::Guard> SuspendFlags::activate()
// don't let processing of SIGINT be interrupted
// of SIGTERM and vice versa, if we are doing the
// handling
- if (m_oldSigInt.sa_handler == SIG_DFL) {
- sigaddset(&new_action.sa_mask, SIGINT);
- }
- if (m_oldSigTerm.sa_handler == SIG_DFL) {
- sigaddset(&new_action.sa_mask, SIGTERM);
- }
- if (m_oldSigInt.sa_handler == SIG_DFL) {
- sigaction(SIGINT, &new_action, NULL);
- SE_LOG_DEBUG(NULL, "SuspendFlags: catch SIGINT");
+ for (int sig = 0; sig < 32; sig++) {
+ if (sigmask & (1<<sig)) {
+ if (m_oldSignalHandlers[sig].sa_handler == SIG_DFL) {
+ sigaddset(&new_action.sa_mask, sig);
+ }
+ }
}
- if (m_oldSigTerm.sa_handler == SIG_DFL) {
- sigaction(SIGTERM, &new_action, NULL);
- SE_LOG_DEBUG(NULL, "SuspendFlags: catch SIGTERM");
+
+ for (int sig = 0; sig < 32; sig++) {
+ if (sigmask & (1<<sig)) {
+ if (m_oldSignalHandlers[sig].sa_handler == SIG_DFL) {
+ sigaction(sig, &new_action, NULL);
+ SE_LOG_DEBUG(NULL, "SuspendFlags: catch signal %d", sig);
+ }
+ }
}
+ m_activeSignals = sigmask;
+ boost::shared_ptr<Guard> guard(new GLibGuard(m_receiverFD));
+ m_guard = guard;
- return boost::shared_ptr<Guard>(new GLibGuard(m_receiverFD));
+ return guard;
}
void SuspendFlags::deactivate()
@@ -196,14 +210,19 @@ void SuspendFlags::deactivate()
SE_LOG_DEBUG(NULL, "SuspendFlags: deactivating fds %d->%d",
m_senderFD, m_receiverFD);
if (m_receiverFD >= 0) {
- sigaction(SIGTERM, &m_oldSigTerm, NULL);
- sigaction(SIGINT, &m_oldSigInt, NULL);
+ for (int sig = 0; sig < 32; sig++) {
+ if (m_activeSignals & (1<<sig)) {
+ sigaction(sig, m_oldSignalHandlers + sig, NULL);
+ }
+ }
+ m_activeSignals = 0;
SE_LOG_DEBUG(NULL, "SuspendFlags: close m_receiverFD %d", m_receiverFD);
close(m_receiverFD);
SE_LOG_DEBUG(NULL, "SuspendFlags: close m_senderFD %d", m_senderFD);
close(m_senderFD);
m_receiverFD = -1;
m_senderFD = -1;
+ m_guard.reset();
SE_LOG_DEBUG(NULL, "SuspendFlags: done with deactivation");
}
}
@@ -245,19 +264,24 @@ void SuspendFlags::handleSignal(int sig)
msg = SUSPEND_AGAIN;
}
break;
- case SuspendFlags::ABORT:
+ case ABORT:
msg = ABORT_AGAIN;
break;
- case SuspendFlags::ABORT_AGAIN:
- case SuspendFlags::SUSPEND_AGAIN:
+ case ABORT_AGAIN:
+ case SUSPEND_AGAIN:
+ case ABORT_MAX:
// shouldn't happen
+ msg = ABORT_MAX;
break;
}
+ default:
+ msg = ABORT_MAX;
break;
}
}
if (me.m_senderFD >= 0) {
- write(me.m_senderFD, &msg, 1);
+ unsigned char msg2[2] = { (unsigned char)(ABORT_MAX + sig), msg };
+ write(me.m_senderFD, msg2, msg == ABORT_MAX ? 1 : 2);
}
}
@@ -282,10 +306,13 @@ void SuspendFlags::printSignals()
case ABORT_AGAIN:
str = "Already aborting as requested earlier ...";
break;
+ default: {
+ int sig = msg - ABORT_MAX;
+ SE_LOG_DEBUG(NULL, "reveived signal %d", sig);
+ m_receivedSignals |= 1<<sig;
}
- if (!str) {
- SE_LOG_DEBUG(NULL, "internal error: received invalid signal msg %d", msg);
- } else {
+ }
+ if (str) {
SE_LOG(NULL, m_level, "%s", str);
}
m_stateChanged(*this);