pub(in crate::pagecache) fn make_stable(
    iobufs: &Arc<IoBufs>,
    lsn: Lsn,
) -> Result<usize> {
    let _measure = Measure::new(&M.make_stable);

    // NB before we write the 0th byte of the file, stable  is -1
    let first_stable = iobufs.stable();
    if first_stable >= lsn {
        return Ok(0);
    }

    let mut stable = first_stable;

    while stable < lsn {
        if let Err(e) = iobufs.config.global_error() {
            let intervals = iobufs.intervals.lock();

            // having held the mutex makes this linearized
            // with the notify below.
            drop(intervals);

            let _notified = iobufs.interval_updated.notify_all();
            return Err(e);
        }

        let iobuf = iobufs.current_iobuf();
        let header = iobuf.get_header();
        if offset(header) == 0 || is_sealed(header) || iobuf.lsn > lsn {
            // nothing to write, don't bother sealing
            // current IO buffer.
        } else {
            maybe_seal_and_write_iobuf(iobufs, &iobuf, header, false)?;
            stable = iobufs.stable();
            // NB we have to continue here to possibly clear
            // the next io buffer, which may have dirty
            // data we need to flush (and maybe no other
            // thread is still alive to do so)
            continue;
        }

        // block until another thread updates the stable lsn
        let mut waiter = iobufs.intervals.lock();

        stable = iobufs.stable();
        if stable < lsn {
            trace!("waiting on cond var for make_stable({})", lsn);

            if cfg!(feature = "event_log") {
                let timeout = iobufs
                    .interval_updated
                    .wait_for(&mut waiter, std::time::Duration::from_secs(30));
                if timeout.timed_out() {
                    fn tn() -> String {
                        std::thread::current()
                            .name()
                            .unwrap_or("unknown")
                            .to_owned()
                    }
                    panic!(
                        "{} failed to make_stable after 30 seconds. \
                         waiting to stabilize lsn {}, current stable {} \
                         intervals: {:?}",
                        tn(),
                        lsn,
                        iobufs.stable(),
                        waiter
                    );
                }
            } else {
                iobufs.interval_updated.wait(&mut waiter);
            }
        } else {
            trace!("make_stable({}) returning", lsn);
            break;
        }
    }

    Ok(assert_usize(stable - first_stable))
}
/// Blocks until the specified log sequence number has
/// been made stable on disk. Returns the number of
/// bytes written.
Blocks until the specified log sequence number has
been made stable on disk. Returns the number of
bytes written.
Blocks until the specified log sequence number has been made stable on disk . Returns the number of bytes written .
pub(in crate::pagecache) fn make_stable(
    iobufs: &Arc<IoBufs>,
    lsn: Lsn,
) -> Result<usize> {
    let _measure = Measure::new(&M.make_stable);
    // NB before we write the 0th byte of the file, stable  is -1
    let first_stable = iobufs.stable();
    if first_stable >= lsn {
        return Ok(0);
    }
    let mut stable = first_stable;
    while stable < lsn {
        if let Err(e) = iobufs.config.global_error() {
            let intervals = iobufs.intervals.lock();
            // having held the mutex makes this linearized
            // with the notify below.
            drop(intervals);
            let _notified = iobufs.interval_updated.notify_all();
            return Err(e);
        }
        let iobuf = iobufs.current_iobuf();
        let header = iobuf.get_header();
        if offset(header) == 0 || is_sealed(header) || iobuf.lsn > lsn {
            // nothing to write, don't bother sealing
            // current IO buffer.
        } else {
            maybe_seal_and_write_iobuf(iobufs, &iobuf, header, false)?;
            stable = iobufs.stable();
            // NB we have to continue here to possibly clear
            // the next io buffer, which may have dirty
            // data we need to flush (and maybe no other
            // thread is still alive to do so)
            continue;
        }
        // block until another thread updates the stable lsn
        let mut waiter = iobufs.intervals.lock();
        stable = iobufs.stable();
        if stable < lsn {
            trace!("waiting on cond var for make_stable({})", lsn);
            if cfg!(feature = "event_log") {
                let timeout = iobufs
                    .interval_updated
                    .wait_for(&mut waiter, std::time::Duration::from_secs(30));
                if timeout.timed_out() {
                    fn tn() -> String {
                        std::thread::current()
                            .name()
                            .unwrap_or("unknown")
                            .to_owned()
                    }
                    panic!(
                        "{} failed to make_stable after 30 seconds. \
                         waiting to stabilize lsn {}, current stable {} \
                         intervals: {:?}",
                        tn(),
                        lsn,
                        iobufs.stable(),
                        waiter
                    );
                }
            } else {
                iobufs.interval_updated.wait(&mut waiter);
            }
        } else {
            trace!("make_stable({}) returning", lsn);
            break;
        }
    }
    Ok(assert_usize(stable - first_stable))
}
pub ( in crate :: pagecache ) fn make_stable ( iobufs : & Arc < IoBufs > , lsn : Lsn , ) -> Result < usize > { let _measure = Measure :: new ( & M . make_stable ) ; // NB before we write the 0th byte of the file, stable  is -1 let first_stable = iobufs . stable ( ) ; if first_stable >= lsn { return Ok ( 0 ) ; } let mut stable = first_stable ; while stable < lsn { if let Err ( e ) = iobufs . config . global_error ( ) { let intervals = iobufs . intervals . lock ( ) ; // having held the mutex makes this linearized // with the notify below. drop ( intervals ) ; let _notified = iobufs . interval_updated . notify_all ( ) ; return Err ( e ) ; } let iobuf = iobufs . current_iobuf ( ) ; let header = iobuf . get_header ( ) ; if offset ( header ) == 0 || is_sealed ( header ) || iobuf . lsn > lsn { // nothing to write, don't bother sealing // current IO buffer. } else { maybe_seal_and_write_iobuf ( iobufs , & iobuf , header , false ) ? ; stable = iobufs . stable ( ) ; // NB we have to continue here to possibly clear // the next io buffer, which may have dirty // data we need to flush (and maybe no other // thread is still alive to do so) continue ; } // block until another thread updates the stable lsn let mut waiter = iobufs . intervals . lock ( ) ; stable = iobufs . stable ( ) ; if stable < lsn { trace ! ( " " lsn ) ; if cfg ! ( feature " " ) { let timeout = iobufs . interval_updated . wait_for ( & mut waiter , std :: time :: Duration :: from_secs ( 30 ) ) ; if timeout . timed_out ( ) { fn tn ( ) -> String { std :: thread :: current ( ) . name ( ) . unwrap_or ( " " ) . to_owned ( ) } panic ! ( " \
 \
 " tn ( ) lsn iobufs stable ( ) waiter ) ; } } else { iobufs . interval_updated . wait ( & mut waiter ) ; } } else { trace ! ( " " lsn ) ; break ; } } Ok ( assert_usize ( stable - first_stable ) ) }
Blocks until the specified log sequence number has
been made stable on disk.
Blocks until the specified log sequence number has been made stable on disk .
iobufs
&Arc<IoBufs>
lsn
Lsn