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