Skip to content

Commit

Permalink
Merge pull request #142 from lvgl/safe-init
Browse files Browse the repository at this point in the history
Make `init()` safe again, remove papercuts re: (re/de)initialization
  • Loading branch information
nia-e authored Jun 21, 2023
2 parents a5dde98 + 2d47307 commit b9763a4
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 44 deletions.
2 changes: 1 addition & 1 deletion lvgl/src/input_device/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,6 @@ mod test {
EncoderInputData::Press.pressed().once()
}

let _encoder = Encoder::register(|| read_encoder_device(), &display).unwrap();
let _encoder = Encoder::register(read_encoder_device, &display).unwrap();
}
}
2 changes: 1 addition & 1 deletion lvgl/src/input_device/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,6 @@ mod test {
.once()
}

let _touch_screen = Pointer::register(|| read_touchpad_device(), &display).unwrap();
let _touch_screen = Pointer::register(read_touchpad_device, &display).unwrap();
}
}
65 changes: 23 additions & 42 deletions lvgl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,72 +72,53 @@ pub mod widgets;
#[cfg(feature = "rust_timer")]
pub mod timer;

/*
struct RunOnce(AtomicBool);
impl RunOnce {
const fn new() -> Self {
Self(AtomicBool::new(false))
}
fn swap_and_check(&self) -> bool {
self.0
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
.is_ok()
}
}
*/

#[cfg(feature = "unsafe_no_autoinit")]
static LVGL_INITIALIZED: RunOnce = RunOnce::new();
static mut IS_INIT: bool = false;
#[cfg(not(feature = "unsafe_no_autoinit"))]
static mut IS_INIT: bool = true;

/// Initializes LVGL. Call at the start of the program.
#[cfg(feature = "unsafe_no_autoinit")]
/// Initializes LVGL. Call at the start of the program, or after safely
/// deinitializing with `deinit()`.
pub fn init() {
if LVGL_INITIALIZED.swap_and_check() {
unsafe {
unsafe {
if !IS_INIT {
lvgl_sys::lv_init();
IS_INIT = true;
}
}
}

#[cfg(not(feature = "unsafe_no_autoinit"))]
#[ctor::ctor]
fn once_init() {
/// Uninitializes LVGL. Make sure to reinitialize LVGL with `init()` before
/// accessing its functionality
///
/// # Safety
///
/// After calling, ensure existing LVGL-related values are not accessed even if
/// LVGL is reinitialized.
pub unsafe fn deinit() {
unsafe {
lvgl_sys::lv_init();
if IS_INIT {
lvgl_sys::lv_deinit();
IS_INIT = false;
}
}
}

/// Initializes LVGL.
///
/// # Safety
///
/// Unless `unsafe_no_autoinit` is enabled, do not call this function without
/// first calling `deinit()` and dropping all old values.
#[cfg(not(feature = "unsafe_no_autoinit"))]
pub unsafe fn init() {
#[ctor::ctor]
fn once_init() {
unsafe {
lvgl_sys::lv_init();
}
}

/// Uninitializes LVGL. Make sure to reinitialize it before reusing it.
///
/// # Safety
///
/// This function should not be called if LVGL is already uninitialized.
pub unsafe fn deinit() {
unsafe { lvgl_sys::lv_deinit() }
}

#[cfg(test)]
pub(crate) mod tests {
use crate::display::{Display, DrawBuffer};

pub(crate) fn initialize_test(buf: bool) {
unsafe { crate::deinit() };
unsafe { crate::init() };
crate::init();
if buf {
const REFRESH_BUFFER_SIZE: usize = 240 * 240 / 10;
let buffer = DrawBuffer::<REFRESH_BUFFER_SIZE>::default();
Expand Down

0 comments on commit b9763a4

Please sign in to comment.