-
-
Notifications
You must be signed in to change notification settings - Fork 344
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
Add optional deferMillis
parameter to System::restart()
#1611
Add optional deferMillis
parameter to System::restart()
#1611
Conversation
A system restart may be requested from within a deeply-nested callback routine, such as on network transfer completion. This happens in the `Basic_rBoot` sample application, which I have found occasionally crashes at the end of an update cycle; this is probably more likely in debug mode where there is more going on. In such scenarios it is best to defer the actual restart request so that the callback can unwind and complete fully. Therefore, this modification will _always_ defer a restart request, using either the task queue (if deferMillis == 0) or a system timer if a longer delay is required by the application.
I found with testing rBoot sample that no delay is actually required, deferring the call is sufficient. I could simplify this PR... thoughts? |
Probably fix for #1275 |
Can you elaborate on that? |
Well, only the question of whether it's necessary or useful to have the Further thought: if one's application has various other network callbacks queued (e.g. websocket broadcasts) then that would be a good reason to have an additional delay. |
What bothers me about this PR is that it fixes an issue that we don't quite well understand. Is the SDK causing the segfault, is the UART code causing it or it is something else? I am having a suspicion that we are proposing a wrong fix. The following is true for ESP8266 and NodeMCU in particular:
From here esp8266/Arduino#1722 What I am thinking is that just setting GIO0 to high will be enough. Can you try this? |
I suspect that's a different, unrelated issue. I'll use the
Now with the deferred restart:
My immediate impression is that the rug is getting pulled out from under the network stack and leading to the crash. Doubtless there is work to be done to specifically address why the |
I would have expected that the Espressif guys have already taken care of this, but without the source code I cannot tell. Will try asking @me-no-dev and @igrr if they can shed some light. |
I haven't looked at the SDK code in a while, but I think calling system_restart from an LwIP callback is not a great idea, as that call will tear down the network interface. Deferring that using a task queue seems to be the correct approach. |
I. If this is the only case where restart segfaults@mikee47 With the information from @igrr I would suggest the following - remove the new code from System::restart and add a new method called II. If there are more places where restart segfaultsThen we could think about adding System::restart to a queue. But this might hide the real cause of the problem. What do you think? |
The SDK API docs. say of I think using the 'does it segfault?' approach is perhaps risky here - it may only do it sometimes! The risk of masking problem code could be mitigated by disabling the behaviour during testing - perhaps another compiler flag. For user applications, we should provide an API which makes life as easy as possible for user applications. That means always deferring the call, and providing the option to include an additional delay so their own stuff can finish up if necessary. So I'm voting in favour of the general case which this PR addresses. |
I had a second thought on this and have to agree with you. This will bring stability without sacrificing performance or resource usage so it's fine. |
A system restart may be requested from within a deeply-nested callback routine, such as on network transfer completion. This happens in the
Basic_rBoot
sample application, which I have found occasionally crashes at the end of an update cycle; this is probably more likely in debug mode where there is more going on.In such scenarios it is best to defer the actual restart request so that the callback can unwind and complete fully. Therefore, this modification will always defer a restart request, using either the task queue (if deferMillis == 0) or a system timer if a longer delay is required by the application.