[lvm-devel] [PATCH 3/4] locking: support stacking
Zdenek Kabelac
zkabelac at redhat.com
Mon Jul 8 15:19:15 UTC 2013
Support 2 levels of nesting signal blocking.
Signed-off-by: Zdenek Kabelac <zkabelac at redhat.com>
---
lib/locking/locking.c | 49 +++++++++++++++++++++++++------------------------
1 file changed, 25 insertions(+), 24 deletions(-)
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index 9183ee6..377d8a4 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -39,8 +39,11 @@ static int _blocking_supported = 0;
static volatile sig_atomic_t _sigint_caught = 0;
static volatile sig_atomic_t _handler_installed;
-static struct sigaction _oldhandler;
-static int _oldmasked;
+
+/* Support 2 level nesting, increase if needed more */
+#define MAX_SIGINTS 2
+static struct sigaction _oldhandler[MAX_SIGINTS];
+static int _oldmasked[MAX_SIGINTS];
typedef enum {
LV_NOOP,
@@ -84,50 +87,48 @@ void sigint_allow(void)
* Do not overwrite the backed-up handler data -
* just increase nesting count.
*/
- if (_handler_installed) {
- _handler_installed++;
+ if (++_handler_installed > MAX_SIGINTS)
return;
- }
/* Grab old sigaction for SIGINT: shall not fail. */
- sigaction(SIGINT, NULL, &handler);
+ if (sigaction(SIGINT, NULL, &handler))
+ log_sys_error("sigaction", "SIGINT");
handler.sa_flags &= ~SA_RESTART; /* Clear restart flag */
handler.sa_handler = _catch_sigint;
- _handler_installed = 1;
-
/* Override the signal handler: shall not fail. */
- sigaction(SIGINT, &handler, &_oldhandler);
+ if (sigaction(SIGINT, &handler, &_oldhandler[_handler_installed - 1]))
+ log_sys_error("sigaction", "SIGINT");
/* Unmask SIGINT. Remember to mask it again on restore. */
- sigprocmask(0, NULL, &sigs);
- if ((_oldmasked = sigismember(&sigs, SIGINT))) {
+ if (sigprocmask(0, NULL, &sigs))
+ log_sys_error("sigprocmask", "");
+
+ if ((_oldmasked[_handler_installed] = sigismember(&sigs, SIGINT))) {
sigdelset(&sigs, SIGINT);
- sigprocmask(SIG_SETMASK, &sigs, NULL);
+ if (sigprocmask(SIG_SETMASK, &sigs, NULL))
+ log_sys_error("sigprocmask", "SIG_SETMASK");
}
}
void sigint_restore(void)
{
- if (!_handler_installed)
- return;
+ sigset_t sigs;
- if (_handler_installed > 1) {
- _handler_installed--;
+ if (!_handler_installed ||
+ _handler_installed-- > MAX_SIGINTS)
return;
- }
-
- /* Nesting count went down to 0. */
- _handler_installed = 0;
- if (_oldmasked) {
- sigset_t sigs;
+ /* Nesting count went bellow 2. */
+ if (_oldmasked[_handler_installed]) {
sigprocmask(0, NULL, &sigs);
sigaddset(&sigs, SIGINT);
- sigprocmask(SIG_SETMASK, &sigs, NULL);
+ if (sigprocmask(SIG_SETMASK, &sigs, NULL))
+ log_sys_error("sigprocmask", "SIG_SETMASK");
}
- sigaction(SIGINT, &_oldhandler, NULL);
+ if (sigaction(SIGINT, &_oldhandler[_handler_installed], NULL))
+ log_sys_error("sigaction", "SIGINT restore");
}
static void _block_signals(uint32_t flags __attribute__((unused)))
--
1.8.3.1
More information about the lvm-devel
mailing list