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