@@ -6,6 +6,13 @@ use std::convert::From;
6
6
use std:: time:: Duration ;
7
7
use std:: { cmp, fmt, ops} ;
8
8
9
+ const fn zero_init_timespec ( ) -> timespec {
10
+ // `std::mem::MaybeUninit::zeroed()` is not yet a const fn
11
+ // (https://github.com/rust-lang/rust/issues/91850) so we will instead initialize an array of
12
+ // the appropriate size to zero and then transmute it to a timespec value.
13
+ unsafe { std:: mem:: transmute ( [ 0u8 ; std:: mem:: size_of :: < timespec > ( ) ] ) }
14
+ }
15
+
9
16
#[ cfg( any(
10
17
all( feature = "time" , any( target_os = "android" , target_os = "linux" ) ) ,
11
18
all(
@@ -20,7 +27,7 @@ use std::{cmp, fmt, ops};
20
27
)
21
28
) ) ]
22
29
pub ( crate ) mod timer {
23
- use crate :: sys:: time:: TimeSpec ;
30
+ use crate :: sys:: time:: { zero_init_timespec , TimeSpec } ;
24
31
use bitflags:: bitflags;
25
32
26
33
#[ derive( Debug , Clone , Copy ) ]
@@ -29,14 +36,8 @@ pub(crate) mod timer {
29
36
impl TimerSpec {
30
37
pub const fn none ( ) -> Self {
31
38
Self ( libc:: itimerspec {
32
- it_interval : libc:: timespec {
33
- tv_sec : 0 ,
34
- tv_nsec : 0 ,
35
- } ,
36
- it_value : libc:: timespec {
37
- tv_sec : 0 ,
38
- tv_nsec : 0 ,
39
- } ,
39
+ it_interval : zero_init_timespec ( ) ,
40
+ it_value : zero_init_timespec ( ) ,
40
41
} )
41
42
}
42
43
}
@@ -57,10 +58,7 @@ pub(crate) mod timer {
57
58
fn from ( expiration : Expiration ) -> TimerSpec {
58
59
match expiration {
59
60
Expiration :: OneShot ( t) => TimerSpec ( libc:: itimerspec {
60
- it_interval : libc:: timespec {
61
- tv_sec : 0 ,
62
- tv_nsec : 0 ,
63
- } ,
61
+ it_interval : zero_init_timespec ( ) ,
64
62
it_value : * t. as_ref ( ) ,
65
63
} ) ,
66
64
Expiration :: IntervalDelayed ( start, interval) => {
@@ -118,6 +116,7 @@ pub(crate) mod timer {
118
116
libc:: timespec {
119
117
tv_sec : 0 ,
120
118
tv_nsec : 0 ,
119
+ ..
121
120
} ,
122
121
it_value : ts,
123
122
} ) => Expiration :: OneShot ( ts. into ( ) ) ,
@@ -257,18 +256,17 @@ impl PartialOrd for TimeSpec {
257
256
258
257
impl TimeValLike for TimeSpec {
259
258
#[ inline]
259
+ #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
260
+ // https://github.com/rust-lang/libc/issues/1848
260
261
fn seconds ( seconds : i64 ) -> TimeSpec {
261
262
assert ! (
262
263
( TS_MIN_SECONDS ..=TS_MAX_SECONDS ) . contains( & seconds) ,
263
264
"TimeSpec out of bounds; seconds={}" ,
264
265
seconds
265
266
) ;
266
- #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
267
- // https://github.com/rust-lang/libc/issues/1848
268
- TimeSpec ( timespec {
269
- tv_sec : seconds as time_t ,
270
- tv_nsec : 0 ,
271
- } )
267
+ let mut ts = zero_init_timespec ( ) ;
268
+ ts. tv_sec = seconds as time_t ;
269
+ TimeSpec ( ts)
272
270
}
273
271
274
272
#[ inline]
@@ -292,18 +290,18 @@ impl TimeValLike for TimeSpec {
292
290
293
291
/// Makes a new `TimeSpec` with given number of nanoseconds.
294
292
#[ inline]
293
+ #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
294
+ // https://github.com/rust-lang/libc/issues/1848
295
295
fn nanoseconds ( nanoseconds : i64 ) -> TimeSpec {
296
296
let ( secs, nanos) = div_mod_floor_64 ( nanoseconds, NANOS_PER_SEC ) ;
297
297
assert ! (
298
298
( TS_MIN_SECONDS ..=TS_MAX_SECONDS ) . contains( & secs) ,
299
299
"TimeSpec out of bounds"
300
300
) ;
301
- #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
302
- // https://github.com/rust-lang/libc/issues/1848
303
- TimeSpec ( timespec {
304
- tv_sec : secs as time_t ,
305
- tv_nsec : nanos as timespec_tv_nsec_t ,
306
- } )
301
+ let mut ts = zero_init_timespec ( ) ;
302
+ ts. tv_sec = secs as time_t ;
303
+ ts. tv_nsec = nanos as timespec_tv_nsec_t ;
304
+ TimeSpec ( ts)
307
305
}
308
306
309
307
// The cast is not unnecessary on all platforms.
@@ -337,10 +335,10 @@ impl TimeSpec {
337
335
/// Construct a new `TimeSpec` from its components
338
336
#[ cfg_attr( target_env = "musl" , allow( deprecated) ) ] // https://github.com/rust-lang/libc/issues/1848
339
337
pub const fn new ( seconds : time_t , nanoseconds : timespec_tv_nsec_t ) -> Self {
340
- Self ( timespec {
341
- tv_sec : seconds,
342
- tv_nsec : nanoseconds,
343
- } )
338
+ let mut ts = zero_init_timespec ( ) ;
339
+ ts . tv_sec = seconds;
340
+ ts . tv_nsec = nanoseconds;
341
+ Self ( ts )
344
342
}
345
343
346
344
fn nanos_mod_sec ( & self ) -> timespec_tv_nsec_t {
@@ -360,13 +358,13 @@ impl TimeSpec {
360
358
self . 0 . tv_nsec
361
359
}
362
360
361
+ #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
362
+ // https://github.com/rust-lang/libc/issues/1848
363
363
pub const fn from_duration ( duration : Duration ) -> Self {
364
- #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
365
- // https://github.com/rust-lang/libc/issues/1848
366
- TimeSpec ( timespec {
367
- tv_sec : duration. as_secs ( ) as time_t ,
368
- tv_nsec : duration. subsec_nanos ( ) as timespec_tv_nsec_t ,
369
- } )
364
+ let mut ts = zero_init_timespec ( ) ;
365
+ ts. tv_sec = duration. as_secs ( ) as time_t ;
366
+ ts. tv_nsec = duration. subsec_nanos ( ) as timespec_tv_nsec_t ;
367
+ TimeSpec ( ts)
370
368
}
371
369
372
370
pub const fn from_timespec ( timespec : timespec ) -> Self {
0 commit comments