X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibelogind%2Fsd-event%2Fsd-event.c;h=b4686d0065b1a943312735bf11f15b4d6b0ebac0;hb=eb0e417895c37dbdb64f18ae95c6b1a7a99f871e;hp=192dc0ea6980898fcefd2744cbad303ad3ba9cf1;hpb=2e95ec430d1d295404c517aee832ab5097f36e1c;p=elogind.git diff --git a/src/libelogind/sd-event/sd-event.c b/src/libelogind/sd-event/sd-event.c index 192dc0ea6..b4686d006 100644 --- a/src/libelogind/sd-event/sd-event.c +++ b/src/libelogind/sd-event/sd-event.c @@ -109,8 +109,8 @@ struct sd_event_source { int64_t priority; unsigned pending_index; unsigned prepare_index; - unsigned pending_iteration; - unsigned prepare_iteration; + uint64_t pending_iteration; + uint64_t prepare_iteration; LIST_FIELDS(sd_event_source, sources); @@ -215,9 +215,8 @@ struct sd_event { pid_t original_pid; - unsigned iteration; - dual_timestamp timestamp; - usec_t timestamp_boottime; + uint64_t iteration; + triple_timestamp timestamp; int state; bool exit_requested:1; @@ -547,7 +546,6 @@ static int source_io_register( return 0; } -#if 0 /// UNNEEDED by elogind static clockid_t event_source_type_to_clock(EventSourceType t) { switch (t) { @@ -571,7 +569,6 @@ static clockid_t event_source_type_to_clock(EventSourceType t) { return (clockid_t) -1; } } -#endif // 0 static EventSourceType clock_to_event_source_type(clockid_t clock) { @@ -733,7 +730,6 @@ static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig /* If all the mask is all-zero we can get rid of the structure */ hashmap_remove(e->signal_data, &d->priority); - assert(!d->current); safe_close(d->fd); free(d); return; @@ -1074,16 +1070,16 @@ _public_ int sd_event_add_time( assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); - if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) && - !clock_boottime_supported()) + if (!clock_supported(clock)) /* Checks whether the kernel supports the clock */ + return -EOPNOTSUPP; + + type = clock_to_event_source_type(clock); /* checks whether sd-event supports this clock */ + if (type < 0) return -EOPNOTSUPP; if (!callback) callback = time_exit_callback; - type = clock_to_event_source_type(clock); - assert_return(type >= 0, -EOPNOTSUPP); - d = event_get_clock_data(e, type); assert(d); @@ -1198,7 +1194,6 @@ _public_ int sd_event_add_signal( return 0; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_add_child( sd_event *e, sd_event_source **ret, @@ -1291,7 +1286,6 @@ _public_ int sd_event_add_defer( return 0; } -#endif // 0 _public_ int sd_event_add_post( sd_event *e, @@ -1370,7 +1364,6 @@ _public_ int sd_event_add_exit( return 0; } -#if 0 /// UNNEEDED by elogind _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { if (!s) @@ -1381,7 +1374,6 @@ _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { return s; } -#endif // 0 _public_ sd_event_source* sd_event_source_unref(sd_event_source *s) { @@ -1419,7 +1411,6 @@ _public_ int sd_event_source_set_description(sd_event_source *s, const char *des return free_and_strdup(&s->description, description); } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_source_get_description(sd_event_source *s, const char **description) { assert_return(s, -EINVAL); assert_return(description, -EINVAL); @@ -1429,7 +1420,6 @@ _public_ int sd_event_source_get_description(sd_event_source *s, const char **de *description = s->description; return 0; } -#endif // 0 _public_ sd_event *sd_event_source_get_event(sd_event_source *s) { assert_return(s, NULL); @@ -1437,7 +1427,6 @@ _public_ sd_event *sd_event_source_get_event(sd_event_source *s) { return s->event; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_source_get_pending(sd_event_source *s) { assert_return(s, -EINVAL); assert_return(s->type != SOURCE_EXIT, -EDOM); @@ -1454,7 +1443,6 @@ _public_ int sd_event_source_get_io_fd(sd_event_source *s) { return s->io.fd; } -#endif // 0 _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { int r; @@ -1492,7 +1480,6 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { return 0; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) { assert_return(s, -EINVAL); assert_return(events, -EINVAL); @@ -1502,7 +1489,6 @@ _public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) *events = s->io.events; return 0; } -#endif // 0 _public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) { int r; @@ -1529,7 +1515,6 @@ _public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) return 0; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) { assert_return(s, -EINVAL); assert_return(revents, -EINVAL); @@ -1553,9 +1538,9 @@ _public_ int sd_event_source_get_priority(sd_event_source *s, int64_t *priority) assert_return(s, -EINVAL); assert_return(!event_pid_changed(s->event), -ECHILD); - return s->priority; + *priority = s->priority; + return 0; } -#endif // 0 _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) { int r; @@ -1599,7 +1584,6 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) return 0; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) { assert_return(s, -EINVAL); assert_return(m, -EINVAL); @@ -1608,7 +1592,6 @@ _public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) { *m = s->enabled; return 0; } -#endif // 0 _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { int r; @@ -1794,7 +1777,6 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) { return 0; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) { assert_return(s, -EINVAL); assert_return(usec, -EINVAL); @@ -1849,7 +1831,6 @@ _public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) { *pid = s->child.pid; return 0; } -#endif // 0 _public_ int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback) { int r; @@ -1883,7 +1864,6 @@ _public_ int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t return 0; } -#if 0 /// UNNEEDED by elogind _public_ void* sd_event_source_get_userdata(sd_event_source *s) { assert_return(s, NULL); @@ -1900,7 +1880,6 @@ _public_ void *sd_event_source_set_userdata(sd_event_source *s, void *userdata) return ret; } -#endif // 0 static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) { usec_t c; @@ -2246,11 +2225,16 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) { } static int source_dispatch(sd_event_source *s) { + EventSourceType saved_type; int r = 0; assert(s); assert(s->pending || s->type == SOURCE_EXIT); + /* Save the event source type, here, so that we still know it after the event callback which might invalidate + * the event. */ + saved_type = s->type; + if (s->type != SOURCE_DEFER && s->type != SOURCE_EXIT) { r = source_set_pending(s, false); if (r < 0) @@ -2338,7 +2322,7 @@ static int source_dispatch(sd_event_source *s) { if (r < 0) log_debug_errno(r, "Event source %s (type %s) returned error, disabling: %m", - strna(s->description), event_source_type_to_string(s->type)); + strna(s->description), event_source_type_to_string(saved_type)); if (s->n_ref == 0) source_free(s); @@ -2550,9 +2534,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { goto finish; } - dual_timestamp_get(&e->timestamp); - if (clock_boottime_supported()) - e->timestamp_boottime = now(CLOCK_BOOTTIME); + triple_timestamp_get(&e->timestamp); for (i = 0; i < m; i++) { @@ -2593,7 +2575,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { if (r < 0) goto finish; - r = process_timer(e, e->timestamp_boottime, &e->boottime); + r = process_timer(e, e->timestamp.boottime, &e->boottime); if (r < 0) goto finish; @@ -2605,7 +2587,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { if (r < 0) goto finish; - r = process_timer(e, e->timestamp_boottime, &e->boottime_alarm); + r = process_timer(e, e->timestamp.boottime, &e->boottime_alarm); if (r < 0) goto finish; @@ -2715,7 +2697,6 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) { return r; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_loop(sd_event *e) { int r; @@ -2745,7 +2726,6 @@ _public_ int sd_event_get_fd(sd_event *e) { return e->epoll_fd; } -#endif // 0 _public_ int sd_event_get_state(sd_event *e) { assert_return(e, -EINVAL); @@ -2754,7 +2734,6 @@ _public_ int sd_event_get_state(sd_event *e) { return e->state; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_get_exit_code(sd_event *e, int *code) { assert_return(e, -EINVAL); assert_return(code, -EINVAL); @@ -2766,7 +2745,6 @@ _public_ int sd_event_get_exit_code(sd_event *e, int *code) { *code = e->exit_code; return 0; } -#endif // 0 _public_ int sd_event_exit(sd_event *e, int code) { assert_return(e, -EINVAL); @@ -2779,51 +2757,30 @@ _public_ int sd_event_exit(sd_event *e, int code) { return 0; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) { assert_return(e, -EINVAL); assert_return(usec, -EINVAL); assert_return(!event_pid_changed(e), -ECHILD); - assert_return(IN_SET(clock, - CLOCK_REALTIME, - CLOCK_REALTIME_ALARM, - CLOCK_MONOTONIC, - CLOCK_BOOTTIME, - CLOCK_BOOTTIME_ALARM), -EOPNOTSUPP); + if (!TRIPLE_TIMESTAMP_HAS_CLOCK(clock)) + return -EOPNOTSUPP; + + /* Generate a clean error in case CLOCK_BOOTTIME is not available. Note that don't use clock_supported() here, + * for a reason: there are systems where CLOCK_BOOTTIME is supported, but CLOCK_BOOTTIME_ALARM is not, but for + * the purpose of getting the time this doesn't matter. */ if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) && !clock_boottime_supported()) return -EOPNOTSUPP; - if (!dual_timestamp_is_set(&e->timestamp)) { + if (!triple_timestamp_is_set(&e->timestamp)) { /* Implicitly fall back to now() if we never ran * before and thus have no cached time. */ *usec = now(clock); return 1; } - switch (clock) { - - case CLOCK_REALTIME: - case CLOCK_REALTIME_ALARM: - *usec = e->timestamp.realtime; - break; - - case CLOCK_MONOTONIC: - *usec = e->timestamp.monotonic; - break; - - case CLOCK_BOOTTIME: - case CLOCK_BOOTTIME_ALARM: - *usec = e->timestamp_boottime; - break; - - default: - assert_not_reached("Unknown clock?"); - } - + *usec = triple_timestamp_by_clock(&e->timestamp, clock); return 0; } -#endif // 0 _public_ int sd_event_default(sd_event **ret) { @@ -2851,7 +2808,6 @@ _public_ int sd_event_default(sd_event **ret) { return 1; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_get_tid(sd_event *e, pid_t *tid) { assert_return(e, -EINVAL); assert_return(tid, -EINVAL); @@ -2864,7 +2820,6 @@ _public_ int sd_event_get_tid(sd_event *e, pid_t *tid) { return -ENXIO; } -#endif // 0 _public_ int sd_event_set_watchdog(sd_event *e, int b) { int r; @@ -2918,11 +2873,17 @@ fail: return r; } -#if 0 /// UNNEEDED by elogind _public_ int sd_event_get_watchdog(sd_event *e) { assert_return(e, -EINVAL); assert_return(!event_pid_changed(e), -ECHILD); return e->watchdog; } -#endif // 0 + +_public_ int sd_event_get_iteration(sd_event *e, uint64_t *ret) { + assert_return(e, -EINVAL); + assert_return(!event_pid_changed(e), -ECHILD); + + *ret = e->iteration; + return 0; +}