@@ -900,7 +900,7 @@ static void event_source_time_prioq_reshuffle(sd_event_source *s) {
900900 * properly again. */
901901
902902 if (s -> ratelimited )
903- d = & s -> event -> monotonic ;
903+ d = & s -> event -> boottime ;
904904 else if (EVENT_SOURCE_IS_TIME (s -> type ))
905905 assert_se (d = event_get_clock_data (s -> event , s -> type ));
906906 else
@@ -950,7 +950,7 @@ static void source_disconnect(sd_event_source *s) {
950950 case SOURCE_TIME_BOOTTIME_ALARM :
951951 /* Only remove this event source from the time event source here if it is not ratelimited. If
952952 * it is ratelimited, we'll remove it below, separately. Why? Because the clock used might
953- * differ: ratelimiting always uses CLOCK_MONOTONIC , but timer events might use any clock */
953+ * differ: ratelimiting always uses CLOCK_BOOTTIME , but timer events might use any clock */
954954
955955 if (!s -> ratelimited ) {
956956 struct clock_data * d ;
@@ -1070,7 +1070,7 @@ static void source_disconnect(sd_event_source *s) {
10701070 prioq_remove (s -> event -> prepare , s , & s -> prepare_index );
10711071
10721072 if (s -> ratelimited )
1073- event_source_time_prioq_remove (s , & s -> event -> monotonic );
1073+ event_source_time_prioq_remove (s , & s -> event -> boottime );
10741074
10751075 event = TAKE_PTR (s -> event );
10761076 LIST_REMOVE (sources , event -> sources , s );
@@ -3397,32 +3397,32 @@ static int event_source_enter_ratelimited(sd_event_source *s) {
33973397
33983398 assert (s );
33993399
3400- /* When an event source becomes ratelimited, we place it in the CLOCK_MONOTONIC priority queue, with
3400+ /* When an event source becomes ratelimited, we place it in the CLOCK_BOOTTIME priority queue, with
34013401 * the end of the rate limit time window, much as if it was a timer event source. */
34023402
34033403 if (s -> ratelimited )
34043404 return 0 ; /* Already ratelimited, this is a NOP hence */
34053405
3406- /* Make sure we can install a CLOCK_MONOTONIC event further down. */
3407- r = setup_clock_data (s -> event , & s -> event -> monotonic , CLOCK_MONOTONIC );
3406+ /* Make sure we can install a CLOCK_BOOTTIME event further down. */
3407+ r = setup_clock_data (s -> event , & s -> event -> boottime , CLOCK_BOOTTIME );
34083408 if (r < 0 )
34093409 return r ;
34103410
34113411 /* Timer event sources are already using the earliest/latest queues for the timer scheduling. Let's
34123412 * first remove them from the prioq appropriate for their own clock, so that we can use the prioq
3413- * fields of the event source then for adding it to the CLOCK_MONOTONIC prioq instead. */
3413+ * fields of the event source then for adding it to the CLOCK_BOOTTIME prioq instead. */
34143414 if (EVENT_SOURCE_IS_TIME (s -> type ))
34153415 event_source_time_prioq_remove (s , event_get_clock_data (s -> event , s -> type ));
34163416
3417- /* Now, let's add the event source to the monotonic clock instead */
3418- r = event_source_time_prioq_put (s , & s -> event -> monotonic );
3417+ /* Now, let's add the event source to the boottime clock instead */
3418+ r = event_source_time_prioq_put (s , & s -> event -> boottime );
34193419 if (r < 0 )
34203420 goto fail ;
34213421
34223422 /* And let's take the event source officially offline */
34233423 r = event_source_offline (s , s -> enabled , /* ratelimited= */ true);
34243424 if (r < 0 ) {
3425- event_source_time_prioq_remove (s , & s -> event -> monotonic );
3425+ event_source_time_prioq_remove (s , & s -> event -> boottime );
34263426 goto fail ;
34273427 }
34283428
@@ -3448,8 +3448,8 @@ static int event_source_leave_ratelimit(sd_event_source *s, bool run_callback) {
34483448 if (!s -> ratelimited )
34493449 return 0 ;
34503450
3451- /* Let's take the event source out of the monotonic prioq first. */
3452- event_source_time_prioq_remove (s , & s -> event -> monotonic );
3451+ /* Let's take the event source out of the boottime prioq first. */
3452+ event_source_time_prioq_remove (s , & s -> event -> boottime );
34533453
34543454 /* Let's then add the event source to its native clock prioq again — if this is a timer event source */
34553455 if (EVENT_SOURCE_IS_TIME (s -> type )) {
@@ -3501,7 +3501,7 @@ static int event_source_leave_ratelimit(sd_event_source *s, bool run_callback) {
35013501fail :
35023502 /* Do something somewhat reasonable when we cannot move an event sources out of ratelimited mode:
35033503 * simply put it back in it, maybe we can then process it more successfully next iteration. */
3504- assert_se (event_source_time_prioq_put (s , & s -> event -> monotonic ) >= 0 );
3504+ assert_se (event_source_time_prioq_put (s , & s -> event -> boottime ) >= 0 );
35053505
35063506 return r ;
35073507}
@@ -4781,6 +4781,7 @@ static int process_epoll(sd_event *e, usec_t timeout, int64_t threshold, int64_t
47814781}
47824782
47834783_public_ int sd_event_wait (sd_event * e , uint64_t timeout ) {
4784+ bool ratelimit_expired = false;
47844785 int r ;
47854786
47864787 assert_return (e , - EINVAL );
@@ -4845,6 +4846,8 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
48454846 r = process_timer (e , e -> timestamp .boottime , & e -> boottime );
48464847 if (r < 0 )
48474848 goto finish ;
4849+ else if (r == 1 )
4850+ ratelimit_expired = true;
48484851
48494852 r = process_timer (e , e -> timestamp .realtime , & e -> realtime_alarm );
48504853 if (r < 0 )
@@ -4857,14 +4860,19 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
48574860 r = process_timer (e , e -> timestamp .monotonic , & e -> monotonic );
48584861 if (r < 0 )
48594862 goto finish ;
4860- else if (r == 1 ) {
4861- /* Ratelimit expiry callback was called. Let's postpone processing pending sources and
4862- * put loop in the initial state in order to evaluate (in the next iteration) also sources
4863- * there were potentially re-enabled by the callback.
4863+
4864+ if (ratelimit_expired ) {
4865+ /* Ratelimit expiry callback was called. Let's postpone processing pending sources and put
4866+ * the loop in the initial state in order to evaluate (in the next iteration) also sources
4867+ * that were potentially re-enabled by the callback.
4868+ *
4869+ * Wondering why we treat only the CLOCK_BOOTTIME invocation of process_timer() differently?
4870+ * Once event source is ratelimited we essentially transform it into a CLOCK_BOOTTIME timer
4871+ * hence ratelimit expiry callback is never called for any other timer type.
48644872 *
4865- * Wondering why we treat only this invocation of process_timer() differently? Once event
4866- * source is ratelimited we essentially transform it into CLOCK_MONOTONIC timer hence
4867- * ratelimit expiry callback is never called for any other timer type . */
4873+ * Note that we don't short-circuit earlier because all timer prioqs must be fully processed
4874+ * as their timerfds may have already been flushed by process_epoll(), so skipping them would
4875+ * leave those sources unprocessed and the timerfds un-rearmed . */
48684876 r = 0 ;
48694877 goto finish ;
48704878 }
0 commit comments