Kaynağa Gözat

refactor menu mutexes

aanper 5 yıl önce
ebeveyn
işleme
3c453a2a20

+ 37 - 15
applications/menu/menu.c

@@ -3,7 +3,6 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <stdbool.h>
 #include <stdbool.h>
 
 
-#include <flipper.h>
 #include <flipper_v2.h>
 #include <flipper_v2.h>
 #include <gui/gui.h>
 #include <gui/gui.h>
 
 
@@ -25,23 +24,30 @@ struct Menu {
 
 
 void menu_widget_callback(CanvasApi* canvas, void* context);
 void menu_widget_callback(CanvasApi* canvas, void* context);
 
 
-Menu* menu_init() {
+ValueMutex* menu_init() {
     Menu* menu = furi_alloc(sizeof(Menu));
     Menu* menu = furi_alloc(sizeof(Menu));
 
 
     // Event dispatcher
     // Event dispatcher
     menu->event = menu_event_alloc();
     menu->event = menu_event_alloc();
 
 
+    ValueMutex* menu_mutex = furi_alloc(sizeof(ValueMutex));
+    if(menu_mutex == NULL || !init_mutex(menu_mutex, menu, sizeof(Menu))) {
+        printf("[menu_task] cannot create menu mutex\n");
+        furiac_exit(NULL);
+    }
+
     // Allocate and configure widget
     // Allocate and configure widget
     menu->widget = widget_alloc();
     menu->widget = widget_alloc();
-    widget_draw_callback_set(menu->widget, menu_widget_callback, menu);
-    widget_input_callback_set(menu->widget, menu_event_input_callback, menu->event);
 
 
     // Open GUI and register fullscreen widget
     // Open GUI and register fullscreen widget
     GuiApi* gui = furi_open("gui");
     GuiApi* gui = furi_open("gui");
     assert(gui);
     assert(gui);
     gui->add_widget(gui, menu->widget, WidgetLayerFullscreen);
     gui->add_widget(gui, menu->widget, WidgetLayerFullscreen);
 
 
-    return menu;
+    widget_draw_callback_set(menu->widget, menu_widget_callback, menu_mutex);
+    widget_input_callback_set(menu->widget, menu_event_input_callback, menu->event);
+
+    return menu_mutex;
 }
 }
 
 
 void menu_build_main(Menu* menu) {
 void menu_build_main(Menu* menu) {
@@ -79,10 +85,9 @@ void menu_settings_item_add(Menu* menu, MenuItem* item) {
 void menu_widget_callback(CanvasApi* canvas, void* context) {
 void menu_widget_callback(CanvasApi* canvas, void* context) {
     assert(canvas);
     assert(canvas);
     assert(context);
     assert(context);
-
-    Menu* menu = context;
-
-    menu_event_lock(menu->event);
+    
+    Menu* menu = acquire_mutex((ValueMutex*)context, 100); // wait 10 ms to get mutex
+    if(menu == NULL) return; // redraw fail
 
 
     if(!menu->current) {
     if(!menu->current) {
         canvas->clear(canvas);
         canvas->clear(canvas);
@@ -102,7 +107,8 @@ void menu_widget_callback(CanvasApi* canvas, void* context) {
         }
         }
     }
     }
 
 
-    menu_event_unlock(menu->event);
+    release_mutex((ValueMutex*)context, menu);
+    
 }
 }
 
 
 void menu_update(Menu* menu) {
 void menu_update(Menu* menu) {
@@ -172,10 +178,22 @@ void menu_exit(Menu* menu) {
 }
 }
 
 
 void menu_task(void* p) {
 void menu_task(void* p) {
-    Menu* menu = menu_init();
-    menu_build_main(menu);
+    ValueMutex* menu_mutex = menu_init();
 
 
-    if(!furi_create_deprecated("menu", menu, sizeof(menu))) {
+    MenuEvent* menu_event = NULL;
+    {
+        Menu* menu = acquire_mutex_block(menu_mutex);
+        assert(menu);
+
+        menu_build_main(menu);
+
+        // immutable thread-safe object
+        menu_event = menu->event;
+
+        release_mutex(menu_mutex, menu);
+    }
+
+    if(!furi_create("menu", menu_mutex)) {
         printf("[menu_task] cannot create the menu record\n");
         printf("[menu_task] cannot create the menu record\n");
         furiac_exit(NULL);
         furiac_exit(NULL);
     }
     }
@@ -183,10 +201,12 @@ void menu_task(void* p) {
     furiac_ready();
     furiac_ready();
 
 
     while(1) {
     while(1) {
-        MenuMessage m = menu_event_next(menu->event);
+        MenuMessage m = menu_event_next(menu_event);
+
+        Menu* menu = acquire_mutex_block(menu_mutex);
 
 
         if(!menu->current && m.type != MenuMessageTypeOk) {
         if(!menu->current && m.type != MenuMessageTypeOk) {
-            continue;
+            
         } else if(m.type == MenuMessageTypeUp) {
         } else if(m.type == MenuMessageTypeUp) {
             menu_up(menu);
             menu_up(menu);
         } else if(m.type == MenuMessageTypeDown) {
         } else if(m.type == MenuMessageTypeDown) {
@@ -204,5 +224,7 @@ void menu_task(void* p) {
         } else {
         } else {
             // TODO: fail somehow?
             // TODO: fail somehow?
         }
         }
+
+        release_mutex(menu_mutex, menu);
     }
     }
 }
 }

+ 0 - 17
applications/menu/menu_event.c

@@ -12,7 +12,6 @@
 struct MenuEvent {
 struct MenuEvent {
     osMessageQueueId_t mqueue;
     osMessageQueueId_t mqueue;
     osTimerId_t timeout_timer;
     osTimerId_t timeout_timer;
-    osMutexId_t lock_mutex;
 };
 };
 
 
 void MenuEventimeout_callback(void* arg) {
 void MenuEventimeout_callback(void* arg) {
@@ -32,29 +31,15 @@ MenuEvent* menu_event_alloc() {
         osTimerNew(MenuEventimeout_callback, osTimerOnce, menu_event, NULL);
         osTimerNew(MenuEventimeout_callback, osTimerOnce, menu_event, NULL);
     assert(menu_event->timeout_timer);
     assert(menu_event->timeout_timer);
 
 
-    menu_event->lock_mutex = osMutexNew(NULL);
-    assert(menu_event->lock_mutex);
-
-    menu_event_lock(menu_event);
-
     return menu_event;
     return menu_event;
 }
 }
 
 
 void menu_event_free(MenuEvent* menu_event) {
 void menu_event_free(MenuEvent* menu_event) {
     assert(menu_event);
     assert(menu_event);
-    menu_event_unlock(menu_event);
     assert(osMessageQueueDelete(menu_event->mqueue) == osOK);
     assert(osMessageQueueDelete(menu_event->mqueue) == osOK);
     free(menu_event);
     free(menu_event);
 }
 }
 
 
-void menu_event_lock(MenuEvent* menu_event) {
-    assert(osMutexAcquire(menu_event->lock_mutex, osWaitForever) == osOK);
-}
-
-void menu_event_unlock(MenuEvent* menu_event) {
-    assert(osMutexRelease(menu_event->lock_mutex) == osOK);
-}
-
 void menu_event_activity_notify(MenuEvent* menu_event) {
 void menu_event_activity_notify(MenuEvent* menu_event) {
     assert(menu_event);
     assert(menu_event);
     osTimerStart(menu_event->timeout_timer, 60000U); // 1m timeout, return to main
     osTimerStart(menu_event->timeout_timer, 60000U); // 1m timeout, return to main
@@ -63,10 +48,8 @@ void menu_event_activity_notify(MenuEvent* menu_event) {
 MenuMessage menu_event_next(MenuEvent* menu_event) {
 MenuMessage menu_event_next(MenuEvent* menu_event) {
     assert(menu_event);
     assert(menu_event);
     MenuMessage message;
     MenuMessage message;
-    menu_event_unlock(menu_event);
     while(osMessageQueueGet(menu_event->mqueue, &message, NULL, osWaitForever) != osOK) {
     while(osMessageQueueGet(menu_event->mqueue, &message, NULL, osWaitForever) != osOK) {
     };
     };
-    menu_event_lock(menu_event);
     return message;
     return message;
 }
 }
 
 

+ 0 - 4
applications/menu/menu_event.h

@@ -25,10 +25,6 @@ MenuEvent* menu_event_alloc();
 
 
 void menu_event_free(MenuEvent* menu_event);
 void menu_event_free(MenuEvent* menu_event);
 
 
-void menu_event_lock(MenuEvent* menu_event);
-
-void menu_event_unlock(MenuEvent* menu_event);
-
 void menu_event_activity_notify(MenuEvent* menu_event);
 void menu_event_activity_notify(MenuEvent* menu_event);
 
 
 MenuMessage menu_event_next(MenuEvent* menu_event);
 MenuMessage menu_event_next(MenuEvent* menu_event);