[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/5] sort: use pthread_sigmask, not sigprocmask
From: |
Paul Eggert |
Subject: |
[PATCH 4/5] sort: use pthread_sigmask, not sigprocmask |
Date: |
Thu, 17 Aug 2017 12:04:55 -0700 |
POSIX says sigprocmask has unspecified behavior in a multithreaded
program like ‘sort’.
* src/sort.c (pthread_sigmask) [GNULIB_defined_pthread_functions]:
New macro, for use when ‘sort’ is not multithreaded.
(cs_enter, cs_leave): Use it. Pass address, not value, as
this is typically a tad faster. All callers changed.
---
src/sort.c | 37 +++++++++++++++++++++----------------
1 file changed, 21 insertions(+), 16 deletions(-)
diff --git a/src/sort.c b/src/sort.c
index f52b0d3f7..ccdd2309e 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -83,6 +83,11 @@ struct rlimit { size_t rlim_cur; };
# endif
#endif
+#if GNULIB_defined_pthread_functions
+# undef pthread_sigmask
+# define pthread_sigmask(how, set, oset) sigprocmask (how, set, oset)
+#endif
+
#if !defined OPEN_MAX && defined NR_OPEN
# define OPEN_MAX NR_OPEN
#endif
@@ -638,22 +643,21 @@ struct cs_status
};
/* Enter a critical section. */
-static struct cs_status
-cs_enter (void)
+static void
+cs_enter (struct cs_status *status)
{
- struct cs_status status;
- status.valid = (sigprocmask (SIG_BLOCK, &caught_signals, &status.sigs) == 0);
- return status;
+ int ret = pthread_sigmask (SIG_BLOCK, &caught_signals, &status->sigs);
+ status->valid = ret == 0;
}
/* Leave a critical section. */
static void
-cs_leave (struct cs_status status)
+cs_leave (struct cs_status const *status)
{
- if (status.valid)
+ if (status->valid)
{
/* Ignore failure when restoring the signal mask. */
- sigprocmask (SIG_SETMASK, &status.sigs, NULL);
+ pthread_sigmask (SIG_SETMASK, &status->sigs, NULL);
}
}
@@ -832,9 +836,10 @@ exit_cleanup (void)
{
/* Clean up any remaining temporary files in a critical section so
that a signal handler does not try to clean them too. */
- struct cs_status cs = cs_enter ();
+ struct cs_status cs;
+ cs_enter (&cs);
cleanup ();
- cs_leave (cs);
+ cs_leave (&cs);
}
close_stdout ();
@@ -867,7 +872,7 @@ create_temp_file (int *pfd, bool survive_fd_exhaustion)
temp_dir_index = 0;
/* Create the temporary file in a critical section, to avoid races. */
- cs = cs_enter ();
+ cs_enter (&cs);
fd = mkostemp (file, O_CLOEXEC);
if (0 <= fd)
{
@@ -875,7 +880,7 @@ create_temp_file (int *pfd, bool survive_fd_exhaustion)
temptail = &node->next;
}
saved_errno = errno;
- cs_leave (cs);
+ cs_leave (&cs);
errno = saved_errno;
if (fd < 0)
@@ -1053,7 +1058,7 @@ pipe_fork (int pipefds[2], size_t tries)
{
/* This is so the child process won't delete our temp files
if it receives a signal before exec-ing. */
- cs = cs_enter ();
+ cs_enter (&cs);
saved_temphead = temphead;
temphead = NULL;
@@ -1062,7 +1067,7 @@ pipe_fork (int pipefds[2], size_t tries)
if (pid)
temphead = saved_temphead;
- cs_leave (cs);
+ cs_leave (&cs);
errno = saved_errno;
if (0 <= pid || errno != EAGAIN)
@@ -1247,11 +1252,11 @@ zaptemp (char const *name)
/* Unlink the temporary file in a critical section to avoid races. */
next = node->next;
- cs = cs_enter ();
+ cs_enter (&cs);
unlink_status = unlink (name);
unlink_errno = errno;
*pnode = next;
- cs_leave (cs);
+ cs_leave (&cs);
if (unlink_status != 0)
error (0, unlink_errno, _("warning: cannot remove: %s"), quotef (name));
--
2.13.5