@@ -302,14 +302,14 @@ where
302302     /// Unlike [`publish`](Self::publish), this never spins or waits. Use it on latency-sensitive 
303303     /// paths where skipping a publish is preferable to blocking; call again later or fall back to 
304304     /// [`publish`](Self::publish) if you must ensure visibility. 
305-      /// 
305+      ///   
306306     /// Returns `true` if a publish occurred, `false` otherwise. 
307- 
308307     pub  fn  try_publish ( & mut  self )  -> bool  { 
309308        let  epochs = Arc :: clone ( & self . epochs ) ; 
310309        let  mut  epochs = epochs. lock ( ) . unwrap ( ) ; 
311310
312-         // we're over-estimating here, but slab doesn't expose its max index 
311+         // This wait loop is exactly like the one in wait, except that if we find a reader that 
312+         // has not observed the latest swap, we return rather than spin-and-retry. 
313313        self . last_epochs . resize ( epochs. capacity ( ) ,  0 ) ; 
314314        for  ( ri,  epoch)  in  epochs. iter ( )  { 
315315            if  self . last_epochs [ ri]  % 2  == 0  { 
@@ -326,8 +326,13 @@ where
326326                return  false ; 
327327            } 
328328        } 
329-         self . do_publish ( & mut  epochs) ; 
330-         return  true ; 
329+         #[ cfg( test) ]  
330+         { 
331+             self . is_waiting . store ( false ,  Ordering :: Relaxed ) ; 
332+         } 
333+         self . update_and_swap ( & mut  epochs) ; 
334+ 
335+         true 
331336    } 
332337
333338    /// Publish all operations append to the log to reads. 
@@ -349,11 +354,13 @@ where
349354
350355        self . wait ( & mut  epochs) ; 
351356
352-         self . do_publish ( & mut  epochs) 
357+         self . update_and_swap ( & mut  epochs) 
353358    } 
354359
355-     /// Actual doing the publishing 
356-      fn  do_publish ( 
360+     /// Brings `w_handle` up to date with the oplog, then swaps `r_handle` and `w_handle`. 
361+      /// 
362+      /// This method must only be called when all readers have exited `w_handle` (e.g., after `wait`) 
363+      fn  update_and_swap ( 
357364        & mut  self , 
358365        epochs :  & mut  MutexGuard < ' _ ,  slab:: Slab < Arc < AtomicUsize > > > , 
359366    )  -> & mut  Self  { 
@@ -766,7 +773,7 @@ mod tests {
766773        // Case 1: A reader has not advanced (odd and unchanged) -> returns false 
767774        let  mut  epochs_slab = Slab :: new ( ) ; 
768775        let  idx = epochs_slab. insert ( Arc :: new ( AtomicUsize :: new ( 1 ) ) ) ;  // odd epoch, "in read" 
769-         // Ensure last_epochs sees this reader as odd and unchanged 
776+                                                                       // Ensure last_epochs sees this reader as odd and unchanged 
770777        w. last_epochs  = vec ! [ 0 ;  epochs_slab. capacity( ) ] ; 
771778        w. last_epochs [ idx]  = 1 ; 
772779        w. epochs  = Arc :: new ( Mutex :: new ( epochs_slab) ) ; 
0 commit comments