Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

screen.Exit() called within a button lambda sometimes causes thread deadlock and app freeze #927

Open
szdavid5 opened this issue Aug 29, 2024 · 7 comments

Comments

@szdavid5
Copy link

szdavid5 commented Aug 29, 2024

Title describes the problem pretty well. Code to replicate problem:

#include "ftxui/dom/elements.hpp"
#include "ftxui/screen/screen.hpp"
#include "ftxui/screen/screen.hpp"
#include "ftxui/component/component.hpp"
#include "ftxui/component/screen_interactive.hpp"

int main() {
    auto screen     = ftxui::ScreenInteractive::TerminalOutput(); 
    auto buttontest = ftxui::Button("test", [&] {  });
    auto button     = ftxui::Button("Exit", [&] { screen.Exit(); });
    auto container = ftxui::Container::Vertical({buttontest, button});
    auto renderer = ftxui::Renderer(container, [&] {
        return ftxui::vbox({ buttontest->Render(), button->Render() }) | ftxui::center;
    });
    while (true) {
        screen.Loop(renderer);
    }
}

Pressing the Exit button repeatedly will freeze the program. It sometimes takes a lot of presses but eventually it happens. Its pretty annoying because i use this scenario in my project and the freeze happens often enough to be very annoying. How can i fix this?

@ArthurSonzogni
Copy link
Owner

ArthurSonzogni commented Aug 29, 2024

Hello!
It seems you code is trapped in a "while (true)" loop. Not FTXUI fault ;-)
You can remove it?

    while (true) {

@szdavid5
Copy link
Author

Hello! Sorry for the confusion.
I know about the while loop. Its there so you can press the button many times until you encounter the thread deadlock. The problem is not an infinite loop, its a freeze.

@szdavid5
Copy link
Author

Press the button many times, it can take 5 presses or even 100 presses, but eventually the app freezes. When i pause the debugger it says its stopped in some "notifier wait" thing, which led me to believe that this is a thread deadlock, meaning two threads wait for each other infinitely. Ill attach some pictures:
image
image

@ArthurSonzogni
Copy link
Owner

ArthurSonzogni commented Aug 29, 2024

Thanks! I see.

FTXUI::ScreenInteractive are only "quittable" once. So, after you quit, you end up running the external loop infinitely.

You could use:

#include "ftxui/dom/elements.hpp"
#include "ftxui/screen/screen.hpp"
#include "ftxui/screen/screen.hpp"
#include "ftxui/component/component.hpp"
#include "ftxui/component/screen_interactive.hpp"

int main() {
    while (true) {
      auto screen     = ftxui::ScreenInteractive::TerminalOutput(); 
      auto buttontest = ftxui::Button("test", [&] {  });
      auto button     = ftxui::Button("Exit", [&] { screen.Exit(); });
      auto container = ftxui::Container::Vertical({buttontest, button});
      auto renderer = ftxui::Renderer(container, [&] {
          return ftxui::vbox({ buttontest->Render(), button->Render() }) | ftxui::center;
      });
      screen.Loop(renderer);
    }
}

to fix your problem.

I wonder what we can improve. Maybe adding an assertion to make it obvious to users? Implement "restartable" ScreenInteractive maybe?

@szdavid5
Copy link
Author

This code suffers from the same problem, which means that its not caused by exiting the same screen multiple times, the issue still persists. I just tried it out, after 10 exits this froze too.

@szdavid5
Copy link
Author

basically anytime exit() is called in a button this thread problem has a 2-3% chance of happening, which is very weird and annoying. This needs further investigation.

@szdavid5
Copy link
Author

Hello. Can you move this back to issues please?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants