1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12 /**************************************************************************/ 13 /**************************************************************************/ 14 /** */ 15 /** NetX Component */ 16 /** */ 17 /** Transmission Control Protocol (TCP) */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 #define NX_SOURCE_CODE 23 24 25 /* Include necessary system files. */ 26 27 #include "nx_api.h" 28 #include "nx_ip.h" 29 #include "nx_tcp.h" 30 31 32 /**************************************************************************/ 33 /* */ 34 /* FUNCTION RELEASE */ 35 /* */ 36 /* _nx_tcp_deferred_cleanup_check PORTABLE C */ 37 /* 6.1 */ 38 /* AUTHOR */ 39 /* */ 40 /* Yuxin Zhou, Microsoft Corporation */ 41 /* */ 42 /* DESCRIPTION */ 43 /* */ 44 /* This function checks for deferred cleanup processing, which is the */ 45 /* case for all TCP socket timeout processing. This is done so that */ 46 /* mutex protection can be obtained prior to processing the timeout. */ 47 /* */ 48 /* INPUT */ 49 /* */ 50 /* ip_ptr Pointer to IP control block */ 51 /* */ 52 /* OUTPUT */ 53 /* */ 54 /* None */ 55 /* */ 56 /* CALLS */ 57 /* */ 58 /* _nx_tcp_client_bind_cleanup Bind cleanup */ 59 /* _nx_tcp_connect_cleanup Connect cleanup */ 60 /* _nx_tcp_disconnect_cleanup Disconnect cleanup */ 61 /* _nx_tcp_receive_cleanup Receive cleanup */ 62 /* _nx_tcp_transmit_cleanup Transmit cleanup */ 63 /* */ 64 /* CALLED BY */ 65 /* */ 66 /* _nx_ip_thread_entry IP helper thread */ 67 /* */ 68 /* RELEASE HISTORY */ 69 /* */ 70 /* DATE NAME DESCRIPTION */ 71 /* */ 72 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ 73 /* 09-30-2020 Yuxin Zhou Modified comment(s), */ 74 /* resulting in version 6.1 */ 75 /* */ 76 /**************************************************************************/ _nx_tcp_deferred_cleanup_check(NX_IP * ip_ptr)77VOID _nx_tcp_deferred_cleanup_check(NX_IP *ip_ptr) 78 { 79 80 ULONG created_sockets; 81 ULONG suspended_threads; 82 NX_TCP_SOCKET *socket_ptr; 83 TX_THREAD *thread_ptr; 84 85 86 /* Pickup the first socket and the created count. */ 87 socket_ptr = ip_ptr -> nx_ip_tcp_created_sockets_ptr; 88 created_sockets = ip_ptr -> nx_ip_tcp_created_sockets_count; 89 90 /* Loop through all created TCP sockets on the IP instance. */ 91 while (created_sockets--) 92 { 93 94 /* Check the socket for deferred bind cleanup. */ 95 suspended_threads = socket_ptr -> nx_tcp_socket_bind_suspended_count; 96 if (suspended_threads) 97 { 98 99 /* Pickup the socket pointer. */ 100 thread_ptr = socket_ptr -> nx_tcp_socket_bind_suspension_list; 101 102 /* Loop through the suspended threads for the bind operation to determine if there 103 is a timeout. */ 104 do 105 { 106 107 /* Determine if this thread has deferred the timeout processing. */ 108 if (thread_ptr -> tx_thread_suspend_cleanup == _nx_tcp_cleanup_deferred) 109 { 110 111 /* Yes, call the cleanup routine again! */ 112 _nx_tcp_client_bind_cleanup(thread_ptr NX_CLEANUP_ARGUMENT); 113 } 114 115 /* Move to next suspended thread. */ 116 thread_ptr = thread_ptr -> tx_thread_suspended_next; 117 } while (--suspended_threads); 118 } 119 120 /* Check the socket for deferred connect cleanup. */ 121 thread_ptr = socket_ptr -> nx_tcp_socket_connect_suspended_thread; 122 if (thread_ptr) 123 { 124 125 /* Determine if this thread has deferred the timeout processing. */ 126 if (thread_ptr -> tx_thread_suspend_cleanup == _nx_tcp_cleanup_deferred) 127 { 128 129 /* Yes, call the cleanup routine again! */ 130 _nx_tcp_connect_cleanup(thread_ptr NX_CLEANUP_ARGUMENT); 131 } 132 } 133 134 /* Check the socket for deferred disconnect cleanup. */ 135 thread_ptr = socket_ptr -> nx_tcp_socket_disconnect_suspended_thread; 136 if (thread_ptr) 137 { 138 139 /* Determine if this thread has deferred the timeout processing. */ 140 if (thread_ptr -> tx_thread_suspend_cleanup == _nx_tcp_cleanup_deferred) 141 { 142 143 /* Yes, call the cleanup routine again! */ 144 _nx_tcp_disconnect_cleanup(thread_ptr NX_CLEANUP_ARGUMENT); 145 } 146 } 147 148 /* Check the socket for deferred receive cleanup. */ 149 suspended_threads = socket_ptr -> nx_tcp_socket_receive_suspended_count; 150 if (suspended_threads) 151 { 152 153 /* Pickup the socket pointer. */ 154 thread_ptr = socket_ptr -> nx_tcp_socket_receive_suspension_list; 155 156 /* Loop through the suspended threads for the receive operation to determine if there 157 is a timeout. */ 158 do 159 { 160 161 /* Determine if this thread has deferred the timeout processing. */ 162 if (thread_ptr -> tx_thread_suspend_cleanup == _nx_tcp_cleanup_deferred) 163 { 164 165 /* Yes, call the cleanup routine again! */ 166 _nx_tcp_receive_cleanup(thread_ptr NX_CLEANUP_ARGUMENT); 167 } 168 169 /* Move to next suspended thread. */ 170 thread_ptr = thread_ptr -> tx_thread_suspended_next; 171 } while (--suspended_threads); 172 } 173 174 /* Check the socket for deferred transmit cleanup. */ 175 suspended_threads = socket_ptr -> nx_tcp_socket_transmit_suspended_count; 176 if (suspended_threads) 177 { 178 179 /* Pickup the socket pointer. */ 180 thread_ptr = socket_ptr -> nx_tcp_socket_transmit_suspension_list; 181 182 /* Loop through the suspended threads for the transmit operation to determine if there 183 is a timeout. */ 184 do 185 { 186 187 /* Determine if this thread has deferred the timeout processing. */ 188 if (thread_ptr -> tx_thread_suspend_cleanup == _nx_tcp_cleanup_deferred) 189 { 190 191 /* Yes, call the cleanup routine again! */ 192 _nx_tcp_transmit_cleanup(thread_ptr NX_CLEANUP_ARGUMENT); 193 } 194 195 /* Move to next suspended thread. */ 196 thread_ptr = thread_ptr -> tx_thread_suspended_next; 197 } while (--suspended_threads); 198 } 199 200 /* Move to next created TCP socket. */ 201 socket_ptr = socket_ptr -> nx_tcp_socket_created_next; 202 } 203 } 204 205