Blocking dialogs from callback

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • Blocking dialogs from callback

    Hi,
    In emWin documentation I found phrase "Please note that blocking functions should never be called from within callback functions.
    This may cause malfunction of the application." But one of your examples do that (SKINNING_NestedModal.c)

    In one place in my application I do call about 4 or 5 blocking dialogs in sequence, one will call next one, all from callbacks,
    and now a bit concerned about this. Could you please explain what kind of misbehavior could occur, how to avoid that.

    Making dialogs modal would prevent malfunctioning? (as it is done in example)

    Thanks
  • Hello,

    The more blocking dialogs your application uses in a row, the more stack is required to ensure correct function of your application. The sample SKINNING_NestedModal uses a base dialog which calls sub dialogs. Although the nesting level is quite low, we should change that sample.

    This is why calling blocking dialogs from callback functions should not be done:
    In the usual case the application creates a dialog and executes the Window Manager. The Window Manager in turn communicates with the dialog using its callback function. If a blocking dialog is created from within the callback function, the Window Manager is executed from within the blocking function (e.g. GUI_ExecDialogBox()). The application does not return from the callback function as long as the blocking dialog lasts.

    This may cause the application to run out of stack which is easy to trace, but it can also cause malfunction of the Window Manager, because the Window Manager is interrupted while processing a set of messages. So calling the Window Manager while other Window Manager instances are currently in the middle of being executed may lead to an undefined state.

    I would recommend executing blocking dialogs outside any callback function.

    Best regards,
    Adrian
  • Hello,
    Thank you Adrian, very good explanation.

    Main concern in this case is stack overflow, and multiple(!) instances of Window Manager executed in same time.

    If blocking dialogs must not to be called from callbacks, from where they are allowed to be called? (no RTOS is used)
    As all application actions are just reaction on user input (button press, etc.), the first impulse is to put action in callback.

    For example, by pressing button on window A password must be entered using window B, and focus returned back to window A, very first what is in the head is:

    Source Code

    1. windowA_callback() { case WM_NOTIFY_PARENT:, case ID_BUTTON_OK:, case WM_NOTIFICATION_RELEASED:
    2. button_pressed_on_winB = GUI_ExecDialog(...winB....)

    what is incorrect way, as you explained, because winB is blocking.

    What is then right/recommended way to do that, when no threading is used (no RTOS),
    especially when winB has to get more information from winC, winC from winD, etc. and win B,C,D by nature are blocking (user allowed go back to A only trough D-C-B)
    Could you point me to some examples on your web site, if something similar is implemented.

    That is more conceptual question about application architecture, rather particular issue with blocking dialogs. If you have some documentation regarding that, would be nice to get a link.

    Thank you very much, and have a nice day

    Serge

    The post was edited 1 time, last by Serge ().

  • Hello Serge,

    Blocking dialogs should be created at the same level the (first instance of the) Window Manager is executed. The following code snippet shows how blocking dialogs might be implemented.

    while (1) {
    if (Error) {
    BlockingDialog(); // Creates a blocking dialog
    }
    GUI_Delay(100); // Executes the Window Manager
    }

    Please note that the Window Manager as an event based mechanism does not require MultiThreading at all. I am afraid I do not know exactly which samples use blocking dialogs and which not. Sorry. The chapter "Dialogs" in the emWin user manual deals with this topic. If you feel certain topics should be explained better in this chapter, please let me know.

    Best regards,
    Adrian
  • Hello Adrian,

    I use super loop in main(), to regularly execute WM. Does that mean the only option to use blocking dialogs is to start them from super loop?
    In complex GUI application it is kind of strange, especially with said dialogs chain A-B-C-D.

    And even using your last code, it does not show how to launch A-B-C-D chain. blocking winA will start from proper place, but the rest will not, until winA will return. Still same problem?

    Does that mean, that using of blocking dialogs is limited to one running dialog at the time (no blocking winB from blocking winA),
    and starting place for such dialog is limited to only same loop where WM is called (super loop or thread) ?

    Thanks
    Serge
  • Hello Serge,

    In most cases it is recommended to use one dialog at a time no matter if it is blocking or not. So, if you want to create further blocking dialogs while there is already an active one, you can use the function GUI_EndDialog() to return a certain value. This value may tell the calling thread to create another blocking dialog.

    Best regards,
    Adrian