Skip to content

Commit 859d18a

Browse files
committed
fix(esp_wifi): Fixed some concurrency issues in eloop deinit
1 parent bfc86f6 commit 859d18a

File tree

1 file changed

+34
-14
lines changed
  • components/wpa_supplicant/port

1 file changed

+34
-14
lines changed

components/wpa_supplicant/port/eloop.c

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "eloop.h"
1919
#include "esp_wifi_driver.h"
2020
#include "rom/ets_sys.h"
21+
#include <stdatomic.h>
2122

2223
bool current_task_is_wifi_task(void);
2324

@@ -39,7 +40,8 @@ struct eloop_timeout {
3940
struct eloop_data {
4041
struct dl_list timeout;
4142
ETSTimer eloop_timer;
42-
bool eloop_started;
43+
atomic_bool eloop_started;
44+
atomic_bool timeout_running;
4345
void *eloop_semph;
4446
};
4547

@@ -80,7 +82,8 @@ int eloop_init(void)
8082
wpa_printf(MSG_ERROR, "failed to create eloop data loop");
8183
return -1;
8284
}
83-
eloop.eloop_started = true;
85+
atomic_store(&eloop.eloop_started, true);
86+
atomic_store(&eloop.timeout_running, false);
8487

8588
return 0;
8689
}
@@ -101,6 +104,9 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
101104
int count = 0;
102105
#endif
103106

107+
if (!atomic_load(&eloop.eloop_started)) {
108+
return -1;
109+
}
104110
timeout = os_zalloc(sizeof(*timeout));
105111
if (timeout == NULL) {
106112
return -1;
@@ -188,6 +194,10 @@ int eloop_register_timeout_blocking(eloop_blocking_timeout_handler handler,
188194
assert(false);
189195
return -1;
190196
}
197+
198+
if (!atomic_load(&eloop.eloop_started)) {
199+
return -1;
200+
}
191201
timeout = os_zalloc(sizeof(*timeout));
192202
if (timeout == NULL) {
193203
return -1;
@@ -429,6 +439,11 @@ void eloop_run(void)
429439
{
430440
struct os_reltime tv, now;
431441

442+
if (!atomic_load(&eloop.eloop_started)) {
443+
return;
444+
}
445+
atomic_store(&eloop.timeout_running, true);
446+
432447
while (!dl_list_empty(&eloop.timeout)) {
433448
struct eloop_timeout *timeout;
434449

@@ -446,15 +461,7 @@ void eloop_run(void)
446461
os_timer_arm(&eloop.eloop_timer, ms, 0);
447462
ELOOP_UNLOCK();
448463
goto out;
449-
}
450-
}
451-
452-
/* check if some registered timeouts have occurred */
453-
timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
454-
list);
455-
if (timeout) {
456-
os_get_reltime(&now);
457-
if (!os_reltime_before(&now, &timeout->time)) {
464+
} else {
458465
void *eloop_data = timeout->eloop_data;
459466
void *user_data = timeout->user_data;
460467
void *sync_semaphr = timeout->sync_semph;
@@ -491,20 +498,28 @@ void eloop_run(void)
491498
}
492499
}
493500
out:
501+
atomic_store(&eloop.timeout_running, false);
494502
return;
495503
}
496504

497505
void eloop_destroy(void)
498506
{
499507
struct eloop_timeout *timeout, *prev;
500-
struct os_reltime now;
501508

502-
if (!eloop.eloop_started) {
509+
if (!atomic_load(&eloop.eloop_started)) {
503510
return;
504511
}
505-
os_get_reltime(&now);
512+
513+
atomic_store(&eloop.eloop_started, false);
514+
515+
while (atomic_load(&eloop.timeout_running)) {
516+
vTaskDelay(100 / portTICK_PERIOD_MS); // Yield CPU
517+
}
506518
dl_list_for_each_safe(timeout, prev, &eloop.timeout,
507519
struct eloop_timeout, list) {
520+
#ifdef ELOOP_DEBUG
521+
struct os_reltime now;
522+
os_get_reltime(&now);
508523
int sec, usec;
509524
sec = timeout->time.sec - now.sec;
510525
usec = timeout->time.usec - now.usec;
@@ -516,12 +531,17 @@ void eloop_destroy(void)
516531
"eloop_data=%p user_data=%p handler=%p",
517532
sec, usec, timeout->eloop_data, timeout->user_data,
518533
timeout->handler);
534+
#endif
519535
eloop_remove_timeout(timeout);
520536
}
521537
if (eloop_data_lock) {
522538
os_mutex_delete(eloop_data_lock);
523539
eloop_data_lock = NULL;
524540
}
541+
if (eloop.eloop_semph) {
542+
os_semphr_delete(eloop.eloop_semph);
543+
eloop.eloop_semph = NULL;
544+
}
525545
os_timer_disarm(&eloop.eloop_timer);
526546
os_timer_done(&eloop.eloop_timer);
527547
os_memset(&eloop, 0, sizeof(eloop));

0 commit comments

Comments
 (0)