Skip to content

Commit

Permalink
Merge pull request #1270 from jordanhalase/master
Browse files Browse the repository at this point in the history
Remove &mut self requirement in TimerSubsystem::delay()
  • Loading branch information
Cobrand authored Nov 10, 2022
2 parents ff004b6 + 18d3d7f commit c2fba95
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ when upgrading from a version of rust-sdl2 to another.

### Unreleased

[PR #1270](https://github.com/Rust-SDL2/rust-sdl2/pull/1270) **BREAKING CHANGE** Remove &mut self requirement in `TimerSubsystem::delay`; Add `TimerSubsystem::ticks64`

[PR #1225](https://github.com/Rust-SDL2/rust-sdl2/pull/1225) Update wgpu to 0.12 and fix raw-window-handle-with-wgpu example
[PR #1250](https://github.com/Rust-SDL2/rust-sdl2/pull/1250) Add `lib64` to native library search path when using bundled feature

Expand Down
43 changes: 40 additions & 3 deletions src/sdl2/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ impl TimerSubsystem {
///
/// * when the timer is dropped
/// * or when the callback returns a non-positive continuation interval
///
/// The callback is run in a thread that is created and managed internally
/// by SDL2 from C. The callback *must* not panic!
#[must_use = "if unused the Timer will be dropped immediately"]
#[doc(alias = "SDL_AddTimer")]
pub fn add_timer<'b, 'c>(&'b self, delay: u32, callback: TimerCallback<'c>) -> Timer<'b, 'c> {
Expand All @@ -34,18 +37,45 @@ impl TimerSubsystem {
/// Gets the number of milliseconds elapsed since the timer subsystem was initialized.
///
/// It's recommended that you use another library for timekeeping, such as `time`.
///
/// This function is not recommended in upstream SDL2 as of 2.0.18 and internally
/// calls the 64-bit variant and masks the result.
#[doc(alias = "SDL_GetTicks")]
pub fn ticks(&self) -> u32 {
// Google says this is probably not thread-safe (TODO: prove/disprove this).
// This is thread-safe as long as the ticks subsystem is inited, and
// tying this to `TimerSubsystem` ensures the timer subsystem can
// safely make calls into the ticks subsystem without invoking a
// thread-unsafe `SDL_TicksInit()`.
//
// This binding is offered for completeness but is debatably a relic.
unsafe { sys::SDL_GetTicks() }
}

/// Gets the number of milliseconds elapsed since the timer subsystem was initialized.
///
/// It's recommended that you use another library for timekeeping, such as `time`.
#[doc(alias = "SDL_GetTicks64")]
pub fn ticks64(&self) -> u64 {
// This is thread-safe as long as the ticks subsystem is inited, and
// tying this to `TimerSubsystem` ensures the timer subsystem can
// safely make calls into the ticks subsystem without invoking a
// thread-unsafe `SDL_TicksInit()`.
//
// This binding is offered for completeness but is debatably a relic.
unsafe { sys::SDL_GetTicks64() }
}

/// Sleeps the current thread for the specified amount of milliseconds.
///
/// It's recommended that you use `std::thread::sleep()` instead.
#[doc(alias = "SDL_Delay")]
pub fn delay(&mut self, ms: u32) {
// Google says this is probably not thread-safe (TODO: prove/disprove this).
pub fn delay(&self, ms: u32) {
// This is thread-safe as long as the ticks subsystem is inited, and
// tying this to `TimerSubsystem` ensures the timer subsystem can
// safely make calls into the ticks subsystem without invoking a
// thread-unsafe `SDL_TicksInit()`.
//
// This binding is offered for completeness but is debatably a relic.
unsafe { sys::SDL_Delay(ms) }
}

Expand Down Expand Up @@ -88,6 +118,13 @@ impl<'b, 'a> Drop for Timer<'b, 'a> {
}

extern "C" fn c_timer_callback(_interval: u32, param: *mut c_void) -> u32 {
// FIXME: This is UB if the callback panics! (But will realistically
// crash on stack underflow.)
//
// I tried using `std::panic::catch_unwind()` here and it compiled but
// would not catch. Maybe wait for `c_unwind` to stabilize? Then the behavior
// will automatically abort the process when panicking over an `extern "C"`
// function.
let f = param as *mut TimerCallback<'_>;
unsafe { (*f)() }
}
Expand Down

0 comments on commit c2fba95

Please sign in to comment.