esp-idf
esp-idf copied to clipboard
[Console] fix: console deinit always deadlocks - adds ability to unblock linenoise (try 2) (IDFGH-9188)
Previous PR: https://github.com/espressif/esp-idf/pull/9983
I am re-opening this PR to get more traction on it.
This solves: https://github.com/espressif/esp-idf/issues/9974
Motivation:
- currently, console deinit causes a deadlock
- without deinit, we can't create consoles "as needed"
- for example, USB Serial JTAG console should be destroyed when entering USB host mode
- for example, "web" consoles should be destroyed when the browser window is closed
Hi @chipweinberger, I started looking into your PR. Can I ask you to rebase and fix the build issues and conflict with upstream?
sure, one moment.
@SoucheSouche updated.
@SoucheSouche how are things going?
@chipweinberger, there has been some changes in the ring buffer so I am now looking at your PR again since the semaphores for rx and tx were removed.
But tomorrow is my last working day before my extended leaves so I will most likely not finish up before. Someone from my team will take over the console related PRs.
since the semaphores for rx and tx were removed.
I updated the PR and removed the semaphores.
But as I was saying before I think we should move this bit: #define rbBUFFER_UNBLOCK_RX_FLAG ( ( UBaseType_t ) 32 )
to its own variable, to simplify race condition worries.
The other issue is that this comment is still valid and your current solution won't be accepted.
I am implementing an alternative to your changes using xTaskAbortDelay
proposed solution.
@SoucheSouche , did you understand Ivans comment? "Thinking about this again, select on a pair of file descriptors (stdin and eventfd) is probably the cleanest solution." I'm not sure what that solution would look like.
If you use xTaskAbortDelay
, make sure the thread is not blocked in user code. 1. suspend the linenoise thread. 2. check its location.
@SoucheSouche another idea - we could send a "enter" key event to vfs buffers to force the thread to exit line noise.
something like:
- esp_linenoise_quit //prevent any further linenoise stdin reads or command lines being returned
- usb_serial_jtag_write('\n')
Warnings | |
---|---|
:warning: |
Some issues found for the commit messages in this PR:
Please fix these commit messages - here are some basic tips:
|
:warning: |
The source branch
|
👋 Hello chipweinberger, we appreciate your contribution to this project!
📘 Please review the project's Contributions Guide for key guidelines on code, documentation, testing, and more.
🖊️ Please also make sure you have read and signed the Contributor License Agreement for this project.
Click to see more instructions ...
This automated output is generated by the PR linter DangerJS, which checks if your Pull Request meets the project's requirements and helps you fix potential issues.
DangerJS is triggered with each push
event to a Pull Request and modify the contents of this comment.
Please consider the following:
- Danger mainly focuses on the PR structure and formatting and can't understand the meaning behind your code or changes.
- Danger is not a substitute for human code reviews; it's still important to request a code review from your colleagues.
- Resolve all warnings (⚠️ ) before requesting a review from human reviewers - they will appreciate it.
- To manually retry these Danger checks, please navigate to the Actions tab and re-run last Danger workflow.
Review and merge process you can expect ...
We do welcome contributions in the form of bug reports, feature requests and pull requests via this public GitHub repository.
This GitHub project is public mirror of our internal git repository
1. An internal issue has been created for the PR, we assign it to the relevant engineer.
2. They review the PR and either approve it or ask you for changes or clarifications.
3. Once the GitHub PR is approved, we synchronize it into our internal git repository.
4. In the internal git repository we do the final review, collect approvals from core owners and make sure all the automated tests are passing.
- At this point we may do some adjustments to the proposed change, or extend it by adding tests or documentation.
5. If the change is approved and passes the tests it is merged into the default branch.
5. On next sync from the internal git repository merged change will appear in this public GitHub repository.
Generated by :no_entry_sign: dangerJS against f85938e4db2d7bbcdffea24594cffa326216e881
Hi @chipweinberger, Sorry that I left this PR not updated for so long. I will get back at it this week. It's been a while so it might take a bit of time to get back into it but I will update you as I go through it. Hopefully we will finally be able to merge it this time.
Hi @chipweinberger, a little update on the PR. Since it was fairly old, I first had to rebase it on the latest master and realized that your solution was no longer working. The concept of adding 2 states to the console repl is great and works just fine but the solution that you were using to force linenoise to return didn't seem to work.
I experimented with select
as @igrr suggested and ended up finding a solution.
The very drafty logic implemented in linenoiseDumb()
and linenoiseRaw()
is the following:
[...]
if (select(in_fd + 1, &read_fds, NULL, &except_fds, NULL) < 0) {
// select returned with -1, handle the error
}
// std_in is either ready to read or an exceptional condition occurred
if(FD_ISSET(in_fd, &except_fds)) {
// exceptional condition occurred, return from linenoise back into the while loop
// of `esp_console_repl_task` where the repl state will be reevaluated
break;
}
else if(FD_ISSET(in_fd, &read_fds)) {
// do the reading since std_in is ready for reading
}
else {
continue;
}
I kept uart_unblock_reads
and usb_serial_jtag_unblock_reads
and I make them fire an "exceptional condition" event that will make the select
return and if(FD_ISSET(in_fd, &except_fds))
evaluated to true.
seems like a reasonable solution!
impressive :) fun :)
I had to implement the select for the usb serial jtag driver so I will have to first merge this added feature before proceeding with the actual deadlock fix. I will keep you posted.
related: https://github.com/espressif/esp-idf/issues/9964 ([USB Serial JTAG] calling select() & poll() crashes)
Hi @chipweinberger, a little update on the fix. I am still waiting to merge the select() feature for the usb cdc and usb serial jtag drivers before I can merge the fix for the deadlock. I will let you know when the select() features have been merged but it might take a little while.