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

fix: WiFiClient::flush() yields but can be called from events #5254

Merged
merged 3 commits into from
Oct 17, 2018

Conversation

d-a-v
Copy link
Collaborator

@d-a-v d-a-v commented Oct 17, 2018

for #5237

Bug introduced by #5167 which replaced delay() by yield(),
and that should have been esp_yield() which is the one delay() calls.
To be noted for current maintainers included myself:
delay() and esp_yield() can be called from sys context

yield();
// yield because we are staying longer
// (only if possible because we can be called from events)
esp_yield();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to move the esp_yield inside the if-block? Before it would yield each loop, here it will only yield if it actually sends something so it seems like it'll hard-lock, no?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In doubt, you are right.

We are waiting for acks to give us the right to send, and they are supposed to come asynchronously. So yielding here is only for avoiding wdt.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The esp_yield() should not be conditional.
Also, while in the sys context, i.e.: in an async callback: if we're relying on receiving something and detecting that reception during the yield, that won't happen => infinite loop. The async way of doing this is to break the loop body into its own function, and schedule the function to get called by the sys context. Then, in the function body, if nothing has happened and we need to continue waiting, the function is re-scheduled, and return.
Personally, I don't like the idea of trying to allow sync calls during async callbacks. In fact, I would disallow such usage, period. The call sequence and use models are very different, and there's bound to be something that will bite hard. Async callbacks in the sys context have stricter timing requirements (e.g.: sending several packets and waiting for the acks or whatever could go boom), you can't yield and then continue execution, if you're waiting on something you have to return and come back later, etc.
What I would love to have is an async socket that can work from async callbacks, and a sync socket that is built on top of it by serializing (i.e.: waiting for) the async calls. One possibility would be to implement a new WiFiClient/Server built on top of @me-no-dev 's async libs. I'm not sure how that serialization would be implemented, I'd have to think about it, but if we did manage it, we could drop a lot of code, unify with the async libs, get an async framework into the core, and overall get lots of goodies.

yield();
// yield because we are staying longer
// (only if possible because we can be called from events)
esp_yield();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The esp_yield() should not be conditional.
Also, while in the sys context, i.e.: in an async callback: if we're relying on receiving something and detecting that reception during the yield, that won't happen => infinite loop. The async way of doing this is to break the loop body into its own function, and schedule the function to get called by the sys context. Then, in the function body, if nothing has happened and we need to continue waiting, the function is re-scheduled, and return.
Personally, I don't like the idea of trying to allow sync calls during async callbacks. In fact, I would disallow such usage, period. The call sequence and use models are very different, and there's bound to be something that will bite hard. Async callbacks in the sys context have stricter timing requirements (e.g.: sending several packets and waiting for the acks or whatever could go boom), you can't yield and then continue execution, if you're waiting on something you have to return and come back later, etc.
What I would love to have is an async socket that can work from async callbacks, and a sync socket that is built on top of it by serializing (i.e.: waiting for) the async calls. One possibility would be to implement a new WiFiClient/Server built on top of @me-no-dev 's async libs. I'm not sure how that serialization would be implemented, I'd have to think about it, but if we did manage it, we could drop a lot of code, unify with the async libs, get an async framework into the core, and overall get lots of goodies.

Copy link
Collaborator

@devyte devyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see my requested changes were uploaded while I was reviewing ;)
Approved!

Copy link
Collaborator

@earlephilhower earlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now that we're back to the same structure as before, thanks!

@earlephilhower earlephilhower merged commit e549355 into esp8266:master Oct 17, 2018
@ascillato
Copy link
Contributor

Hi

@d-a-v, @earlephilhower, @devyte

We have done several tests and we found that this last commit make the device unresponsive to webserver.

Reverting to ad7cb63 all works again.

Please, could you revert this last commit?

@ascillato
Copy link
Contributor

ascillato commented Oct 18, 2018

Hi,

As discussed in e549355 changing esp_yield() to delay(0) make the webserver to work again.

Thanks. 👍

earlephilhower pushed a commit to earlephilhower/Arduino that referenced this pull request Oct 18, 2018
Replace esp_yield with delay(0) which calls both the yield and
the scheduler.

Supersedes PR esp8266#5254
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

Successfully merging this pull request may close these issues.

None yet

4 participants