From d966251abbdae8a9c7e4d3df89e43527dd01bd4d Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 11:11:43 -0800 Subject: [PATCH 01/22] Try use poll instead of select --- picoquic/sockloop.c | 127 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 25f6ea8d0..00c534114 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -78,6 +78,10 @@ #include #include #include +#define PICOQUIC_USE_POLL +#ifdef PICOQUIC_USE_POLL +#include +#endif #ifndef __APPLE__ #ifdef __LINUX__ @@ -572,7 +576,83 @@ int picoquic_packet_loop_wait(picoquic_socket_ctx_t* s_ctx, } return bytes_recv; } -#else +#else +#ifdef PICOQUIC_USE_POLL +int picoquic_packet_loop_poll( + picoquic_socket_ctx_t* s_ctx, + int nb_sockets, + struct pollfd* poll_list, + int nb_pollfd, + struct sockaddr_storage* addr_from, + struct sockaddr_storage* addr_dest, + int* dest_if, + unsigned char* received_ecn, + uint8_t* buffer, int buffer_max, + int64_t delta_t, + int* is_wake_up_event, + picoquic_network_thread_ctx_t* thread_ctx, + int* socket_rank) +{ + int delta_t_ms = (int)((delta_t + 999) / 1000); + int bytes_recv = 0; + int ret_poll = poll(poll_list, nb_pollfd, delta_t_ms); + + if (received_ecn != NULL) { + *received_ecn = 0; + } + + + if (ret_poll < 0) { + bytes_recv = -1; + DBG_PRINTF("Error: poll returns %d\n", ret_poll); + } + else if (ret_poll > 0) { + /* Check if the 'wake up' pipe is full. If it is, read the data on it, + * set the is_wake_up_event flag, and ignore the other file descriptors. */ + if (thread_ctx->wake_up_defined && poll_list[nb_sockets].revent != 0) { + /* Something was written on the "wakeup" pipe. Read it. */ + uint8_t eventbuf[8]; + int pipe_recv; + if ((pipe_recv = read(thread_ctx->wake_up_pipe_fd[0], eventbuf, sizeof(eventbuf))) <= 0) { + bytes_recv = -1; + DBG_PRINTF("Error: read pipe returns %d\n", (pipe_recv == 0) ? EPIPE : errno); + } + else { + *is_wake_up_event = 1; + } + } + else + { + for (int i = 0; i < nb_sockets; i++) { + if (poll_list[i].revent != 0) { + *socket_rank = i; + bytes_recv = picoquic_recvmsg(s_ctx[i].fd, addr_from, + addr_dest, dest_if, received_ecn, + buffer, buffer_max); + + if (bytes_recv <= 0) { + DBG_PRINTF("Could not receive packet on UDP socket[%d]= %d!\n", + i, (int)s_ctx[i].fd); + break; + } + else { + /* Document incoming port */ + if (addr_dest->ss_family == AF_INET6) { + ((struct sockaddr_in6*)addr_dest)->sin6_port = s_ctx[i].n_port; + } + else if (addr_dest->ss_family == AF_INET) { + ((struct sockaddr_in*)addr_dest)->sin_port = s_ctx[i].n_port; + } + break; + } + } + } + } + } + + return bytes_recv; +} +#else int picoquic_packet_loop_select(picoquic_socket_ctx_t* s_ctx, int nb_sockets, struct sockaddr_storage* addr_from, @@ -677,6 +757,7 @@ int picoquic_packet_loop_select(picoquic_socket_ctx_t* s_ctx, return bytes_recv; } #endif +#endif static int monitor_system_call_duration(packet_loop_system_call_duration_t* sc_duration, uint64_t current_time, uint64_t previous_time) { @@ -747,6 +828,11 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifdef _WINDOWS WSADATA wsaData = { 0 }; (void)WSA_START(MAKEWORD(2, 2), &wsaData); +#else +#ifdef PICOQUIC_USE_POLL + struct pollfd* poll_list = NULL; + int nb_pollfd = 0; +#endif #endif if (thread_ctx->thread_name != NULL) { @@ -776,6 +862,29 @@ void* picoquic_packet_loop_v3(void* v_ctx) ret = loop_callback(quic, picoquic_packet_loop_alt_port, loop_callback_ctx, &alt_port); } } +#ifndef _WINDOWS +#ifdef PICOQUIC_USE_POLL + if (ret == 0) { + nb_pollfd = nb_sockets + (thread_ctx->wake_up_defined)?1:0; + poll_list = (struct pollfd*)malloc(sizeof(struct pollfd) * nb_pollfd); + if (poll_list == NULL) { + ret = PICOQUIC_ERROR_UNEXPECTED_ERROR; + } + else + { + memset(poll_list, 0, sizeof(struct pollfd) * nb_pollfd); + for (int i = 0; i < nb_sockets; i++) { + poll_list[i].fd = (int)s_ctx[i].fd; + poll_list[i].events = POLLIN; + } + if (thread_ctx->wake_up_defined) { + poll_list[nb_sockets].fd = (int)thread_ctx->wake_up_pipe_fd[0]; + poll_list[nb_sockets].events = POLLIN; + } + } + } +#endif +#endif if (ret == 0) { nb_sockets_available = nb_sockets; @@ -847,6 +956,16 @@ void* picoquic_packet_loop_v3(void* v_ctx) bytes_recv = picoquic_packet_loop_wait(s_ctx, nb_sockets_available, &addr_from, &addr_to, &if_index_to, &received_ecn, &received_buffer, delta_t, &is_wake_up_event, thread_ctx, &socket_rank); +#else +#ifdef PICOQUIC_USE_POLL + bytes_recv = picoquic_packet_loop_poll( + s_ctx, nb_sockets_available, + poll_list, nb_pollfd, + & addr_from, + & addr_to, & if_index_to, & received_ecn, + buffer, sizeof(buffer), + delta_t, & is_wake_up_event, thread_ctx, & socket_rank); + received_buffer = buffer; #else bytes_recv = picoquic_packet_loop_select(s_ctx, nb_sockets_available, &addr_from, @@ -854,6 +973,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) buffer, sizeof(buffer), delta_t, &is_wake_up_event, thread_ctx, &socket_rank); received_buffer = buffer; +#endif #endif current_time = picoquic_current_time(); if (options.do_system_call_duration && delta_t == 0 && @@ -1112,6 +1232,11 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifdef _WINDOWS return (DWORD)ret; #else +#ifdef PICOQUIC_USE_POLL + if (poll_list != NULL) { + free(poll_list); + } +#endif if (thread_ctx->is_threaded) { pthread_exit((void*)&thread_ctx->return_code); } From a2a040f1b803373aeb99aad5bb332a941f226851 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 11:14:04 -0800 Subject: [PATCH 02/22] Fix typo --- picoquic/sockloop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 00c534114..76d48a82e 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -609,7 +609,7 @@ int picoquic_packet_loop_poll( else if (ret_poll > 0) { /* Check if the 'wake up' pipe is full. If it is, read the data on it, * set the is_wake_up_event flag, and ignore the other file descriptors. */ - if (thread_ctx->wake_up_defined && poll_list[nb_sockets].revent != 0) { + if (thread_ctx->wake_up_defined && poll_list[nb_sockets].revents != 0) { /* Something was written on the "wakeup" pipe. Read it. */ uint8_t eventbuf[8]; int pipe_recv; @@ -624,7 +624,7 @@ int picoquic_packet_loop_poll( else { for (int i = 0; i < nb_sockets; i++) { - if (poll_list[i].revent != 0) { + if (poll_list[i].revents != 0) { *socket_rank = i; bytes_recv = picoquic_recvmsg(s_ctx[i].fd, addr_from, addr_dest, dest_if, received_ecn, From e8489796d33daddd11780932ba7e2c92501acb5d Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 11:36:14 -0800 Subject: [PATCH 03/22] Add debugging info --- picoquic/sockloop.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 76d48a82e..46f314848 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -872,6 +872,8 @@ void* picoquic_packet_loop_v3(void* v_ctx) } else { + DBG_PRINTF("Allocated %zu time %d bytes for poll_list (nb sockets: %d)", + sizeof(struct pollfd), nb_pollfd, nb_sockets); memset(poll_list, 0, sizeof(struct pollfd) * nb_pollfd); for (int i = 0; i < nb_sockets; i++) { poll_list[i].fd = (int)s_ctx[i].fd; From 9116ac9d8dfbfeb39bebcb88711ee0f4807dc60b Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 11:50:36 -0800 Subject: [PATCH 04/22] more debug info, again. --- picoquic/sockloop.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 46f314848..9e831a934 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -830,7 +830,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) (void)WSA_START(MAKEWORD(2, 2), &wsaData); #else #ifdef PICOQUIC_USE_POLL - struct pollfd* poll_list = NULL; + struct pollfd poll_list[] = NULL; int nb_pollfd = 0; #endif #endif @@ -865,15 +865,17 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifndef _WINDOWS #ifdef PICOQUIC_USE_POLL if (ret == 0) { + size_t pollfd_size; nb_pollfd = nb_sockets + (thread_ctx->wake_up_defined)?1:0; - poll_list = (struct pollfd*)malloc(sizeof(struct pollfd) * nb_pollfd); + pollfd_size = sizeof(struct pollfd) * nb_pollfd; + poll_list = (struct pollfd*)malloc(pollfd_size); if (poll_list == NULL) { ret = PICOQUIC_ERROR_UNEXPECTED_ERROR; } else { - DBG_PRINTF("Allocated %zu time %d bytes for poll_list (nb sockets: %d)", - sizeof(struct pollfd), nb_pollfd, nb_sockets); + DBG_PRINTF("Allocated %zu bytes (%zu times %d) for poll_list (nb sockets: %d, wakeup: %d)", + pollfd_size, sizeof(struct pollfd), nb_pollfd, nb_sockets, (thread_ctx->wake_up_defined) ? 1 : 0); memset(poll_list, 0, sizeof(struct pollfd) * nb_pollfd); for (int i = 0; i < nb_sockets; i++) { poll_list[i].fd = (int)s_ctx[i].fd; @@ -883,6 +885,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) poll_list[nb_sockets].fd = (int)thread_ctx->wake_up_pipe_fd[0]; poll_list[nb_sockets].events = POLLIN; } + DBG_PRINTF("Initialized %zu bytes for poll_list", pollfd_size); } } #endif From 17f8fe746f2604e9bc648bd671705cdaa5a64c11 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 11:54:56 -0800 Subject: [PATCH 05/22] fix errant [] --- picoquic/sockloop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 9e831a934..8b569ec8e 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -830,7 +830,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) (void)WSA_START(MAKEWORD(2, 2), &wsaData); #else #ifdef PICOQUIC_USE_POLL - struct pollfd poll_list[] = NULL; + struct pollfd poll_list * = NULL; int nb_pollfd = 0; #endif #endif From 0ae5fa345cdd476a73a05913fe2aac19e40923b1 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 11:56:16 -0800 Subject: [PATCH 06/22] fix another typo --- picoquic/sockloop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 8b569ec8e..73cf4ab02 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -830,7 +830,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) (void)WSA_START(MAKEWORD(2, 2), &wsaData); #else #ifdef PICOQUIC_USE_POLL - struct pollfd poll_list * = NULL; + struct pollfd * poll_list = NULL; int nb_pollfd = 0; #endif #endif From dda51495379671eb8e9b6b59366dc78c44ca79ad Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 12:10:10 -0800 Subject: [PATCH 07/22] Track wakeup issue --- picoquic/sockloop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 73cf4ab02..bb5f7a29a 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -613,11 +613,14 @@ int picoquic_packet_loop_poll( /* Something was written on the "wakeup" pipe. Read it. */ uint8_t eventbuf[8]; int pipe_recv; + DBG_PRINTF("Waking up -- defined: %d, nb_sockets: %d", + (thread_ctx->wake_up_defined) ? 1 : 0, nb_sockets); if ((pipe_recv = read(thread_ctx->wake_up_pipe_fd[0], eventbuf, sizeof(eventbuf))) <= 0) { bytes_recv = -1; DBG_PRINTF("Error: read pipe returns %d\n", (pipe_recv == 0) ? EPIPE : errno); } else { + DBG_PRINTF("Waking up -- received: %d", pipe_recv); *is_wake_up_event = 1; } } From 4c746d596a0d24c6202c48dd78f7e04b42873ebd Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 12:23:25 -0800 Subject: [PATCH 08/22] Do set wakeup = 0 --- picoquic/sockloop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index bb5f7a29a..69544b7cd 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -600,7 +600,7 @@ int picoquic_packet_loop_poll( if (received_ecn != NULL) { *received_ecn = 0; } - + *is_wake_up_event = 0; if (ret_poll < 0) { bytes_recv = -1; From 30bd1a4e5290429da378ff2a4eeb8c1db5097e5a Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 14:45:27 -0800 Subject: [PATCH 09/22] Reset poll list if new socket --- picoquic/sockloop.c | 67 +++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 69544b7cd..54b5af113 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -578,6 +578,40 @@ int picoquic_packet_loop_wait(picoquic_socket_ctx_t* s_ctx, } #else #ifdef PICOQUIC_USE_POLL +int picoquic_packet_loop_set_fds(struct pollfd ** poll_list, int * nb_pollfd, + picoquic_socket_ctx_t* s_ctx, + int nb_sockets, + picoquic_network_thread_ctx_t* thread_ctx) +{ + int ret = 0; + size_t pollfd_size; + if (*poll_list != NULL) { + free(*poll_list); + } + *nb_pollfd = nb_sockets + (thread_ctx->wake_up_defined) ? 1 : 0; + pollfd_size = sizeof(struct pollfd) * (*nb_pollfd); + *poll_list = (struct pollfd*)malloc(pollfd_size); + if (*poll_list == NULL) { + ret = PICOQUIC_ERROR_UNEXPECTED_ERROR; + } + else + { + DBG_PRINTF("Allocated %zu bytes (%zu times %d) for poll_list (nb sockets: %d, wakeup: %d)", + pollfd_size, sizeof(struct pollfd), *nb_pollfd, nb_sockets, (thread_ctx->wake_up_defined) ? 1 : 0); + memset(poll_list, 0, sizeof(struct pollfd) * nb_pollfd); + for (int i = 0; i < nb_sockets; i++) { + (*poll_list)[i].fd = (int)s_ctx[i].fd; + (*poll_list)[i].events = POLLIN; + } + if (thread_ctx->wake_up_defined) { + (*poll_list)[nb_sockets].fd = (int)thread_ctx->wake_up_pipe_fd[0]; + (*poll_list)[nb_sockets].events = POLLIN; + } + DBG_PRINTF("Initialized %zu bytes for poll_list", pollfd_size); + } +} + + int picoquic_packet_loop_poll( picoquic_socket_ctx_t* s_ctx, int nb_sockets, @@ -868,28 +902,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifndef _WINDOWS #ifdef PICOQUIC_USE_POLL if (ret == 0) { - size_t pollfd_size; - nb_pollfd = nb_sockets + (thread_ctx->wake_up_defined)?1:0; - pollfd_size = sizeof(struct pollfd) * nb_pollfd; - poll_list = (struct pollfd*)malloc(pollfd_size); - if (poll_list == NULL) { - ret = PICOQUIC_ERROR_UNEXPECTED_ERROR; - } - else - { - DBG_PRINTF("Allocated %zu bytes (%zu times %d) for poll_list (nb sockets: %d, wakeup: %d)", - pollfd_size, sizeof(struct pollfd), nb_pollfd, nb_sockets, (thread_ctx->wake_up_defined) ? 1 : 0); - memset(poll_list, 0, sizeof(struct pollfd) * nb_pollfd); - for (int i = 0; i < nb_sockets; i++) { - poll_list[i].fd = (int)s_ctx[i].fd; - poll_list[i].events = POLLIN; - } - if (thread_ctx->wake_up_defined) { - poll_list[nb_sockets].fd = (int)thread_ctx->wake_up_pipe_fd[0]; - poll_list[nb_sockets].events = POLLIN; - } - DBG_PRINTF("Initialized %zu bytes for poll_list", pollfd_size); - } + ret = picoquic_packet_loop_set_fds(&poll_list, & nb_pollfd, s_ctx, nb_sockets, thread_ctx); } #endif #endif @@ -1039,7 +1052,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) /* If the number of packets received in immediate mode has not * reached the threshold, set the "immediate" flag and bypass - * the sending code. + * the sending code. */ if (ret == 0 && nb_loop_immediate < PICOQUIC_PACKET_LOOP_RECV_MAX) { loop_immediate = 1; @@ -1133,6 +1146,13 @@ void* picoquic_packet_loop_v3(void* v_ctx) nb_sockets_available++; if (nb_sockets < nb_sockets_available) { nb_sockets = nb_sockets_available; +#ifndef _WINDOWS +#ifdef PICOQUIC_USE_POLL + if ((ret = picoquic_packet_loop_set_fds(&poll_list, &nb_pollfd, s_ctx, nb_sockets, thread_ctx)) != 0){ + break; + } +#endif +#endif } } } @@ -1144,7 +1164,6 @@ void* picoquic_packet_loop_v3(void* v_ctx) } else { - if (param->simulate_eio && send_length > PICOQUIC_MAX_PACKET_SIZE) { /* Test hook, simulating a driver that does not support GSO */ sock_ret = -1; From 6bd3d2f03b0c7ad0e84902fb9817711311cefc61 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 14:47:44 -0800 Subject: [PATCH 10/22] fix typo --- picoquic/sockloop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 54b5af113..725c2004d 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -598,7 +598,7 @@ int picoquic_packet_loop_set_fds(struct pollfd ** poll_list, int * nb_pollfd, { DBG_PRINTF("Allocated %zu bytes (%zu times %d) for poll_list (nb sockets: %d, wakeup: %d)", pollfd_size, sizeof(struct pollfd), *nb_pollfd, nb_sockets, (thread_ctx->wake_up_defined) ? 1 : 0); - memset(poll_list, 0, sizeof(struct pollfd) * nb_pollfd); + memset(poll_list, 0, pollfd_size); for (int i = 0; i < nb_sockets; i++) { (*poll_list)[i].fd = (int)s_ctx[i].fd; (*poll_list)[i].events = POLLIN; From 3b59545d85ad7f9ae6d2061acdb1a4d52bda0383 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 14:49:52 -0800 Subject: [PATCH 11/22] Another typo --- picoquic/sockloop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 725c2004d..dea7179dd 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -598,7 +598,7 @@ int picoquic_packet_loop_set_fds(struct pollfd ** poll_list, int * nb_pollfd, { DBG_PRINTF("Allocated %zu bytes (%zu times %d) for poll_list (nb sockets: %d, wakeup: %d)", pollfd_size, sizeof(struct pollfd), *nb_pollfd, nb_sockets, (thread_ctx->wake_up_defined) ? 1 : 0); - memset(poll_list, 0, pollfd_size); + memset(*poll_list, 0, pollfd_size); for (int i = 0; i < nb_sockets; i++) { (*poll_list)[i].fd = (int)s_ctx[i].fd; (*poll_list)[i].events = POLLIN; From 5c03e610d5aa5d101f2cebc2f0c1716aa5f85205 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 14:53:19 -0800 Subject: [PATCH 12/22] missing return! --- picoquic/sockloop.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index dea7179dd..efbf0b377 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -609,6 +609,8 @@ int picoquic_packet_loop_set_fds(struct pollfd ** poll_list, int * nb_pollfd, } DBG_PRINTF("Initialized %zu bytes for poll_list", pollfd_size); } + + return ret; } From 6178791895a35e0be66b3f338acfcb3ee0c50ba6 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 15:03:42 -0800 Subject: [PATCH 13/22] More debug print. --- picoquic/sockloop.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index efbf0b377..c049fad58 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -1147,6 +1147,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) send_port = new_ctx->n_port; nb_sockets_available++; if (nb_sockets < nb_sockets_available) { + DBG_PRINTF("new socket, nb = %d", nb_sockets_available); nb_sockets = nb_sockets_available; #ifndef _WINDOWS #ifdef PICOQUIC_USE_POLL @@ -1171,6 +1172,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) sock_ret = -1; sock_err = EIO; param->simulate_eio = 0; + DBG_PRINTF("Simulating EIO, send length = %zu", send_length); } else { sock_ret = picoquic_sendmsg(send_socket, @@ -1203,6 +1205,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) size_t packet_size = send_msg_size; while (packet_index < send_length) { + DBG_PRINTF("EIO, length= %zu/%zu", packet_index, send_length); if (packet_index + packet_size > send_length) { packet_size = send_length - packet_index; } @@ -1213,6 +1216,8 @@ void* picoquic_packet_loop_v3(void* v_ctx) packet_index += packet_size; } else { + DBG_PRINTF("Retry with packet size=%zu fails at index %zu, ret=%d, err=%d.", + packet_size, packet_index, sock_ret, sock_err); picoquic_log_app_message(last_cnx, "Retry with packet size=%zu fails at index %zu, ret=%d, err=%d.", packet_size, packet_index, sock_ret, sock_err); break; From 9708a47f89e452378e4304cc0e9fe65b40c04910 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 15:23:46 -0800 Subject: [PATCH 14/22] manage nb available sockets --- picoquic/sockloop.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index c049fad58..b3caa5b1e 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -871,6 +871,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifdef PICOQUIC_USE_POLL struct pollfd * poll_list = NULL; int nb_pollfd = 0; + int nb_pollfd_available = 0; #endif #endif @@ -905,6 +906,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifdef PICOQUIC_USE_POLL if (ret == 0) { ret = picoquic_packet_loop_set_fds(&poll_list, & nb_pollfd, s_ctx, nb_sockets, thread_ctx); + nb_pollfd_available = nb_pollfd; } #endif #endif @@ -973,7 +975,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) loop_immediate = 0; /* Remember the time before the select call, so it duration be monitored */ previous_time = current_time; - /* Initialize the dest addr family to UNSPEC yo handle systems that cannot set it. */ + /* Initialize the dest addr family to UNSPEC to handle systems that cannot set it. */ addr_to.ss_family = AF_UNSPEC; #ifdef _WINDOWS bytes_recv = picoquic_packet_loop_wait(s_ctx, nb_sockets_available, @@ -981,6 +983,20 @@ void* picoquic_packet_loop_v3(void* v_ctx) delta_t, &is_wake_up_event, thread_ctx, &socket_rank); #else #ifdef PICOQUIC_USE_POLL + +#ifndef _WINDOWS +#ifdef PICOQUIC_USE_POLL + if (ret == 0) { + if (nb_pollfd_available != (nb_sockets_available + (thread_ctx->wake_up_defined) ? 1 : 0)) { + ret = picoquic_packet_loop_set_fds(&poll_list, &nb_pollfd, s_ctx, nb_sockets_available, thread_ctx); + nb_pollfd_available = nb_pollfd; + } + if (ret == 0) { + ret = picoquic_packet_loop_set_fds(&poll_list, &nb_pollfd, s_ctx, nb_sockets, thread_ctx); + } + } +#endif +#endif bytes_recv = picoquic_packet_loop_poll( s_ctx, nb_sockets_available, poll_list, nb_pollfd, @@ -1075,6 +1091,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) * memorized for that path. */ nb_sockets_available = nb_sockets / 2; + } ret = 0; } @@ -1154,6 +1171,9 @@ void* picoquic_packet_loop_v3(void* v_ctx) if ((ret = picoquic_packet_loop_set_fds(&poll_list, &nb_pollfd, s_ctx, nb_sockets, thread_ctx)) != 0){ break; } + else { + nb_pollfd_available = nb_pollfd; + } #endif #endif } From db7121d4e4b84db02e02da792d0fb1be690b39ba Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 15:34:14 -0800 Subject: [PATCH 15/22] wakeup socket first --- picoquic/sockloop.c | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index b3caa5b1e..76401eaeb 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -596,16 +596,20 @@ int picoquic_packet_loop_set_fds(struct pollfd ** poll_list, int * nb_pollfd, } else { + int i_poll = 0; DBG_PRINTF("Allocated %zu bytes (%zu times %d) for poll_list (nb sockets: %d, wakeup: %d)", pollfd_size, sizeof(struct pollfd), *nb_pollfd, nb_sockets, (thread_ctx->wake_up_defined) ? 1 : 0); memset(*poll_list, 0, pollfd_size); - for (int i = 0; i < nb_sockets; i++) { - (*poll_list)[i].fd = (int)s_ctx[i].fd; - (*poll_list)[i].events = POLLIN; - } + if (thread_ctx->wake_up_defined) { - (*poll_list)[nb_sockets].fd = (int)thread_ctx->wake_up_pipe_fd[0]; - (*poll_list)[nb_sockets].events = POLLIN; + (*poll_list)[0].fd = (int)thread_ctx->wake_up_pipe_fd[0]; + (*poll_list)[0].events = POLLIN; + i_poll = 1; + } + + for (int i = 0; i < nb_sockets; i++) { + (*poll_list)[i + i_poll].fd = (int)s_ctx[i].fd; + (*poll_list)[i + i_poll].events = POLLIN; } DBG_PRINTF("Initialized %zu bytes for poll_list", pollfd_size); } @@ -618,7 +622,6 @@ int picoquic_packet_loop_poll( picoquic_socket_ctx_t* s_ctx, int nb_sockets, struct pollfd* poll_list, - int nb_pollfd, struct sockaddr_storage* addr_from, struct sockaddr_storage* addr_dest, int* dest_if, @@ -631,7 +634,8 @@ int picoquic_packet_loop_poll( { int delta_t_ms = (int)((delta_t + 999) / 1000); int bytes_recv = 0; - int ret_poll = poll(poll_list, nb_pollfd, delta_t_ms); + int i_poll = (thread_ctx->wake_up_defined) ? 1 : 0; + int ret_poll = poll(poll_list, nb_sockets + i_poll, delta_t_ms); if (received_ecn != NULL) { *received_ecn = 0; @@ -645,7 +649,7 @@ int picoquic_packet_loop_poll( else if (ret_poll > 0) { /* Check if the 'wake up' pipe is full. If it is, read the data on it, * set the is_wake_up_event flag, and ignore the other file descriptors. */ - if (thread_ctx->wake_up_defined && poll_list[nb_sockets].revents != 0) { + if (thread_ctx->wake_up_defined && poll_list[0].revents != 0) { /* Something was written on the "wakeup" pipe. Read it. */ uint8_t eventbuf[8]; int pipe_recv; @@ -663,7 +667,7 @@ int picoquic_packet_loop_poll( else { for (int i = 0; i < nb_sockets; i++) { - if (poll_list[i].revents != 0) { + if (poll_list[i+i_poll].revents != 0) { *socket_rank = i; bytes_recv = picoquic_recvmsg(s_ctx[i].fd, addr_from, addr_dest, dest_if, received_ecn, @@ -871,7 +875,6 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifdef PICOQUIC_USE_POLL struct pollfd * poll_list = NULL; int nb_pollfd = 0; - int nb_pollfd_available = 0; #endif #endif @@ -906,7 +909,6 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifdef PICOQUIC_USE_POLL if (ret == 0) { ret = picoquic_packet_loop_set_fds(&poll_list, & nb_pollfd, s_ctx, nb_sockets, thread_ctx); - nb_pollfd_available = nb_pollfd; } #endif #endif @@ -983,23 +985,9 @@ void* picoquic_packet_loop_v3(void* v_ctx) delta_t, &is_wake_up_event, thread_ctx, &socket_rank); #else #ifdef PICOQUIC_USE_POLL - -#ifndef _WINDOWS -#ifdef PICOQUIC_USE_POLL - if (ret == 0) { - if (nb_pollfd_available != (nb_sockets_available + (thread_ctx->wake_up_defined) ? 1 : 0)) { - ret = picoquic_packet_loop_set_fds(&poll_list, &nb_pollfd, s_ctx, nb_sockets_available, thread_ctx); - nb_pollfd_available = nb_pollfd; - } - if (ret == 0) { - ret = picoquic_packet_loop_set_fds(&poll_list, &nb_pollfd, s_ctx, nb_sockets, thread_ctx); - } - } -#endif -#endif bytes_recv = picoquic_packet_loop_poll( s_ctx, nb_sockets_available, - poll_list, nb_pollfd, + poll_list, & addr_from, & addr_to, & if_index_to, & received_ecn, buffer, sizeof(buffer), From d522eeded37fe8415b026e97b95da41e53dd1dea Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 15:35:19 -0800 Subject: [PATCH 16/22] remove unused line --- picoquic/sockloop.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 76401eaeb..f756dda50 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -1159,9 +1159,6 @@ void* picoquic_packet_loop_v3(void* v_ctx) if ((ret = picoquic_packet_loop_set_fds(&poll_list, &nb_pollfd, s_ctx, nb_sockets, thread_ctx)) != 0){ break; } - else { - nb_pollfd_available = nb_pollfd; - } #endif #endif } From 90bdb3f32dea08427fd19f291d176578ab33ec1d Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 17:35:52 -0800 Subject: [PATCH 17/22] One more printf --- picoquic/sockloop.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index f756dda50..3216334c5 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -985,6 +985,10 @@ void* picoquic_packet_loop_v3(void* v_ctx) delta_t, &is_wake_up_event, thread_ctx, &socket_rank); #else #ifdef PICOQUIC_USE_POLL + if (nb_pollfd < nb_sockets_available + (thread_ctx->wake_up_defined) ? 1 : 0) { + DBG_PRINTF("Overflow! nb_pollfd= %d, nb_socks= %d, nb_sockets_available= %d, wake_up: %d", + nb_pollfd, nb_socks, nb_sockets_available, (thread_ctx->wake_up_defined) ? 1 : 0); + } bytes_recv = picoquic_packet_loop_poll( s_ctx, nb_sockets_available, poll_list, @@ -1079,7 +1083,6 @@ void* picoquic_packet_loop_v3(void* v_ctx) * memorized for that path. */ nb_sockets_available = nb_sockets / 2; - } ret = 0; } From 66c5d03ef9e70aad4d23090fe159b616e982b5b5 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 17:36:54 -0800 Subject: [PATCH 18/22] And a typo --- picoquic/sockloop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 3216334c5..d03df8ff2 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -987,7 +987,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifdef PICOQUIC_USE_POLL if (nb_pollfd < nb_sockets_available + (thread_ctx->wake_up_defined) ? 1 : 0) { DBG_PRINTF("Overflow! nb_pollfd= %d, nb_socks= %d, nb_sockets_available= %d, wake_up: %d", - nb_pollfd, nb_socks, nb_sockets_available, (thread_ctx->wake_up_defined) ? 1 : 0); + nb_pollfd, nb_sockets, nb_sockets_available, (thread_ctx->wake_up_defined) ? 1 : 0); } bytes_recv = picoquic_packet_loop_poll( s_ctx, nb_sockets_available, From a60087232ab0c9c357d6fe1f22a47a4cbfb57da7 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 18:13:11 -0800 Subject: [PATCH 19/22] Some more checks. --- picoquic/picosocks.c | 2 +- picoquic/sockloop.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/picoquic/picosocks.c b/picoquic/picosocks.c index 27a65014d..594a39362 100644 --- a/picoquic/picosocks.c +++ b/picoquic/picosocks.c @@ -397,7 +397,7 @@ void picoquic_socks_cmsg_parse( } } #ifdef UDP_COALESCED_INFO - if (cmsg->cmsg_level == IPPROTO_UDP && + else if (cmsg->cmsg_level == IPPROTO_UDP && cmsg->cmsg_type == UDP_COALESCED_INFO) { if (cmsg->cmsg_len > 0) { if (udp_coalesced_size != NULL) { diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index d03df8ff2..5e6155c29 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -905,6 +905,10 @@ void* picoquic_packet_loop_v3(void* v_ctx) ret = loop_callback(quic, picoquic_packet_loop_alt_port, loop_callback_ctx, &alt_port); } } + if (param->extra_socket_required) { + DBG_PRINTF("Extra: %d, nb_sockets= %d, nb_sockets_available= %d, wake_up: %d", + param->extra_socket_required, nb_sockets, nb_sockets_available, (thread_ctx->wake_up_defined) ? 1 : 0); + } #ifndef _WINDOWS #ifdef PICOQUIC_USE_POLL if (ret == 0) { @@ -979,16 +983,16 @@ void* picoquic_packet_loop_v3(void* v_ctx) previous_time = current_time; /* Initialize the dest addr family to UNSPEC to handle systems that cannot set it. */ addr_to.ss_family = AF_UNSPEC; + if (nb_sockets < nb_sockets_available) { + DBG_PRINTF("Overflow! nb_sockets= %d, nb_sockets_available= %d, wake_up: %d", + nb_sockets, nb_sockets_available, (thread_ctx->wake_up_defined) ? 1 : 0); + } #ifdef _WINDOWS bytes_recv = picoquic_packet_loop_wait(s_ctx, nb_sockets_available, &addr_from, &addr_to, &if_index_to, &received_ecn, &received_buffer, delta_t, &is_wake_up_event, thread_ctx, &socket_rank); #else #ifdef PICOQUIC_USE_POLL - if (nb_pollfd < nb_sockets_available + (thread_ctx->wake_up_defined) ? 1 : 0) { - DBG_PRINTF("Overflow! nb_pollfd= %d, nb_socks= %d, nb_sockets_available= %d, wake_up: %d", - nb_pollfd, nb_sockets, nb_sockets_available, (thread_ctx->wake_up_defined) ? 1 : 0); - } bytes_recv = picoquic_packet_loop_poll( s_ctx, nb_sockets_available, poll_list, @@ -1053,8 +1057,6 @@ void* picoquic_packet_loop_v3(void* v_ctx) (struct sockaddr*)&addr_to, if_index_to, received_ecn, &last_cnx, current_time); #endif - - if (loop_callback != NULL) { size_t b_recvd = (size_t)bytes_recv; ret = loop_callback(quic, picoquic_packet_loop_after_receive, loop_callback_ctx, &b_recvd); From 39dc511597c2a9342e086b84c653c0d1674f0fa2 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 20:36:32 -0800 Subject: [PATCH 20/22] Use statis allocation for poll --- picoquic/sockloop.c | 69 +++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 5e6155c29..daeacdf67 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -578,43 +578,27 @@ int picoquic_packet_loop_wait(picoquic_socket_ctx_t* s_ctx, } #else #ifdef PICOQUIC_USE_POLL -int picoquic_packet_loop_set_fds(struct pollfd ** poll_list, int * nb_pollfd, +void picoquic_packet_loop_set_fds(struct pollfd * poll_list, picoquic_socket_ctx_t* s_ctx, int nb_sockets, picoquic_network_thread_ctx_t* thread_ctx) { - int ret = 0; - size_t pollfd_size; - if (*poll_list != NULL) { - free(*poll_list); + int nb_pollfd = nb_sockets + (thread_ctx->wake_up_defined) ? 1 : 0; + memset(poll_list, 0, sizeof(struct pollfd)* (PICOQUIC_PACKET_LOOP_SOCKETS_MAX+1)); + int i_poll = 0; + + if (thread_ctx->wake_up_defined) { + poll_list[0].fd = (int)thread_ctx->wake_up_pipe_fd[0]; + poll_list[0].events = POLLIN; + i_poll = 1; } - *nb_pollfd = nb_sockets + (thread_ctx->wake_up_defined) ? 1 : 0; - pollfd_size = sizeof(struct pollfd) * (*nb_pollfd); - *poll_list = (struct pollfd*)malloc(pollfd_size); - if (*poll_list == NULL) { - ret = PICOQUIC_ERROR_UNEXPECTED_ERROR; + for (int i = 0; i < nb_sockets && i < PICOQUIC_PACKET_LOOP_SOCKETS_MAX; i++, i_poll++) { + poll_list[i_poll].fd = (int)s_ctx[i].fd; + poll_list[i_poll].events = POLLIN; } - else - { - int i_poll = 0; - DBG_PRINTF("Allocated %zu bytes (%zu times %d) for poll_list (nb sockets: %d, wakeup: %d)", - pollfd_size, sizeof(struct pollfd), *nb_pollfd, nb_sockets, (thread_ctx->wake_up_defined) ? 1 : 0); - memset(*poll_list, 0, pollfd_size); - - if (thread_ctx->wake_up_defined) { - (*poll_list)[0].fd = (int)thread_ctx->wake_up_pipe_fd[0]; - (*poll_list)[0].events = POLLIN; - i_poll = 1; - } - - for (int i = 0; i < nb_sockets; i++) { - (*poll_list)[i + i_poll].fd = (int)s_ctx[i].fd; - (*poll_list)[i + i_poll].events = POLLIN; - } - DBG_PRINTF("Initialized %zu bytes for poll_list", pollfd_size); + for (; i_poll < PICOQUIC_PACKET_LOOP_SOCKETS_MAX + 1; i_poll++) { + poll_list[i_poll].fd = -1; } - - return ret; } @@ -858,7 +842,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) size_t* send_msg_ptr = NULL; int bytes_recv; picoquic_connection_id_t log_cid; - picoquic_socket_ctx_t s_ctx[4]; + picoquic_socket_ctx_t s_ctx[PICOQUIC_PACKET_LOOP_SOCKETS_MAX + 1]; int nb_sockets = 0; int nb_sockets_available = 0; picoquic_cnx_t* last_cnx = NULL; @@ -873,8 +857,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) (void)WSA_START(MAKEWORD(2, 2), &wsaData); #else #ifdef PICOQUIC_USE_POLL - struct pollfd * poll_list = NULL; - int nb_pollfd = 0; + struct pollfd poll_list[PICOQUIC_PACKET_LOOP_SOCKETS_MAX]; #endif #endif @@ -912,7 +895,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifndef _WINDOWS #ifdef PICOQUIC_USE_POLL if (ret == 0) { - ret = picoquic_packet_loop_set_fds(&poll_list, & nb_pollfd, s_ctx, nb_sockets, thread_ctx); + ret = picoquic_packet_loop_set_fds(poll_list, s_ctx, nb_sockets, thread_ctx); } #endif #endif @@ -983,10 +966,6 @@ void* picoquic_packet_loop_v3(void* v_ctx) previous_time = current_time; /* Initialize the dest addr family to UNSPEC to handle systems that cannot set it. */ addr_to.ss_family = AF_UNSPEC; - if (nb_sockets < nb_sockets_available) { - DBG_PRINTF("Overflow! nb_sockets= %d, nb_sockets_available= %d, wake_up: %d", - nb_sockets, nb_sockets_available, (thread_ctx->wake_up_defined) ? 1 : 0); - } #ifdef _WINDOWS bytes_recv = picoquic_packet_loop_wait(s_ctx, nb_sockets_available, &addr_from, &addr_to, &if_index_to, &received_ecn, &received_buffer, @@ -1085,6 +1064,11 @@ void* picoquic_packet_loop_v3(void* v_ctx) * memorized for that path. */ nb_sockets_available = nb_sockets / 2; +#ifndef _WINDOWS +#ifdef PICOQUIC_USE_POLL + picoquic_packet_loop_set_fds(poll_list, s_ctx, nb_sockets_available, thread_ctx); +#endif +#endif } ret = 0; } @@ -1161,9 +1145,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) nb_sockets = nb_sockets_available; #ifndef _WINDOWS #ifdef PICOQUIC_USE_POLL - if ((ret = picoquic_packet_loop_set_fds(&poll_list, &nb_pollfd, s_ctx, nb_sockets, thread_ctx)) != 0){ - break; - } + picoquic_packet_loop_set_fds(poll_list, s_ctx, nb_sockets_available, thread_ctx); #endif #endif } @@ -1276,11 +1258,6 @@ void* picoquic_packet_loop_v3(void* v_ctx) #ifdef _WINDOWS return (DWORD)ret; #else -#ifdef PICOQUIC_USE_POLL - if (poll_list != NULL) { - free(poll_list); - } -#endif if (thread_ctx->is_threaded) { pthread_exit((void*)&thread_ctx->return_code); } From 70fab3579461243fffbc80f32e5ea56056d0db76 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 20:38:04 -0800 Subject: [PATCH 21/22] Correct forgotten return --- picoquic/sockloop.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index daeacdf67..51e0eb467 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -888,14 +888,10 @@ void* picoquic_packet_loop_v3(void* v_ctx) ret = loop_callback(quic, picoquic_packet_loop_alt_port, loop_callback_ctx, &alt_port); } } - if (param->extra_socket_required) { - DBG_PRINTF("Extra: %d, nb_sockets= %d, nb_sockets_available= %d, wake_up: %d", - param->extra_socket_required, nb_sockets, nb_sockets_available, (thread_ctx->wake_up_defined) ? 1 : 0); - } #ifndef _WINDOWS #ifdef PICOQUIC_USE_POLL if (ret == 0) { - ret = picoquic_packet_loop_set_fds(poll_list, s_ctx, nb_sockets, thread_ctx); + picoquic_packet_loop_set_fds(poll_list, s_ctx, nb_sockets, thread_ctx); } #endif #endif From eb823a52cd74370f3d9fb343e2a7f6cf0ebf1f53 Mon Sep 17 00:00:00 2001 From: huitema Date: Thu, 18 Dec 2025 20:40:40 -0800 Subject: [PATCH 22/22] Oops, wrong size --- picoquic/sockloop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/picoquic/sockloop.c b/picoquic/sockloop.c index 51e0eb467..17cad330e 100644 --- a/picoquic/sockloop.c +++ b/picoquic/sockloop.c @@ -842,7 +842,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) size_t* send_msg_ptr = NULL; int bytes_recv; picoquic_connection_id_t log_cid; - picoquic_socket_ctx_t s_ctx[PICOQUIC_PACKET_LOOP_SOCKETS_MAX + 1]; + picoquic_socket_ctx_t s_ctx[PICOQUIC_PACKET_LOOP_SOCKETS_MAX]; int nb_sockets = 0; int nb_sockets_available = 0; picoquic_cnx_t* last_cnx = NULL; @@ -857,7 +857,7 @@ void* picoquic_packet_loop_v3(void* v_ctx) (void)WSA_START(MAKEWORD(2, 2), &wsaData); #else #ifdef PICOQUIC_USE_POLL - struct pollfd poll_list[PICOQUIC_PACKET_LOOP_SOCKETS_MAX]; + struct pollfd poll_list[PICOQUIC_PACKET_LOOP_SOCKETS_MAX + 1]; #endif #endif