Skip to content

Commit

Permalink
Gui: handle view port lockup and notify developer about it (flipperde…
Browse files Browse the repository at this point in the history
…vices#3102)

* Gui: handle view port lockup and notify developer about it

* Gui: fix more viewport deadlock cases and add proper notification
  • Loading branch information
skotopes authored Sep 21, 2023
1 parent 1891d54 commit b98631c
Showing 1 changed file with 19 additions and 4 deletions.
23 changes: 19 additions & 4 deletions applications/services/gui/view_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "gui.h"
#include "gui_i.h"

#define TAG "ViewPort"

_Static_assert(ViewPortOrientationMAX == 4, "Incorrect ViewPortOrientation count");
_Static_assert(
(ViewPortOrientationHorizontal == 0 && ViewPortOrientationHorizontalFlip == 1 &&
Expand Down Expand Up @@ -174,9 +176,15 @@ void view_port_input_callback_set(

void view_port_update(ViewPort* view_port) {
furi_assert(view_port);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);

// We are not going to lockup system, but will notify you instead
// Make sure that you don't call viewport methods inside of another mutex, especially one that is used in draw call
if(furi_mutex_acquire(view_port->mutex, 2) != FuriStatusOk) {
FURI_LOG_W(TAG, "ViewPort lockup: see %s:%d", __FILE__, __LINE__ - 3);
}

if(view_port->gui && view_port->is_enabled) gui_update(view_port->gui);
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
furi_mutex_release(view_port->mutex);
}

void view_port_gui_set(ViewPort* view_port, Gui* gui) {
Expand All @@ -189,14 +197,21 @@ void view_port_gui_set(ViewPort* view_port, Gui* gui) {
void view_port_draw(ViewPort* view_port, Canvas* canvas) {
furi_assert(view_port);
furi_assert(canvas);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);

// We are not going to lockup system, but will notify you instead
// Make sure that you don't call viewport methods inside of another mutex, especially one that is used in draw call
if(furi_mutex_acquire(view_port->mutex, 2) != FuriStatusOk) {
FURI_LOG_W(TAG, "ViewPort lockup: see %s:%d", __FILE__, __LINE__ - 3);
}

furi_check(view_port->gui);

if(view_port->draw_callback) {
view_port_setup_canvas_orientation(view_port, canvas);
view_port->draw_callback(canvas, view_port->draw_callback_context);
}
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);

furi_mutex_release(view_port->mutex);
}

void view_port_input(ViewPort* view_port, InputEvent* event) {
Expand Down

0 comments on commit b98631c

Please sign in to comment.