return -EBUSY;
if (try >= EFI_N_RETRIES_NO_DELAY)
- (void) usleep(EFI_RETRY_DELAY);
+ (void) usleep_safe(EFI_RETRY_DELAY);
}
if (n != sizeof(a))
if (c >= 20)
return -errno;
- (void) usleep(50 * USEC_PER_MSEC);
+ (void) usleep_safe(50 * USEC_PER_MSEC);
c++;
}
return usec_sub_unsigned(timestamp, (usec_t) delta);
}
+static inline int usleep_safe(usec_t usec) {
+ /* usleep() takes useconds_t that is (typically?) uint32_t. Also, usleep() may only support the
+ * range [0, 1000000]. See usleep(3). Let's override usleep() with nanosleep(). */
+
+ // FIXME: use RET_NERRNO() macro here. Currently, this header cannot include errno-util.h.
+ return nanosleep(TIMESPEC_STORE(usec), NULL) < 0 ? -errno : 0;
+}
+
/* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit
* year territory. However, since we want to stay away from this in all timezones we take one day off. */
#define USEC_TIMESTAMP_FORMATTABLE_MAX_64BIT ((usec_t) 253402214399000000) /* Thu 9999-12-30 23:59:59 UTC */
fflush(stdout);
if (arg_batch)
- (void) usleep(usec_add(usec_sub_unsigned(last_refresh, t), arg_delay));
+ (void) usleep_safe(usec_add(usec_sub_unsigned(last_refresh, t), arg_delay));
else {
r = read_one_char(stdin, &key, usec_add(usec_sub_unsigned(last_refresh, t), arg_delay), NULL);
if (r == -ETIMEDOUT)
end = start + BAD_PASSWORD_DELAY_USEC;
if (n < end)
- (void) usleep(usec_sub_unsigned(end, n));
+ (void) usleep_safe(usec_sub_unsigned(end, n));
}
if (r < 0)
return r;
log_debug("Initializing server");
/* Let's play some games, by slowly creating the socket directory, and renaming it in the middle */
- (void) usleep(100 * USEC_PER_MSEC);
+ usleep_safe(100 * USEC_PER_MSEC);
assert_se(mkdir_parents(path, 0755) >= 0);
- (void) usleep(100 * USEC_PER_MSEC);
+ usleep_safe(100 * USEC_PER_MSEC);
assert_se(path_extract_directory(path, &d) >= 0);
assert_se(asprintf(&suffixed, "%s.%" PRIx64, d, random_u64()) >= 0);
assert_se(rename(d, suffixed) >= 0);
- (void) usleep(100 * USEC_PER_MSEC);
+ usleep_safe(100 * USEC_PER_MSEC);
assert_se(asprintf(&suffixed2, "%s.%" PRIx64, d, random_u64()) >= 0);
assert_se(symlink(suffixed2, d) >= 0);
- (void) usleep(100 * USEC_PER_MSEC);
+ usleep_safe(100 * USEC_PER_MSEC);
assert_se(symlink(basename(suffixed), suffixed2) >= 0);
- (void) usleep(100 * USEC_PER_MSEC);
+ usleep_safe(100 * USEC_PER_MSEC);
socklen_t sa_len;
r = sockaddr_un_set_path(&u.un, path);
assert_se(fd >= 0);
assert_se(bind(fd, &u.sa, sa_len) >= 0);
- usleep(100 * USEC_PER_MSEC);
+ usleep_safe(100 * USEC_PER_MSEC);
assert_se(listen(fd, SOMAXCONN_DELUXE) >= 0);
- usleep(100 * USEC_PER_MSEC);
+ usleep_safe(100 * USEC_PER_MSEC);
assert_se(touch(path) >= 0);
- usleep(100 * USEC_PER_MSEC);
+ usleep_safe(100 * USEC_PER_MSEC);
log_debug("Initialized server");
for (unsigned i = 0; i < 10; i++) {
log_debug("slow loop iteration %u", i);
assert_se(sd_event_run(e, UINT64_MAX) >= 0);
- assert_se(usleep(250 * USEC_PER_MSEC) >= 0);
+ assert_se(usleep_safe(250 * USEC_PER_MSEC) >= 0);
}
assert_se(sd_event_source_is_ratelimited(s) == 0);
for (unsigned i = 0; i < 10; i++) {
log_debug("fast event loop iteration %u", i);
assert_se(sd_event_run(e, UINT64_MAX) >= 0);
- assert_se(usleep(10) >= 0);
+ assert_se(usleep_safe(10) >= 0);
}
log_info("ratelimit_io_handler: called %u times, event source got ratelimited", count);
assert_se(count < 10);
r = connect(clientfd, &server_address.sa, SOCKADDR_LEN(server_address));
if (r >= 0)
break;
- usleep(EVENT_TIMEOUT_USEC / 100);
+ usleep_safe(EVENT_TIMEOUT_USEC / 100);
}
assert_se(r >= 0);
try_again:
/* Device is being removed by another process. Let's wait for a while. */
- (void) usleep(2 * USEC_PER_MSEC);
+ (void) usleep_safe(2 * USEC_PER_MSEC);
}
/* All trials failed or a conflicting verity device exists. Let's try to activate with a unique name. */
/* Sleep some random time, but at least 10ms, at most 250ms. Increase the delay the more
* failed attempts we see */
- (void) usleep(UINT64_C(10) * USEC_PER_MSEC +
+ (void) usleep_safe(UINT64_C(10) * USEC_PER_MSEC +
random_u64_range(UINT64_C(240) * USEC_PER_MSEC * n_attempts/64));
}
usec = random_u64_range(UINT64_C(10) * USEC_PER_MSEC +
UINT64_C(240) * USEC_PER_MSEC * n_attempts/64);
log_debug("Trying again after %s.", FORMAT_TIMESPAN(usec, USEC_PER_MSEC));
- (void) usleep(usec);
+ (void) usleep_safe(usec);
}
d->backing_file = TAKE_PTR(backing_file);
delay *= 2;
}
- (void) usleep(delay);
+ (void) usleep_safe(delay);
}
}
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; \
/*
* 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.
*/
({
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),
*/
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));
*/
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));
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));
*/
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));
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));
*/
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));
*/
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));
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));
}),
TEST_BARRIER_WAIT_ALARM(pid1),
({
- sleep_for(BASE_TIME * 2);
+ usleep_safe(BASE_TIME * 2);
}),
TEST_BARRIER_WAIT_SUCCESS(pid2));
}),
TEST_BARRIER_WAIT_ALARM(pid1),
({
- sleep_for(BASE_TIME * 2);
+ usleep_safe(BASE_TIME * 2);
}),
TEST_BARRIER_WAIT_SUCCESS(pid2));
}),
TEST_BARRIER_WAIT_ALARM(pid1),
({
- sleep_for(BASE_TIME * 2);
+ usleep_safe(BASE_TIME * 2);
}),
TEST_BARRIER_WAIT_SUCCESS(pid2));
/*
* 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),
({
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));
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;
}
* 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);
_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);
log_info("Ate %s in total.", FORMAT_BYTES(ate));
- usleep(50 * USEC_PER_MSEC);
+ usleep_safe(50 * USEC_PER_MSEC);
}
}
if (r == 0) {
/* child */
- usleep(100 * USEC_PER_MSEC);
+ usleep_safe(100 * USEC_PER_MSEC);
_exit(88);
}
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)
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);
if (++cnt >= 20 || errno != EBUSY)
return log_debug_errno(errno, "Unable to open '%s': %m", arg_node);
- (void) usleep(100 * USEC_PER_MSEC + random_u64_range(100 * USEC_PER_MSEC));
+ (void) usleep_safe(100 * USEC_PER_MSEC + random_u64_range(100 * USEC_PER_MSEC));
}
log_debug("probing: '%s'", arg_node);
if (event->exec_delay_usec > 0) {
log_device_debug(event->dev, "Delaying execution of \"%s\" for %s.",
command, FORMAT_TIMESPAN(event->exec_delay_usec, USEC_PER_SEC));
- (void) usleep(event->exec_delay_usec);
+ (void) usleep_safe(event->exec_delay_usec);
}
log_device_debug(event->dev, "Running command \"%s\"", command);
UINT64_C(240) * USEC_PER_MSEC * n_attempts/64);
log_debug_errno(r, "Failed to get state of %s, retrying after %s: %s",
e->special, FORMAT_TIMESPAN(usec, USEC_PER_MSEC), bus_error_message(&error, r));
- (void) usleep(usec);
+ (void) usleep_safe(usec);
goto reconnect;
}
if (r < 0)