Skip to content

Commit 508c80d

Browse files
committed
socketpool: add sendall
The standard Python 'fix' for 'send()' returning prematurely is to use the 'sendall()' method instead. However, this method was not available. adafruit_httpserver will probably need to code a version of it for older versions or for Airlift, but when it's available this code works (Tested on picow sending 8192 bytes) and may be more efficient. (implementing 'sendall' in python should take care to slice a memoryview rather than the original buffer)
1 parent 5775686 commit 508c80d

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

shared-bindings/socketpool/Socket.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,39 @@ STATIC mp_obj_t _socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
255255
}
256256
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, _socketpool_socket_send);
257257

258+
//| def sendall(self, bytes: ReadableBuffer) -> None:
259+
//| """Send some bytes to the connected remote address.
260+
//| Suits sockets of type SOCK_STREAM
261+
//|
262+
//| This calls send() repeatedly until all the data is sent or an error
263+
//| occurs. If an error occurs, it's impossible to tell how much data
264+
//| has been sent.
265+
//|
266+
//| :param ~bytes bytes: some bytes to send"""
267+
//| ...
268+
STATIC mp_obj_t _socketpool_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) {
269+
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
270+
if (common_hal_socketpool_socket_get_closed(self)) {
271+
// Bad file number.
272+
mp_raise_OSError(MP_EBADF);
273+
}
274+
if (!common_hal_socketpool_socket_get_connected(self)) {
275+
mp_raise_BrokenPipeError();
276+
}
277+
mp_buffer_info_t bufinfo;
278+
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
279+
while (bufinfo.len > 0) {
280+
mp_int_t ret = common_hal_socketpool_socket_send(self, bufinfo.buf, bufinfo.len);
281+
if (ret == -1) {
282+
mp_raise_BrokenPipeError();
283+
}
284+
bufinfo.len -= ret;
285+
bufinfo.buf += ret;
286+
}
287+
return mp_const_none;
288+
}
289+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_sendall_obj, _socketpool_socket_sendall);
290+
258291
//| def sendto(self, bytes: ReadableBuffer, address: Tuple[str, int]) -> int:
259292
//| """Send some bytes to a specific address.
260293
//| Suits sockets of type SOCK_DGRAM
@@ -372,6 +405,7 @@ STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = {
372405
{ MP_ROM_QSTR(MP_QSTR_recvfrom_into), MP_ROM_PTR(&socketpool_socket_recvfrom_into_obj) },
373406
{ MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socketpool_socket_recv_into_obj) },
374407
{ MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socketpool_socket_send_obj) },
408+
{ MP_ROM_QSTR(MP_QSTR_sendall), MP_ROM_PTR(&socketpool_socket_sendall_obj) },
375409
{ MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socketpool_socket_sendto_obj) },
376410
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socketpool_socket_setblocking_obj) },
377411
// { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socketpool_socket_setsockopt_obj) },

0 commit comments

Comments
 (0)