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 "tx_thread.h"
29 #include "tx_timer.h"
30 #include "nx_ip.h"
31 #include "nx_tcp.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _nx_tcp_receive_cleanup PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* Yuxin Zhou, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function processes TCP receive timeout and thread terminate */
47 /* actions that require the TCP socket data structures to be cleaned */
48 /* up. */
49 /* */
50 /* INPUT */
51 /* */
52 /* thread_ptr Pointer to suspended thread's */
53 /* control block */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* None */
58 /* */
59 /* CALLS */
60 /* */
61 /* tx_event_flags_set Set event flag */
62 /* _tx_thread_system_resume Resume thread service */
63 /* */
64 /* CALLED BY */
65 /* */
66 /* _nx_tcp_deferred_cleanup_check Deferred cleanup processing */
67 /* _nx_tcp_socket_connection_reset Socket reset connection */
68 /* _nx_tcp_socket_disconnect Socket disconnect */
69 /* _tx_thread_timeout Thread timeout processing */
70 /* _tx_thread_terminate Thread terminate processing */
71 /* */
72 /* RELEASE HISTORY */
73 /* */
74 /* DATE NAME DESCRIPTION */
75 /* */
76 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
77 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
78 /* resulting in version 6.1 */
79 /* */
80 /**************************************************************************/
_nx_tcp_receive_cleanup(TX_THREAD * thread_ptr NX_CLEANUP_PARAMETER)81 VOID _nx_tcp_receive_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER)
82 {
83
84 TX_INTERRUPT_SAVE_AREA
85
86 NX_IP *ip_ptr;
87 NX_TCP_SOCKET *socket_ptr; /* Working socket pointer */
88
89 NX_CLEANUP_EXTENSION
90
91 /* Disable interrupts. */
92 TX_DISABLE
93
94 /* Setup pointer to TCP socket control block. */
95 socket_ptr = (NX_TCP_SOCKET *)thread_ptr -> tx_thread_suspend_control_block;
96
97 /* Determine if the socket pointer is valid. */
98 if ((!socket_ptr) || (socket_ptr -> nx_tcp_socket_id != NX_TCP_ID))
99 {
100
101 /* Restore interrupts. */
102 TX_RESTORE
103
104 return;
105 }
106
107 /* Determine if the cleanup is still required. */
108 if (!(thread_ptr -> tx_thread_suspend_cleanup))
109 {
110
111 /* Restore interrupts. */
112 TX_RESTORE
113
114 return;
115 }
116
117 /* Determine if the caller is an ISR or the system timer thread. */
118 #ifndef TX_TIMER_PROCESS_IN_ISR
119 if ((TX_THREAD_GET_SYSTEM_STATE()) || (_tx_thread_current_ptr == &_tx_timer_thread))
120 #else
121 if (TX_THREAD_GET_SYSTEM_STATE())
122 #endif
123 {
124
125 /* Yes, defer the processing to the NetX IP thread. */
126
127 /* Yes, change the suspend cleanup routine to indicate the cleanup is deferred. */
128 thread_ptr -> tx_thread_suspend_cleanup = _nx_tcp_cleanup_deferred;
129
130 /* Pickup the IP pointer. */
131 ip_ptr = socket_ptr -> nx_tcp_socket_ip_ptr;
132
133 /* Restore interrupts. */
134 TX_RESTORE
135
136 /* Set the deferred cleanup flag for the IP thread. */
137 tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_TCP_CLEANUP_DEFERRED, TX_OR);
138
139 /* Return to caller. */
140 return;
141 }
142 else
143 {
144
145 /* Yes, we still have thread suspension! */
146
147 /* Clear the suspension cleanup flag. */
148 thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
149
150 /* Remove the suspended thread from the list. */
151
152 /* See if this is the only suspended thread on the list. */
153 if (thread_ptr == thread_ptr -> tx_thread_suspended_next)
154 {
155
156 /* Yes, the only suspended thread. */
157
158 /* Update the head pointer. */
159 socket_ptr -> nx_tcp_socket_receive_suspension_list = NX_NULL;
160 }
161 else
162 {
163
164 /* At least one more thread is on the same suspension list. */
165
166 /* Update the list head pointer. */
167 socket_ptr -> nx_tcp_socket_receive_suspension_list = thread_ptr -> tx_thread_suspended_next;
168
169 /* Update the links of the adjacent threads. */
170 (thread_ptr -> tx_thread_suspended_next) -> tx_thread_suspended_previous =
171 thread_ptr -> tx_thread_suspended_previous;
172 (thread_ptr -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
173 thread_ptr -> tx_thread_suspended_next;
174 }
175
176 /* Decrement the suspension count. */
177 socket_ptr -> nx_tcp_socket_receive_suspended_count--;
178
179 /* Now we need to determine if this cleanup is from a terminate, timeout,
180 or from a wait abort. */
181 if (thread_ptr -> tx_thread_state == TX_TCP_IP)
182 {
183
184 /* Thread still suspended on the TCP socket. Setup return error status and
185 resume the thread. */
186
187 /* Determine which receive error is present. */
188 if (socket_ptr -> nx_tcp_socket_state != NX_TCP_ESTABLISHED)
189 {
190
191 /* This socket is no longer connected. */
192 thread_ptr -> tx_thread_suspend_status = NX_NOT_CONNECTED;
193 }
194 else
195 {
196
197 /* Setup return status. */
198 thread_ptr -> tx_thread_suspend_status = NX_NO_PACKET;
199 }
200
201 /* Temporarily disable preemption. */
202 _tx_thread_preempt_disable++;
203
204 /* Restore interrupts. */
205 TX_RESTORE
206
207 /* Resume the thread! Check for preemption even though we are executing
208 from the system timer thread right now which normally executes at the
209 highest priority. */
210 _tx_thread_system_resume(thread_ptr);
211
212 /* Finished, just return. */
213 return;
214 }
215 }
216
217 /* Restore interrupts. */
218 TX_RESTORE
219 }
220
221