diff options
author | Damien George <damien.p.george@gmail.com> | 2018-12-03 18:02:10 +1100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2018-12-03 18:02:10 +1100 |
commit | 29da9f06709df77d15437b67db5978ecafcccaef (patch) | |
tree | f6f7e6d0878c65e4677542e4c0950cb5b1bff7e8 /extmod/modlwip.c | |
parent | 10bddc5c288c49351d832ef4b37b231c0a1458bc (diff) |
extmod/modlwip: Fix read-polling of listening socket with a backlog.
The recent implementation of the listen backlog meant that the logic to
test for readability of such a socket changed, and this commit updates the
logic to work again.
Diffstat (limited to 'extmod/modlwip.c')
-rw-r--r-- | extmod/modlwip.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/extmod/modlwip.c b/extmod/modlwip.c index 5cc7bbf81..73f167955 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -292,9 +292,10 @@ typedef struct _lwip_socket_obj_t { uint8_t type; #define STATE_NEW 0 - #define STATE_CONNECTING 1 - #define STATE_CONNECTED 2 - #define STATE_PEER_CLOSED 3 + #define STATE_LISTENING 1 + #define STATE_CONNECTING 2 + #define STATE_CONNECTED 3 + #define STATE_PEER_CLOSED 4 // Negative value is lwIP error int8_t state; } lwip_socket_obj_t; @@ -759,7 +760,7 @@ STATIC mp_obj_t lwip_socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) { tcp_accept(new_pcb, _lwip_tcp_accept); // Socket is no longer considered "new" for purposes of polling - socket->state = STATE_CONNECTING; + socket->state = STATE_LISTENING; return mp_const_none; } @@ -1214,8 +1215,20 @@ STATIC mp_uint_t lwip_socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_ uintptr_t flags = arg; ret = 0; - if (flags & MP_STREAM_POLL_RD && socket->incoming.pbuf != NULL) { - ret |= MP_STREAM_POLL_RD; + if (flags & MP_STREAM_POLL_RD) { + if (socket->state == STATE_LISTENING) { + // Listening TCP socket may have one or multiple connections waiting + if ((socket->incoming.connection.alloc == 0 + && socket->incoming.connection.tcp.item != NULL) + || socket->incoming.connection.tcp.array[socket->incoming.connection.iget] != NULL) { + ret |= MP_STREAM_POLL_RD; + } + } else { + // Otherwise there is just one slot for incoming data + if (socket->incoming.pbuf != NULL) { + ret |= MP_STREAM_POLL_RD; + } + } } // Note: pcb.tcp==NULL if state<0, and in this case we can't call tcp_sndbuf |