@@ -267,14 +267,32 @@ impl Thread {
267267
268268    #[ cfg( target_os = "espidf" ) ]  
269269    pub  fn  sleep ( dur :  Duration )  { 
270-         let  mut  micros = dur. as_micros ( ) ; 
271-         unsafe  { 
272-             while  micros > 0  { 
273-                 let  st = if  micros > u32:: MAX  as  u128  {  u32:: MAX  }  else  {  micros as  u32  } ; 
270+         // ESP-IDF does not have `nanosleep`, so we use `usleep` instead. 
271+         // As per the documentation of `usleep`, it is expected to support 
272+         // sleep times as big as at least up to 1 second. 
273+         // 
274+         // ESP-IDF does support almost up to `u32::MAX`, but due to a potential integer overflow in its 
275+         // `usleep` implementation 
276+         // (https://github.com/espressif/esp-idf/blob/d7ca8b94c852052e3bc33292287ef4dd62c9eeb1/components/newlib/time.c#L210), 
277+         // we limit the sleep time to the maximum one that would not cause the underlying `usleep` implementation to overflow 
278+         // (`portTICK_PERIOD_MS` can be anything between 1 to 1000, and is 10 by default). 
279+         const  MAX_MICROS :  u32  = u32:: MAX  - 1_000_000  - 1 ; 
280+ 
281+         // Add any nanoseconds smaller than a microsecond as an extra microsecond 
282+         // so as to comply with the `std::thread::sleep` contract which mandates 
283+         // implementations to sleep for _at least_ the provided `dur`. 
284+         // We can't overflow `micros` as it is a `u128`, while `Duration` is a pair of 
285+         // (`u64` secs, `u32` nanos), where the nanos are strictly smaller than 1 second 
286+         // (i.e. < 1_000_000_000) 
287+         let  mut  micros = dur. as_micros ( )  + if  dur. subsec_nanos ( )  % 1_000  > 0  {  1  }  else  {  0  } ; 
288+ 
289+         while  micros > 0  { 
290+             let  st = if  micros > MAX_MICROS  as  u128  {  MAX_MICROS  }  else  {  micros as  u32  } ; 
291+             unsafe  { 
274292                libc:: usleep ( st) ; 
275- 
276-                 micros -= st as  u128 ; 
277293            } 
294+ 
295+             micros -= st as  u128 ; 
278296        } 
279297    } 
280298
0 commit comments