Fix UB, the value in MaybeUninit was being dropped

This commit is contained in:
Rafael Caricio 2020-06-19 00:16:38 +02:00 committed by Rafael Carício
parent e3fd8d5736
commit 6a9bd2d87f
3 changed files with 21 additions and 7 deletions

View file

@ -74,6 +74,8 @@ fn main() -> Result<(), LvError> {
let mut i = 0;
'running: loop {
gauge.set_value(0, i)?;
let mut ui = threaded_ui.lock().unwrap();
ui.task_handler();
if let Some(disp) = ui.get_display_ref() {
@ -93,8 +95,7 @@ fn main() -> Result<(), LvError> {
}
}
sleep(Duration::from_millis(25));
gauge.set_value(0, i)?;
sleep(Duration::from_millis(50));
if i > 99 {
i = 0;

View file

@ -1,5 +1,6 @@
use crate::{LvError, LvResult};
use core::mem;
use core::ops::{Deref, DerefMut};
use core::ptr::NonNull;
/// Places `T` into LVGL memory.
@ -45,6 +46,20 @@ impl<T> Drop for Box<T> {
}
}
impl<T> DerefMut for Box<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut()
}
}
impl<T> Deref for Box<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { self.0.as_ref() }
}
}
impl<T> AsMut<T> for Box<T> {
fn as_mut(&mut self) -> &mut T {
unsafe { self.0.as_mut() }

View file

@ -1,7 +1,7 @@
use crate::mem::Box;
use crate::{Color, Event, LvError, LvResult, Obj, Widget};
use core::marker::PhantomData;
use core::mem::{ManuallyDrop, MaybeUninit};
use core::mem::MaybeUninit;
use core::ptr;
use core::ptr::NonNull;
use core::sync::atomic::{AtomicBool, Ordering};
@ -81,15 +81,13 @@ where
let mut disp_drv = MaybeUninit::<lvgl_sys::lv_disp_drv_t>::uninit();
lvgl_sys::lv_disp_drv_init(disp_drv.as_mut_ptr());
// Since this is C managed memory, we don't want to drop it using Rust, thus `ManuallyDrop` wrapping.
let mut disp_drv = ManuallyDrop::new(disp_drv.assume_init());
let mut disp_drv = Box::new(disp_drv.assume_init())?;
// Assign the buffer to the display
disp_drv.buffer = Box::into_raw(disp_buf);
// Set your driver function
disp_drv.flush_cb = Some(display_callback_wrapper::<T, C>);
disp_drv.user_data = &mut self.display_data as *mut _ as *mut cty::c_void;
lvgl_sys::lv_disp_drv_register(
&mut ManuallyDrop::take(&mut disp_drv) as *mut lvgl_sys::lv_disp_drv_t
);
lvgl_sys::lv_disp_drv_register(Box::into_raw(disp_drv));
};
Ok(())