Merge pull request #27843 from yuwata/usleep_safe
time-util: introduce usleep_safe()
This commit is contained in:
+17
-23
@@ -33,12 +33,6 @@ static void set_alarm(usec_t usecs) {
|
||||
assert_se(setitimer(ITIMER_REAL, &v, NULL) >= 0);
|
||||
}
|
||||
|
||||
static void sleep_for(usec_t usecs) {
|
||||
/* stupid usleep() might fail if >1000000 */
|
||||
assert_se(usecs < USEC_PER_SEC);
|
||||
usleep(usecs);
|
||||
}
|
||||
|
||||
#define TEST_BARRIER(_FUNCTION, _CHILD_CODE, _WAIT_CHILD, _PARENT_CODE, _WAIT_PARENT) \
|
||||
TEST(_FUNCTION) { \
|
||||
Barrier b = BARRIER_NULL; \
|
||||
@@ -94,9 +88,9 @@ static void sleep_for(usec_t usecs) {
|
||||
/*
|
||||
* Test basic sync points
|
||||
* This places a barrier in both processes and waits synchronously for them.
|
||||
* The timeout makes sure the sync works as expected. The sleep_for() on one side
|
||||
* The timeout makes sure the sync works as expected. The usleep_safe() on one side
|
||||
* makes sure the exit of the parent does not overwrite previous barriers. Due
|
||||
* to the sleep_for(), we know that the parent already exited, thus there's a
|
||||
* to the usleep_safe(), we know that the parent already exited, thus there's a
|
||||
* pending HUP on the pipe. However, the barrier_sync() prefers reads on the
|
||||
* eventfd, thus we can safely wait on the barrier.
|
||||
*/
|
||||
@@ -104,7 +98,7 @@ TEST_BARRIER(barrier_sync,
|
||||
({
|
||||
set_alarm(BASE_TIME * 10);
|
||||
assert_se(barrier_place(&b));
|
||||
sleep_for(BASE_TIME * 2);
|
||||
usleep_safe(BASE_TIME * 2);
|
||||
assert_se(barrier_sync(&b));
|
||||
}),
|
||||
TEST_BARRIER_WAIT_SUCCESS(pid1),
|
||||
@@ -124,7 +118,7 @@ TEST_BARRIER(barrier_sync,
|
||||
*/
|
||||
TEST_BARRIER(barrier_wait_next,
|
||||
({
|
||||
sleep_for(BASE_TIME);
|
||||
usleep_safe(BASE_TIME);
|
||||
set_alarm(BASE_TIME * 10);
|
||||
assert_se(barrier_wait_next(&b));
|
||||
assert_se(barrier_place(&b));
|
||||
@@ -150,7 +144,7 @@ TEST_BARRIER(barrier_wait_next,
|
||||
*/
|
||||
TEST_BARRIER(barrier_wait_next_twice,
|
||||
({
|
||||
sleep_for(BASE_TIME);
|
||||
usleep_safe(BASE_TIME);
|
||||
set_alarm(BASE_TIME);
|
||||
assert_se(barrier_wait_next(&b));
|
||||
assert_se(barrier_wait_next(&b));
|
||||
@@ -161,7 +155,7 @@ TEST_BARRIER(barrier_wait_next_twice,
|
||||
set_alarm(BASE_TIME * 10);
|
||||
assert_se(barrier_place(&b));
|
||||
assert_se(barrier_place(&b));
|
||||
sleep_for(BASE_TIME * 4);
|
||||
usleep_safe(BASE_TIME * 4);
|
||||
}),
|
||||
TEST_BARRIER_WAIT_SUCCESS(pid2));
|
||||
|
||||
@@ -173,7 +167,7 @@ TEST_BARRIER(barrier_wait_next_twice,
|
||||
*/
|
||||
TEST_BARRIER(barrier_wait_next_twice_local,
|
||||
({
|
||||
sleep_for(BASE_TIME);
|
||||
usleep_safe(BASE_TIME);
|
||||
set_alarm(BASE_TIME);
|
||||
assert_se(barrier_wait_next(&b));
|
||||
assert_se(barrier_place(&b));
|
||||
@@ -186,7 +180,7 @@ TEST_BARRIER(barrier_wait_next_twice_local,
|
||||
set_alarm(BASE_TIME * 10);
|
||||
assert_se(barrier_place(&b));
|
||||
assert_se(barrier_place(&b));
|
||||
sleep_for(BASE_TIME * 4);
|
||||
usleep_safe(BASE_TIME * 4);
|
||||
}),
|
||||
TEST_BARRIER_WAIT_SUCCESS(pid2));
|
||||
|
||||
@@ -198,7 +192,7 @@ TEST_BARRIER(barrier_wait_next_twice_local,
|
||||
*/
|
||||
TEST_BARRIER(barrier_wait_next_twice_sync,
|
||||
({
|
||||
sleep_for(BASE_TIME);
|
||||
usleep_safe(BASE_TIME);
|
||||
set_alarm(BASE_TIME);
|
||||
assert_se(barrier_wait_next(&b));
|
||||
assert_se(barrier_sync_next(&b));
|
||||
@@ -219,7 +213,7 @@ TEST_BARRIER(barrier_wait_next_twice_sync,
|
||||
*/
|
||||
TEST_BARRIER(barrier_wait_next_twice_local_sync,
|
||||
({
|
||||
sleep_for(BASE_TIME);
|
||||
usleep_safe(BASE_TIME);
|
||||
set_alarm(BASE_TIME);
|
||||
assert_se(barrier_wait_next(&b));
|
||||
assert_se(barrier_place(&b));
|
||||
@@ -253,7 +247,7 @@ TEST_BARRIER(barrier_sync_next,
|
||||
TEST_BARRIER_WAIT_SUCCESS(pid1),
|
||||
({
|
||||
set_alarm(BASE_TIME * 10);
|
||||
sleep_for(BASE_TIME);
|
||||
usleep_safe(BASE_TIME);
|
||||
assert_se(barrier_place(&b));
|
||||
assert_se(barrier_place(&b));
|
||||
assert_se(barrier_sync(&b));
|
||||
@@ -274,7 +268,7 @@ TEST_BARRIER(barrier_sync_next_local,
|
||||
}),
|
||||
TEST_BARRIER_WAIT_ALARM(pid1),
|
||||
({
|
||||
sleep_for(BASE_TIME * 2);
|
||||
usleep_safe(BASE_TIME * 2);
|
||||
}),
|
||||
TEST_BARRIER_WAIT_SUCCESS(pid2));
|
||||
|
||||
@@ -323,7 +317,7 @@ TEST_BARRIER(barrier_wait_abortion_unmatched,
|
||||
}),
|
||||
TEST_BARRIER_WAIT_ALARM(pid1),
|
||||
({
|
||||
sleep_for(BASE_TIME * 2);
|
||||
usleep_safe(BASE_TIME * 2);
|
||||
}),
|
||||
TEST_BARRIER_WAIT_SUCCESS(pid2));
|
||||
|
||||
@@ -356,7 +350,7 @@ TEST_BARRIER(barrier_wait_abortion_local_unmatched,
|
||||
}),
|
||||
TEST_BARRIER_WAIT_ALARM(pid1),
|
||||
({
|
||||
sleep_for(BASE_TIME * 2);
|
||||
usleep_safe(BASE_TIME * 2);
|
||||
}),
|
||||
TEST_BARRIER_WAIT_SUCCESS(pid2));
|
||||
|
||||
@@ -379,12 +373,12 @@ TEST_BARRIER(barrier_exit,
|
||||
/*
|
||||
* Test child exit with sleep
|
||||
* Same as test_barrier_exit but verifies the test really works due to the
|
||||
* child-exit. We add a usleep() which triggers the alarm in the parent and
|
||||
* child-exit. We add a usleep_safe() which triggers the alarm in the parent and
|
||||
* causes the test to time out.
|
||||
*/
|
||||
TEST_BARRIER(barrier_no_exit,
|
||||
({
|
||||
sleep_for(BASE_TIME * 2);
|
||||
usleep_safe(BASE_TIME * 2);
|
||||
}),
|
||||
TEST_BARRIER_WAIT_SUCCESS(pid1),
|
||||
({
|
||||
@@ -407,7 +401,7 @@ TEST_BARRIER(barrier_no_exit,
|
||||
TEST_BARRIER(barrier_pending_exit,
|
||||
({
|
||||
set_alarm(BASE_TIME * 4);
|
||||
sleep_for(BASE_TIME * 2);
|
||||
usleep_safe(BASE_TIME * 2);
|
||||
assert_se(barrier_wait_next(&b));
|
||||
assert_se(barrier_sync_next(&b));
|
||||
assert_se(barrier_place(&b));
|
||||
|
||||
@@ -31,27 +31,27 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
sd_notify(0,
|
||||
"STATUS=Starting up");
|
||||
usleep(duration);
|
||||
usleep_safe(duration);
|
||||
|
||||
sd_notify(0,
|
||||
"STATUS=Running\n"
|
||||
"READY=1");
|
||||
usleep(duration);
|
||||
usleep_safe(duration);
|
||||
|
||||
sd_notify(0,
|
||||
"STATUS=Reloading\n"
|
||||
"RELOADING=1");
|
||||
usleep(duration);
|
||||
usleep_safe(duration);
|
||||
|
||||
sd_notify(0,
|
||||
"STATUS=Running\n"
|
||||
"READY=1");
|
||||
usleep(duration);
|
||||
usleep_safe(duration);
|
||||
|
||||
sd_notify(0,
|
||||
"STATUS=Quitting\n"
|
||||
"STOPPING=1");
|
||||
usleep(duration);
|
||||
usleep_safe(duration);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -740,7 +740,7 @@ TEST(xopenat_lock) {
|
||||
* little and assume that's enough time for the child process to get along far enough. It doesn't
|
||||
* matter if it doesn't get far enough, in that case we just won't trigger the fallback logic in
|
||||
* xopenat_lock(), but the test will still succeed. */
|
||||
assert_se(usleep(20 * USEC_PER_MSEC) >= 0);
|
||||
assert_se(usleep_safe(20 * USEC_PER_MSEC) >= 0);
|
||||
|
||||
assert_se(unlinkat(tfd, "abc", AT_REMOVEDIR) >= 0);
|
||||
fd = safe_close(fd);
|
||||
|
||||
@@ -30,11 +30,11 @@ static void *fake_pressure_thread(void *p) {
|
||||
_cleanup_free_ struct fake_pressure_context *c = ASSERT_PTR(p);
|
||||
_cleanup_close_ int cfd = -EBADF;
|
||||
|
||||
usleep(150);
|
||||
usleep_safe(150);
|
||||
|
||||
assert_se(write(c->fifo_fd, &(const char) { 'x' }, 1) == 1);
|
||||
|
||||
usleep(150);
|
||||
usleep_safe(150);
|
||||
|
||||
cfd = accept4(c->socket_fd, NULL, NULL, SOCK_CLOEXEC);
|
||||
assert_se(cfd >= 0);
|
||||
@@ -164,7 +164,7 @@ _noreturn_ static void real_pressure_eat_memory(int pipe_fd) {
|
||||
|
||||
log_info("Ate %s in total.", FORMAT_BYTES(ate));
|
||||
|
||||
usleep(50 * USEC_PER_MSEC);
|
||||
usleep_safe(50 * USEC_PER_MSEC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -638,7 +638,7 @@ TEST(safe_fork) {
|
||||
|
||||
if (r == 0) {
|
||||
/* child */
|
||||
usleep(100 * USEC_PER_MSEC);
|
||||
usleep_safe(100 * USEC_PER_MSEC);
|
||||
|
||||
_exit(88);
|
||||
}
|
||||
|
||||
+20
-2
@@ -3,8 +3,9 @@
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
#include <float.h>
|
||||
@@ -28,6 +29,18 @@ DISABLE_WARNING_TYPE_LIMITS;
|
||||
(t)-1 < (t)0 ? ", signed" : ", unsigned", \
|
||||
alignof(t))
|
||||
|
||||
#define check_no_sign(t, size) \
|
||||
do { \
|
||||
info_no_sign(t); \
|
||||
assert_se(sizeof(t) == size); \
|
||||
} while (false)
|
||||
|
||||
#define check(t, size) \
|
||||
do { \
|
||||
info(t); \
|
||||
assert_se(sizeof(t) == size); \
|
||||
} while (false)
|
||||
|
||||
enum Enum {
|
||||
enum_value,
|
||||
};
|
||||
@@ -44,6 +57,12 @@ enum BigEnum2 {
|
||||
int main(void) {
|
||||
int (*function_pointer)(void);
|
||||
|
||||
check_no_sign(dev_t, SIZEOF_DEV_T);
|
||||
check_no_sign(ino_t, SIZEOF_INO_T);
|
||||
check_no_sign(rlim_t, SIZEOF_RLIM_T);
|
||||
check(time_t, SIZEOF_TIME_T);
|
||||
check(typeof(((struct timex *)0)->freq), SIZEOF_TIMEX_MEMBER);
|
||||
|
||||
info_no_sign(typeof(function_pointer));
|
||||
info_no_sign(void*);
|
||||
info(char*);
|
||||
@@ -76,7 +95,6 @@ int main(void) {
|
||||
|
||||
info(size_t);
|
||||
info(ssize_t);
|
||||
info(time_t);
|
||||
info(usec_t);
|
||||
#ifdef __GLIBC__
|
||||
info(__time_t);
|
||||
|
||||
@@ -29,7 +29,7 @@ int main(int argc, char *argv[]) {
|
||||
for (i = 0; i < count; i++) {
|
||||
t = watchdog_runtime_wait();
|
||||
log_info("Sleeping " USEC_FMT " microseconds...", t);
|
||||
usleep(t);
|
||||
usleep_safe(t);
|
||||
log_info("Pinging...");
|
||||
r = watchdog_ping();
|
||||
if (r < 0)
|
||||
|
||||
@@ -130,7 +130,7 @@ static int run(int argc, char *argv[]) {
|
||||
r = safe_atou(argv[3], &us);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Invalid delay '%s': %m", argv[3]);
|
||||
usleep(us);
|
||||
usleep_safe(us);
|
||||
}
|
||||
|
||||
assert_se(udev_rules_load(&rules, RESOLVE_NAME_EARLY) == 0);
|
||||
|
||||
Reference in New Issue
Block a user