lwIP sockets: socket:close/1 does not release the processes selecting on the socket
Maintainers usually reply within 3 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 76/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- c, erlang
- Domain
- embedded-iot, networking
Research direction
Read src/libAtomVM/otp_socket.c, focusing on nif_socket_close and its OTP_SOCKET_LWIP branch; compare the suggested cleanup with socket_stop's BSD path. Check how socket_select_disown and ref_ticks are handled for both read and write selections. Done means closing an lwIP socket releases selecting processes and allows the resource destructor to run while those processes remain alive.
Written by the indexing model from the issue text.
Description
Affected: release-0.7 at ca1583068, lwIP socket backend (RP2 port; ESP32 uses BSD sockets).
Not fixed by #2345 (c4a2824f4), which extends the problem to the write direction.
What happens
On BSD sockets, socket:close/1 stops the select event and the stop callback
demonitors the selecting process, so the resource can be freed.
On lwIP, nif_socket_close only sends the closed notification. The selecting
process stays registered as owner: its pid, its monitor and the reference the
monitor holds on the resource are never released.
The socket resource (struct, rwlock, unread pbufs in received_list) is therefore
kept alive until the owning process exits, or selects again on that same socket.
A long-lived process that opens, uses and closes many sockets leaks one resource
per connection for its whole lifetime. With #2345, a process that waited for write
readiness in socket:send/2 leaks the same way.
How to reproduce (Pico W)
In one process, loop:
{ok, S} = socket:open(inet, stream, tcp),
ok = socket:connect(S, Peer),
{ok, _} = socket:recv(S, 0, 1000), % arms a read select: this process becomes owner
ok = socket:close(S)
Add a trace to socket_dtor: it does not run while the process lives.
Free heap shrinks on every iteration.
Where
src/libAtomVM/otp_socket.c, nif_socket_close, #elif OTP_SOCKET_LWIP branch.
Suggested fix
After sending the closed notifications, disown both directions
(socket_select_disown on read_select and write_select, reset their
ref_ticks), as socket_stop does on BSD sockets.
- Dominant language
- Erlang
- Stars
- 2.3k
- Forks
- 171
- Avg merge
- 4d 11h
- Merged PRs (30d)
- 20
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from atomvm/AtomVM
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 3 days
-
lwIP sockets: a failed listen or connect leaves the socket lock held, a later close hangs foreverOpen
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
Maintainers usually reply within 3 days
Similar issues
-
SPIDevice selects an active-high device as soon as it is createdPossibly taken @mikeysklar claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
adafruit/circuitpython#11869 ·
Maintainers usually reply within 1 day
-
backlog bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
EchoTools/nevr-runtime#2664 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
seven-lynx/HoundMind#108 ·
Maintainers usually reply within 1 day
-
Type: Bug USB-650
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
espressif/esp-usb#650 · 2 comments ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100