fn refresh()

in time/src/lib.rs [86:222]


    fn refresh(&self) {
        match self.state.load(Ordering::Relaxed) {
            UNINITIALIZED => {
                if self
                    .state
                    .compare_exchange(
                        UNINITIALIZED,
                        REFRESHING,
                        Ordering::Acquire,
                        Ordering::Acquire,
                    )
                    .is_ok()
                {
                    let mut ts = libc::timespec {
                        tv_sec: 0,
                        tv_nsec: 0,
                    };
                    unsafe {
                        libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts);
                    }
                    self.coarse.store(
                        Instant {
                            inner: Seconds::from(ts),
                        },
                        Ordering::Release,
                    );
                    self.precise.store(
                        Instant {
                            inner: Nanoseconds::from(ts),
                        },
                        Ordering::Release,
                    );

                    let mut ts = libc::timespec {
                        tv_sec: 0,
                        tv_nsec: 0,
                    };
                    unsafe {
                        libc::clock_gettime(libc::CLOCK_REALTIME, &mut ts);
                    }
                    self.coarse_unix.store(
                        UnixInstant {
                            inner: Seconds::from(ts),
                        },
                        Ordering::Release,
                    );
                    self.precise_unix.store(
                        UnixInstant {
                            inner: Nanoseconds::from(ts),
                        },
                        Ordering::Release,
                    );

                    // finalize initialization
                    self.state.store(INITIALIZED, Ordering::Release);
                }
                // if we raced, we should block until the other thread completes
                // initialization
                while self.state.load(Ordering::Relaxed) != INITIALIZED {}
            }
            INITIALIZED => {
                if self
                    .state
                    .compare_exchange(
                        INITIALIZED,
                        REFRESHING,
                        Ordering::Acquire,
                        Ordering::Acquire,
                    )
                    .is_ok()
                {
                    let mut ts = libc::timespec {
                        tv_sec: 0,
                        tv_nsec: 0,
                    };
                    unsafe {
                        libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts);
                    }

                    let now: Instant<Nanoseconds<u64>> = Instant {
                        inner: Nanoseconds::from(ts),
                    };

                    let previous = self.precise.load(Ordering::Acquire);

                    // this makes sure we're truly monotonic even if there are
                    // platform bugs
                    if now > previous {
                        self.precise.store(now, Ordering::Release);
                        self.coarse.store(
                            Instant {
                                inner: Seconds::from(ts),
                            },
                            Ordering::Release,
                        );
                    }

                    // update unix time
                    let mut ts = libc::timespec {
                        tv_sec: 0,
                        tv_nsec: 0,
                    };
                    unsafe {
                        libc::clock_gettime(libc::CLOCK_REALTIME, &mut ts);
                    }

                    // unconditionally set unix time, which may move backwards
                    self.coarse_unix.store(
                        UnixInstant {
                            inner: Seconds::from(ts),
                        },
                        Ordering::Release,
                    );
                    self.precise_unix.store(
                        UnixInstant {
                            inner: Nanoseconds::from(ts),
                        },
                        Ordering::Release,
                    );

                    // finalize refresh
                    self.state.store(INITIALIZED, Ordering::Relaxed);
                }
                // if we raced, we should block until the other thread completes
                // initialization
                while self.state.load(Ordering::Relaxed) != INITIALIZED {}
            }
            REFRESHING => {
                // if we raced, we should block until the other thread completes
                // initialization
                while self.state.load(Ordering::Relaxed) != INITIALIZED {}
            }
            _ => {
                unreachable!()
            }
        }
    }