@@ -103,48 +103,63 @@ static inline bool _init_async_event_queue(){
103
103
return true ;
104
104
}
105
105
106
- static inline bool _send_async_event (lwip_event_packet_t ** e ){
107
- return _async_queue && xQueueSend (_async_queue, e , portMAX_DELAY) == pdPASS;
106
+ static inline bool _send_async_event (lwip_event_packet_t ** e_buf ){
107
+ return _async_queue && xQueueSend (_async_queue, e_buf , portMAX_DELAY) == pdPASS;
108
108
}
109
109
110
- static inline bool _prepend_async_event (lwip_event_packet_t ** e ){
111
- return _async_queue && xQueueSendToFront (_async_queue, e , portMAX_DELAY) == pdPASS;
110
+ static inline bool _prepend_async_event (lwip_event_packet_t ** e_buf ){
111
+ return _async_queue && xQueueSendToFront (_async_queue, e_buf , portMAX_DELAY) == pdPASS;
112
112
}
113
113
114
- static inline bool _get_async_event (lwip_event_packet_t ** e ){
115
- return _async_queue && xQueueReceive (_async_queue, e , portMAX_DELAY) == pdPASS;
114
+ static inline bool _get_async_event (lwip_event_packet_t ** e_buf ){
115
+ return _async_queue && xQueueReceive (_async_queue, e_buf , portMAX_DELAY) == pdPASS;
116
116
}
117
117
118
- static bool _remove_events_with_arg (void * arg){
118
+ // Removes (from the _async_queue) and also frees the associated memory of
119
+ // any event packages where the void *arg struct member is identical
120
+ // to the one of the input event packet by pointer stored in e_buf.
121
+ //
122
+ // This always iterates over the whole queue and adds everything back
123
+ // in the same order except for the removed elements
124
+ //
125
+ // The event package pointer in the input e_buf is NULLed and can/must be freed later
126
+ static bool _remove_events_with_arg (lwip_event_packet_t ** e_buf){
127
+ lwip_event_packet_t * packet_in = *e_buf;
119
128
lwip_event_packet_t * first_packet = NULL ;
120
129
lwip_event_packet_t * packet = NULL ;
121
130
122
- if (!_async_queue){
131
+ if (!_async_queue || !packet_in ){
123
132
return false ;
133
+ } else {
134
+ // Nullifying the event packet pointer so that it is safe to call
135
+ // free() later even if there are duplicate events in the queue
136
+ *e_buf = NULL ;
124
137
}
125
- // figure out which is the first packet so we can keep the order
138
+ int arg_in = reinterpret_cast <int >(packet_in->arg );
139
+ // Figure out which is the first packet so we can keep the order
126
140
while (!first_packet){
127
141
if (xQueueReceive (_async_queue, &first_packet, 0 ) != pdPASS){
128
142
return false ;
129
143
}
130
- // discard packet if matching
131
- if ((int )first_packet->arg == (int )arg){
144
+ // Packet was already removed from the queue, so if matching, it is
145
+ // not added back but discarded, and also its memory is freed.
146
+ if (reinterpret_cast <int >(first_packet->arg ) == arg_in){
132
147
free (first_packet);
133
148
first_packet = NULL ;
134
- // return first packet to the back of the queue
135
- } else if (xQueueSend (_async_queue, &first_packet, portMAX_DELAY) != pdPASS){
149
+ // If not matching, return packet back to the end of the queue and continue
150
+ } else if (xQueueSendToBack (_async_queue, &first_packet, portMAX_DELAY) != pdPASS){
136
151
return false ;
137
152
}
138
153
}
139
-
154
+ // Same for all othes until arriving back again at the front (first_packet)
140
155
while (xQueuePeek (_async_queue, &packet, 0 ) == pdPASS && packet != first_packet){
141
156
if (xQueueReceive (_async_queue, &packet, 0 ) != pdPASS){
142
157
return false ;
143
158
}
144
- if (( int ) packet->arg == ( int )arg ){
159
+ if (reinterpret_cast < int >( packet->arg ) == arg_in ){
145
160
free (packet);
146
161
packet = NULL ;
147
- } else if (xQueueSend (_async_queue, &packet, portMAX_DELAY) != pdPASS){
162
+ } else if (xQueueSendToBack (_async_queue, &packet, portMAX_DELAY) != pdPASS){
148
163
return false ;
149
164
}
150
165
}
@@ -156,7 +171,7 @@ static void _handle_async_event(lwip_event_packet_t * e){
156
171
// do nothing when arg is NULL
157
172
// ets_printf("event arg == NULL: 0x%08x\n", e->recv.pcb);
158
173
} else if (e->event == LWIP_TCP_CLEAR){
159
- _remove_events_with_arg (e-> arg );
174
+ _remove_events_with_arg (&e );
160
175
} else if (e->event == LWIP_TCP_RECV){
161
176
// ets_printf("-R: 0x%08x\n", e->recv.pcb);
162
177
AsyncClient::_s_recv (e->arg , e->recv .pcb , e->recv .pb , e->recv .err );
@@ -182,7 +197,7 @@ static void _handle_async_event(lwip_event_packet_t * e){
182
197
// ets_printf("D: 0x%08x %s = %s\n", e->arg, e->dns.name, ipaddr_ntoa(&e->dns.addr));
183
198
AsyncClient::_s_dns_found (e->dns .name , &e->dns .addr , e->arg );
184
199
}
185
- free (( void *)(e) );
200
+ free (e );
186
201
}
187
202
188
203
static void _async_service_task (void *pvParameters){
0 commit comments