X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-event%2Fsd-event.c;h=7917ab934ae4f233732180be5e70c72266cf1224;hb=050f74f286b12945e3eb13a45dca92783fa65bb8;hp=9a9664cc0039b69170d18e9de9b3ae472e3c7750;hpb=92daebc0d0268c35f416c1665e0da3d4be5dd69f;p=elogind.git diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 9a9664cc0..7917ab934 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -43,6 +43,7 @@ typedef enum EventSourceType { SOURCE_IO, SOURCE_TIME_REALTIME, + SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM, @@ -56,7 +57,7 @@ typedef enum EventSourceType { _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1 } EventSourceType; -#define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM) +#define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM) struct sd_event_source { unsigned n_ref; @@ -130,6 +131,8 @@ struct clock_data { Prioq *earliest; Prioq *latest; usec_t next; + + bool needs_rearm:1; }; struct sd_event { @@ -142,10 +145,11 @@ struct sd_event { Prioq *pending; Prioq *prepare; - /* timerfd_create() only supports these four clocks so far. We + /* timerfd_create() only supports these five clocks so far. We * can add support for more clocks when the kernel learns to * deal with them, too. */ struct clock_data realtime; + struct clock_data boottime; struct clock_data monotonic; struct clock_data realtime_alarm; struct clock_data boottime_alarm; @@ -377,6 +381,7 @@ static void event_free(sd_event *e) { safe_close(e->watchdog_fd); free_clock_data(&e->realtime); + free_clock_data(&e->boottime); free_clock_data(&e->monotonic); free_clock_data(&e->realtime_alarm); free_clock_data(&e->boottime_alarm); @@ -403,10 +408,10 @@ _public_ int sd_event_new(sd_event** ret) { return -ENOMEM; e->n_ref = 1; - e->signal_fd = e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1; - e->realtime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = (usec_t) -1; + e->signal_fd = e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->boottime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1; + e->realtime.next = e->boottime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = USEC_INFINITY; e->original_pid = getpid(); - e->perturb = (usec_t) -1; + e->perturb = USEC_INFINITY; assert_se(sigemptyset(&e->sigset) == 0); @@ -517,6 +522,9 @@ static clockid_t event_source_type_to_clock(EventSourceType t) { case SOURCE_TIME_REALTIME: return CLOCK_REALTIME; + case SOURCE_TIME_BOOTTIME: + return CLOCK_BOOTTIME; + case SOURCE_TIME_MONOTONIC: return CLOCK_MONOTONIC; @@ -538,6 +546,9 @@ static EventSourceType clock_to_event_source_type(clockid_t clock) { case CLOCK_REALTIME: return SOURCE_TIME_REALTIME; + case CLOCK_BOOTTIME: + return SOURCE_TIME_BOOTTIME; + case CLOCK_MONOTONIC: return SOURCE_TIME_MONOTONIC; @@ -560,6 +571,9 @@ static struct clock_data* event_get_clock_data(sd_event *e, EventSourceType t) { case SOURCE_TIME_REALTIME: return &e->realtime; + case SOURCE_TIME_BOOTTIME: + return &e->boottime; + case SOURCE_TIME_MONOTONIC: return &e->monotonic; @@ -593,6 +607,7 @@ static void source_disconnect(sd_event_source *s) { break; case SOURCE_TIME_REALTIME: + case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM: { @@ -603,6 +618,7 @@ static void source_disconnect(sd_event_source *s) { prioq_remove(d->earliest, s, &s->time.earliest_index); prioq_remove(d->latest, s, &s->time.latest_index); + d->needs_rearm = true; break; } @@ -702,6 +718,7 @@ static int source_set_pending(sd_event_source *s, bool b) { prioq_reshuffle(d->earliest, s, &s->time.earliest_index); prioq_reshuffle(d->latest, s, &s->time.latest_index); + d->needs_rearm = true; } return 0; @@ -762,7 +779,7 @@ _public_ int sd_event_add_io( r = source_io_register(s, s->enabled, events); if (r < 0) { source_free(s); - return -errno; + return r; } if (ret) @@ -783,7 +800,7 @@ static void initialize_perturb(sd_event *e) { bit. Here, we calculate a perturbation usec offset from the boot ID. */ - if (_likely_(e->perturb != (usec_t) -1)) + if (_likely_(e->perturb != USEC_INFINITY)) return; if (sd_id128_get_boot(&bootid) >= 0) @@ -877,6 +894,8 @@ _public_ int sd_event_add_time( s->userdata = userdata; s->enabled = SD_EVENT_ONESHOT; + d->needs_rearm = true; + r = prioq_put(d->earliest, s, &s->time.earliest_index); if (r < 0) goto fail; @@ -1041,7 +1060,7 @@ _public_ int sd_event_add_child( r = event_update_signal_fd(e); if (r < 0) { source_free(s); - return -errno; + return r; } } @@ -1383,6 +1402,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { break; case SOURCE_TIME_REALTIME: + case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM: { @@ -1394,6 +1414,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { prioq_reshuffle(d->earliest, s, &s->time.earliest_index); prioq_reshuffle(d->latest, s, &s->time.latest_index); + d->needs_rearm = true; break; } @@ -1445,6 +1466,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { break; case SOURCE_TIME_REALTIME: + case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM: { @@ -1456,6 +1478,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { prioq_reshuffle(d->earliest, s, &s->time.earliest_index); prioq_reshuffle(d->latest, s, &s->time.latest_index); + d->needs_rearm = true; break; } @@ -1533,6 +1556,7 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) { prioq_reshuffle(d->earliest, s, &s->time.earliest_index); prioq_reshuffle(d->latest, s, &s->time.latest_index); + d->needs_rearm = true; return 0; } @@ -1567,6 +1591,7 @@ _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec assert(d); prioq_reshuffle(d->latest, s, &s->time.latest_index); + d->needs_rearm = true; return 0; } @@ -1730,13 +1755,18 @@ static int event_arm_timer( assert(e); assert(d); + if (!d->needs_rearm) + return 0; + else + d->needs_rearm = false; + a = prioq_peek(d->earliest); if (!a || a->enabled == SD_EVENT_OFF) { if (d->fd < 0) return 0; - if (d->next == (usec_t) -1) + if (d->next == USEC_INFINITY) return 0; /* disarm */ @@ -1744,7 +1774,7 @@ static int event_arm_timer( if (r < 0) return r; - d->next = (usec_t) -1; + d->next = USEC_INFINITY; return 0; } @@ -1812,7 +1842,7 @@ static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) { return -EIO; if (next) - *next = (usec_t) -1; + *next = USEC_INFINITY; return 0; } @@ -1842,6 +1872,7 @@ static int process_timer( prioq_reshuffle(d->earliest, s, &s->time.earliest_index); prioq_reshuffle(d->latest, s, &s->time.latest_index); + d->needs_rearm = true; } return 0; @@ -2005,6 +2036,7 @@ static int source_dispatch(sd_event_source *s) { break; case SOURCE_TIME_REALTIME: + case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM: @@ -2205,6 +2237,10 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { if (r < 0) goto finish; + r = event_arm_timer(e, &e->boottime); + if (r < 0) + goto finish; + r = event_arm_timer(e, &e->monotonic); if (r < 0) goto finish; @@ -2239,6 +2275,8 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_REALTIME)) r = flush_timer(e, e->realtime.fd, ev_queue[i].events, &e->realtime.next); + else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_BOOTTIME)) + r = flush_timer(e, e->boottime.fd, ev_queue[i].events, &e->boottime.next); else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_MONOTONIC)) r = flush_timer(e, e->monotonic.fd, ev_queue[i].events, &e->monotonic.next); else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_REALTIME_ALARM)) @@ -2264,6 +2302,10 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { if (r < 0) goto finish; + r = process_timer(e, e->timestamp_boottime, &e->boottime); + if (r < 0) + goto finish; + r = process_timer(e, e->timestamp.monotonic, &e->monotonic); if (r < 0) goto finish; @@ -2369,6 +2411,7 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) { *usec = e->timestamp.monotonic; break; + case CLOCK_BOOTTIME: case CLOCK_BOOTTIME_ALARM: *usec = e->timestamp_boottime; break;