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 /** User Datagram Protocol (UDP) */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 #define NX_SOURCE_CODE 23 24 25 /* Include necessary system files. */ 26 27 #include "nx_api.h" 28 #include "tx_thread.h" 29 #include "nx_udp.h" 30 31 32 /**************************************************************************/ 33 /* */ 34 /* FUNCTION RELEASE */ 35 /* */ 36 /* _nx_udp_bind_cleanup PORTABLE C */ 37 /* 6.1 */ 38 /* AUTHOR */ 39 /* */ 40 /* Yuxin Zhou, Microsoft Corporation */ 41 /* */ 42 /* DESCRIPTION */ 43 /* */ 44 /* This function processes UDP bind timeout and thread terminate */ 45 /* actions that require the UDP socket data structures to be cleaned */ 46 /* up. */ 47 /* */ 48 /* INPUT */ 49 /* */ 50 /* thread_ptr Pointer to suspended thread's */ 51 /* control block */ 52 /* */ 53 /* OUTPUT */ 54 /* */ 55 /* None */ 56 /* */ 57 /* CALLS */ 58 /* */ 59 /* _tx_thread_system_resume Resume thread service */ 60 /* */ 61 /* CALLED BY */ 62 /* */ 63 /* _nx_udp_socket_unbind Unbind processing */ 64 /* _tx_thread_timeout Thread timeout processing */ 65 /* _tx_thread_terminate Thread terminate processing */ 66 /* */ 67 /* RELEASE HISTORY */ 68 /* */ 69 /* DATE NAME DESCRIPTION */ 70 /* */ 71 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ 72 /* 09-30-2020 Yuxin Zhou Modified comment(s), */ 73 /* resulting in version 6.1 */ 74 /* */ 75 /**************************************************************************/ _nx_udp_bind_cleanup(TX_THREAD * thread_ptr NX_CLEANUP_PARAMETER)76VOID _nx_udp_bind_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER) 77 { 78 79 TX_INTERRUPT_SAVE_AREA 80 81 NX_UDP_SOCKET *socket_ptr; /* Working socket pointer */ 82 NX_UDP_SOCKET *owning_socket_ptr; /* Socket owning the port */ 83 84 NX_CLEANUP_EXTENSION 85 86 /* Setup pointer to UDP socket control block. */ 87 socket_ptr = (NX_UDP_SOCKET *)thread_ptr -> tx_thread_suspend_control_block; 88 89 /* Disable interrupts to remove the suspended thread from the UDP socket. */ 90 TX_DISABLE 91 92 /* Determine if the cleanup is still required. */ 93 if ((thread_ptr -> tx_thread_suspend_cleanup) && (socket_ptr) && 94 (socket_ptr -> nx_udp_socket_id == NX_UDP_ID)) 95 { 96 97 /* Yes, we still have thread suspension! */ 98 99 /* Clear the socket bind in progress flag. */ 100 socket_ptr -> nx_udp_socket_bind_in_progress = NX_NULL; 101 102 /* Clear the suspension cleanup flag. */ 103 thread_ptr -> tx_thread_suspend_cleanup = TX_NULL; 104 105 /* Pickup the socket owning the port. This pointer was 106 saved in the bind processing prior to suspension. */ 107 owning_socket_ptr = socket_ptr -> nx_udp_socket_bound_previous; 108 109 /* Remove the suspended thread from the list. */ 110 111 /* See if this is the only suspended thread on the list. */ 112 if (thread_ptr == thread_ptr -> tx_thread_suspended_next) 113 { 114 115 /* Yes, the only suspended thread. */ 116 117 /* Update the head pointer. */ 118 owning_socket_ptr -> nx_udp_socket_bind_suspension_list = NX_NULL; 119 } 120 else 121 { 122 123 /* At least one more thread is on the same suspension list. */ 124 125 /* Update the list head pointer. */ 126 owning_socket_ptr -> nx_udp_socket_bind_suspension_list = thread_ptr -> tx_thread_suspended_next; 127 128 /* Update the links of the adjacent threads. */ 129 (thread_ptr -> tx_thread_suspended_next) -> tx_thread_suspended_previous = 130 thread_ptr -> tx_thread_suspended_previous; 131 (thread_ptr -> tx_thread_suspended_previous) -> tx_thread_suspended_next = 132 thread_ptr -> tx_thread_suspended_next; 133 } 134 135 /* Decrement the suspension count. */ 136 owning_socket_ptr -> nx_udp_socket_bind_suspended_count--; 137 138 /* Now we need to determine if this cleanup is from a terminate, timeout, 139 or from a wait abort. */ 140 if (thread_ptr -> tx_thread_state == TX_TCP_IP) 141 { 142 143 /* Thread still suspended on the UDP socket. Setup return error status and 144 resume the thread. */ 145 146 /* Setup return status. */ 147 thread_ptr -> tx_thread_suspend_status = NX_PORT_UNAVAILABLE; 148 149 /* Temporarily disable preemption. */ 150 _tx_thread_preempt_disable++; 151 152 /* Restore interrupts. */ 153 TX_RESTORE 154 155 /* Resume the thread! Check for preemption even though we are executing 156 from the system timer thread right now which normally executes at the 157 highest priority. */ 158 _tx_thread_system_resume(thread_ptr); 159 160 /* Finished, just return. */ 161 return; 162 } 163 } 164 165 /* Restore interrupts. */ 166 TX_RESTORE 167 } 168 169