On Raspberry Pi Pico W, socket `accept` hangs when started in a thread
On Raspberry Pi Pico W, sockets are broken when started in a thread.
Here is a minimal broken code, hanging on socket accept (at best 1st call works):
from machine import I2C, Pin
import network, time
import _thread
try:
import usocket as socket
except:
import socket
#WiFi
ssid = "MySSID"
wifikey = "MyKey"
door_state = "unknown"
def web_page():
html = """<html><head> <title>My minimal TEST</title></head><body> <h1>My minimal TEST</h1>
<p>Door state: <strong>""" + door_state + """</strong></p></body></html>"""
return html
mywifi = network.WLAN(network.STA_IF)
try:
mywifi.active(True)
mywifi.connect(ssid, wifikey)
except:
print('network config FAILED!')
for i in range(60):
if mywifi.isconnected():
print('network config:', mywifi.ifconfig())
break
else:
time.sleep(1) # Sleep for 1 second
def DummyLoop():
while True:
time.sleep(10)
def WebServer():
print("Starting webserver...")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 80))
s.listen(5)
while True:
print('Webserver: Waiting on s.accept')
conn, addr = s.accept() # Blocked here forever...
print('Webserver: Got a connection from %s' % str(addr))
request = conn.recv(1024)
request = str(request)
print('Webserver: Content = %s' % request)
response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)
conn.close()
print('Webserver: Conn.close')
_thread.start_new_thread(WebServer, ())
DummyLoop()
If I replace the last 2 lines with:
_thread.start_new_thread(DummyLoop, ())
WebServer()
to not start WebServer in a separate thread (Basically invert DummyLoop and WebServer), then, it just works.
MicroPython v1.21.0 on 2023-10-06; Raspberry Pi Pico W with RP2040
_thread module freezing whole device (RPI_PICO_W)
Summary
When using firmware built from the master branch calling _thread.start_new_thread freezes the whole machine. v1.22.0-preview and earlier works as expected.
Using Raspberry Pi Pico W.
I went back to find the commit where it breaks, and i found the breaking point: bcbdee235719d459a4cd60d51021454fba54cd0f
- 2d363a23cb9e825200e772f973eab921a69e0646 still works
- bcbdee235719d459a4cd60d51021454fba54cd0f does not work anymore
Scenario
Im using a Raspberry Pi Pico W with firmware built from the repository (make etc.) In my application, right at the start of boot.py I started a process on the second thread that constantly measured the orientation, then continued as normal, but yesterday the whole program started freezing.
After some testing I found out that calling _thread.start_new_thread(test_function, ()) freezes the machine, it cannot be stopped with ctrl-c or any other method.
I tested with this file, then importing and running test()
import _thread
def test1():
for i in range(4):
print(f"test1-{i}")
def test2():
for i in range(4):
print(f"test2-{i}")
def test():
print("Main thread:")
test1()
print("In second thread:")
_thread.start_new_thread(test2, ())
print("Main thread again:")
test1()
With 2d363a23cb9e825200e772f973eab921a69e0646 and earlier I get the expected:
Main thread:
test1-0
test1-1
test1-2
test1-3
In second thread:
Main thread again:
test2-0
test1-0
test2-1
test1-1
test2-2
test1-2
test2-3
test1-3
But after bcbdee235719d459a4cd60d51021454fba54cd0f I get:
then freezes completely. Power cycling does make the device responsive again.
Sorry about the format, first time creating an issue.