Skip to content

espressif: always make new client sockets be non-blocking #7455

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

Merged
merged 1 commit into from
Jan 16, 2023

Conversation

dhalbert
Copy link
Collaborator

@dhalbert dhalbert commented Jan 14, 2023

Fixes #7431.

  • The new client socket returned by accept() was not set to O_NON_BLOCK all the time, causing it to block until a request was made. Now ensure that it is always set to non-blocking.

Other fixes:

  • write()s to eventfds should always be 8 bytes. There was a write that was only 4 bytes (writing the fd). This should actually return an error, but it wasn't checked. @tannewt I don't see that the results of these writes are used anywhere, so I think this change is OK, but you can take a look. Internally they are added to a counter associated with the eventfd.
  • Added a check for ctrl-C interrupts in loop where it was not present.

I tested this on a Metro ESP32-S2, and saw that requests from Chrome were not hanging. It is also now possible to ctrl-C the HTTPServer. Before this fix, it was blocking internally on an lwip_recv(), and could not be interrupted.

Also tested the web workflow, which seems to work the same as before. Using HTTPServer on port 80 can cause issues with the web workflow, as might be expected, but these issues are not worse with this fix.

@yousafs and @michalpokusa and anyone else: testing appreciated.

I think this makes adafruit/Adafruit_CircuitPython_HTTPServer#32 not be needed.

Copy link

@jepler jepler left a comment

Choose a reason for hiding this comment

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

Makes sense, didn't test

@michalpokusa
Copy link

michalpokusa commented Jan 15, 2023

I can confirm that in my testing on ESP32-S2 TFT Feather, these changes seem to fix the blocking behaviour in Chrome.
Thanks @dhalbert!

The adafruit/Adafruit_CircuitPython_HTTPServer#32 was an experimental way to fix the issue before fix in CircuitPython itself. Right now it is indeed not needed to merge it anymore.

@microdev1 microdev1 merged commit cc6dbb3 into adafruit:main Jan 16, 2023
@dhalbert dhalbert deleted the ensure-nonblocking-socket branch February 24, 2023 16:59
@Sinai
Copy link

Sinai commented Jul 24, 2023

CircuitPython 8.2.0 , adafruit_wiznet5k 3.0.0 ,
cs = digitalio.DigitalInOut(board.D10)
spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
eth = WIZNET5K(spi_bus, cs)
socket.set_interface(eth)
socket.setdefaulttimeout(0.0) ------>>>>>> timeout
server = Server(socket, "/test")
server.poll()
Hangs and the timeout dont work.

@dhalbert
Copy link
Collaborator Author

@Sinai The choice of non-blocking here is internal; we do timeouts outselves.

@Sinai
Copy link

Sinai commented Jul 24, 2023

@dhalbert Thank you for your answer.
Yes i know. but it doesnt work and server.poll() hangs forever....

I think when you setup a Server using Wifi is different than using eth.
I have to built my own socket class. and set a timeout on that..

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.

Incorrect behaviour of timeout on socket / socket & serial port blocked - CP 8.0.0 beta6
5 participants