Skip to content
New issue

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

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

Already on GitHub? Sign in 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?

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

No branches or pull requests

2 participants