calendar-spec: use SAVE_TIMEZONE
Then, we can avoid heavy fork() operation.
This commit is contained in:
@@ -1426,13 +1426,7 @@ static int calendar_spec_next_usec_impl(const CalendarSpec *spec, usec_t usec, u
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct SpecNextResult {
|
||||
usec_t next;
|
||||
int return_value;
|
||||
} SpecNextResult;
|
||||
|
||||
int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *ret_next) {
|
||||
SpecNextResult *shared, tmp;
|
||||
int r;
|
||||
|
||||
assert(spec);
|
||||
@@ -1440,39 +1434,16 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *ret_n
|
||||
if (isempty(spec->timezone))
|
||||
return calendar_spec_next_usec_impl(spec, usec, ret_next);
|
||||
|
||||
shared = mmap(NULL, sizeof *shared, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
|
||||
if (shared == MAP_FAILED)
|
||||
return negative_errno();
|
||||
SAVE_TIMEZONE;
|
||||
|
||||
r = safe_fork("(sd-calendar)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_WAIT, NULL);
|
||||
if (r < 0) {
|
||||
(void) munmap(shared, sizeof *shared);
|
||||
/* tzset(3) says $TZ should be prefixed with ":" if we reference timezone files */
|
||||
const char *colon_tz = strjoina(":", spec->timezone);
|
||||
|
||||
r = RET_NERRNO(setenv("TZ", colon_tz, 1));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
if (r == 0) {
|
||||
char *colon_tz;
|
||||
|
||||
/* tzset(3) says $TZ should be prefixed with ":" if we reference timezone files */
|
||||
colon_tz = strjoina(":", spec->timezone);
|
||||
tzset();
|
||||
|
||||
if (setenv("TZ", colon_tz, 1) != 0) {
|
||||
shared->return_value = negative_errno();
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
tzset();
|
||||
|
||||
shared->return_value = calendar_spec_next_usec_impl(spec, usec, &shared->next);
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
tmp = *shared;
|
||||
if (munmap(shared, sizeof *shared) < 0)
|
||||
return negative_errno();
|
||||
|
||||
if (tmp.return_value == 0 && ret_next)
|
||||
*ret_next = tmp.next;
|
||||
|
||||
return tmp.return_value;
|
||||
return calendar_spec_next_usec_impl(spec, usec, ret_next);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user