An absolute timer tied to CLOCK_REALTIME has a dependency that a monotonic deadline does not: an administrator, synchronization service, or privileged process can move the wall clock discontinuously while the timer is armed. Linux timerfd can expose that event explicitly. With TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, a qualifying clock jump causes a current or later read() on the timer descriptor to fail with ECANCELED.
This behavior separates two events that would otherwise be easy to conflate: reaching a scheduled wall-clock instant and invalidating the clock basis used to schedule it.
Cancellation applies to a narrow timer configuration
TFD_TIMER_CANCEL_ON_SET is meaningful when the timer uses CLOCK_REALTIME or CLOCK_REALTIME_ALARM and is armed as an absolute timer with TFD_TIMER_ABSTIME. The flag marks that timer as cancelable if the realtime clock later undergoes a discontinuous change, such as one produced by clock_settime() or settimeofday().
The combination is deliberate. A relative duration does not encode the same commitment to a named wall-clock instant, while monotonic clocks are designed not to follow wall-clock corrections.
Conceptually:
CLOCK_REALTIME = 10:00
absolute deadline = 10:30
clock jumps to 11:00
read(timerfd) -> -1
errno -> ECANCELEDThe error is therefore not an ordinary expiration count. It reports that the timer’s realtime basis changed discontinuously after the cancelable absolute timer was armed.
timerfd normally reports expiration counts
A timerfd descriptor integrates timers with descriptor-oriented event loops. After one or more expirations, a successful read() returns an eight-byte unsigned integer containing the number of expirations since the previous successful read or timer reconfiguration.
For a periodic timer, delayed consumption can therefore produce a count greater than one:
interval = 1 second
consumer delayed for about 4 intervals
read -> expiration count reflecting elapsed expirationsECANCELED occupies a different semantic channel. No eight-byte expiration count is returned by that failed read. The caller receives -1 and inspects errno.
That distinction lets an event loop treat a clock discontinuity as state invalidation rather than as another timer firing.
Absolute realtime deadlines inherit wall-clock mutability
TFD_TIMER_ABSTIME changes it_value from a relative duration into an absolute value on the selected clock. For CLOCK_REALTIME, that value belongs to a clock that can be set. A discontinuous adjustment can move the current clock value across the programmed deadline or far away from it.
Without explicit cancellation semantics, application state can become ambiguous. A component may have computed other state from the previous realtime value, persisted a matching deadline, or coordinated the deadline with an external system. Merely observing a timer event does not state that the clock basis remained continuous.
TFD_TIMER_CANCEL_ON_SET gives the application a separate failure indication. The application can then recompute its wall-clock-derived state according to its own policy rather than treating the changed clock as an ordinary passage of time.
The flag is not a general clock-change subscription
The cancellation mechanism is attached to a timer configuration. It is not a stream containing every clock adjustment, and it does not replace a general audit mechanism for time-setting operations.
The documented condition is a discontinuous change to the relevant realtime clock while a qualifying absolute timer is armed. Gradual clock discipline is not equivalent to an explicit discontinuous set for this interface. The useful contract is therefore specific: a cancelable absolute realtime timer can report that its time basis was discontinuously changed.
Applications should also avoid extending the property to CLOCK_MONOTONIC. That clock is nonsettable and serves elapsed-time scheduling where wall-clock corrections should not redefine the deadline.
Rearming has an observable Linux-specific edge case
Linux documents a notable case after cancellation. If a CLOCK_REALTIME or CLOCK_REALTIME_ALARM timer was armed with both flags, the clock changed discontinuously, and the caller invokes timerfd_settime() again without first reading the descriptor, that rearm call can return -1 with errno set to ECANCELED while still successfully applying the new timer settings.
The Linux manual describes this as behavior retained for compatibility. Code that rearms after a clock jump therefore cannot assume that an ECANCELED return from this particular sequence means the new settings were discarded.
This is an implementation-specific Linux interface detail, not a generic timer principle. State machines using this path need to account for both the error report and the documented successful rearm effect.
Cancellation keeps wall-clock scheduling explicit
Realtime scheduling is appropriate when a deadline names a civil-time instant rather than an elapsed duration. That choice necessarily imports wall-clock mutability into the timer’s semantics.
A cancelable timerfd makes one important boundary visible: a discontinuous clock set is not forced to masquerade as normal deadline progression. ECANCELED gives descriptor-based code a distinct branch for rebuilding state after the clock basis changes, while ordinary successful reads remain reserved for expiration counts.