Skip to content

modlwip: socket timeout ignored in send when out of memory #19746

Description

@srgg

Port, board and/or hardware

Not port-specific: generic lwip path in extmod/modlwip.c, every MICROPY_PY_LWIP port. Measured on OpenMV RT1062 (i.MX RT1062, cyw43 WiFi).

MicroPython version

master at a129b2f, by reading extmod/modlwip.c. Measured on OpenMV release firmware v5.0.0, MicroPython v1.28.0-49, built 2026-07-02, 8 KB lwIP heap.

Reproduction

  1. settimeout(0.5) socket sends to a slow peer; a second socket to another slow peer holds the lwIP heap in unacked segments.
  2. tcp_write returns ERR_MEM while tcp_sndbuf still reports room.
  3. sock.send(buf) blocks in lwip_tcp_send past 0.5 s.

One-file script, board and host side: #19705, "Test", phase 2.

Expected behaviour

sock.send() raises OSError(ETIMEDOUT) at the socket timeout, as the tcp_sndbuf == 0 wait in the same function already does.

Observed behaviour

The ERR_MEM for (;;) loop in lwip_tcp_send never reads socket->timeout. It ends on tcp_write success or at 10 s with ENOMEM. On master it waits in poll_sockets(); on the v1.28.0 line in mp_hal_delay_ms(50).

Two readers at 20 KB/s, settimeout(0.5), 120 s: starved send() took 1651–3401 ms; 0 ETIMEDOUT, 0 ENOMEM.

Additional Information

Timed-socket case of #19704. Fixed by the second commit of #19705: ETIMEDOUT at the socket timeout, counted from call start; the 10 s limit stays for a socket with no timeout. Same test with the change (16 KB heap): 172 ETIMEDOUT, 0 ENOMEM, longest send() 504 ms.

Code of Conduct

Yes, I agree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions