mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 04:34:43 +04:00
[FL-3957] EventLoop unsubscribe fix (#4109)
* Fix memory leak during event loop unsubscription * Event better memory leak fix * unit test for the fix Co-authored-by: Georgii Surkov <georgii.surkov@outlook.com>
This commit is contained in:
@@ -446,6 +446,55 @@ static int32_t test_furi_event_loop_consumer(void* p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
FuriEventLoop* event_loop;
|
||||
FuriSemaphore* semaphore;
|
||||
size_t counter;
|
||||
} SelfUnsubTestTimerContext;
|
||||
|
||||
static void test_self_unsub_semaphore_callback(FuriEventLoopObject* object, void* context) {
|
||||
furi_event_loop_unsubscribe(context, object); // shouldn't crash here
|
||||
}
|
||||
|
||||
static void test_self_unsub_timer_callback(void* arg) {
|
||||
SelfUnsubTestTimerContext* context = arg;
|
||||
|
||||
if(context->counter == 0) {
|
||||
furi_semaphore_release(context->semaphore);
|
||||
} else if(context->counter == 1) {
|
||||
furi_event_loop_stop(context->event_loop);
|
||||
}
|
||||
|
||||
context->counter++;
|
||||
}
|
||||
|
||||
void test_furi_event_loop_self_unsubscribe(void) {
|
||||
FuriEventLoop* event_loop = furi_event_loop_alloc();
|
||||
|
||||
FuriSemaphore* semaphore = furi_semaphore_alloc(1, 0);
|
||||
furi_event_loop_subscribe_semaphore(
|
||||
event_loop,
|
||||
semaphore,
|
||||
FuriEventLoopEventIn,
|
||||
test_self_unsub_semaphore_callback,
|
||||
event_loop);
|
||||
|
||||
SelfUnsubTestTimerContext timer_context = {
|
||||
.event_loop = event_loop,
|
||||
.semaphore = semaphore,
|
||||
.counter = 0,
|
||||
};
|
||||
FuriEventLoopTimer* timer = furi_event_loop_timer_alloc(
|
||||
event_loop, test_self_unsub_timer_callback, FuriEventLoopTimerTypePeriodic, &timer_context);
|
||||
furi_event_loop_timer_start(timer, furi_ms_to_ticks(20));
|
||||
|
||||
furi_event_loop_run(event_loop);
|
||||
|
||||
furi_event_loop_timer_free(timer);
|
||||
furi_semaphore_free(semaphore);
|
||||
furi_event_loop_free(event_loop);
|
||||
}
|
||||
|
||||
void test_furi_event_loop(void) {
|
||||
TestFuriEventLoopData data = {};
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ void test_furi_concurrent_access(void);
|
||||
void test_furi_pubsub(void);
|
||||
void test_furi_memmgr(void);
|
||||
void test_furi_event_loop(void);
|
||||
void test_furi_event_loop_self_unsubscribe(void);
|
||||
void test_errno_saving(void);
|
||||
void test_furi_primitives(void);
|
||||
void test_stdin(void);
|
||||
@@ -46,6 +47,10 @@ MU_TEST(mu_test_furi_event_loop) {
|
||||
test_furi_event_loop();
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_furi_event_loop_self_unsubscribe) {
|
||||
test_furi_event_loop_self_unsubscribe();
|
||||
}
|
||||
|
||||
MU_TEST(mu_test_errno_saving) {
|
||||
test_errno_saving();
|
||||
}
|
||||
@@ -68,6 +73,7 @@ MU_TEST_SUITE(test_suite) {
|
||||
MU_RUN_TEST(mu_test_furi_pubsub);
|
||||
MU_RUN_TEST(mu_test_furi_memmgr);
|
||||
MU_RUN_TEST(mu_test_furi_event_loop);
|
||||
MU_RUN_TEST(mu_test_furi_event_loop_self_unsubscribe);
|
||||
MU_RUN_TEST(mu_test_stdio);
|
||||
MU_RUN_TEST(mu_test_errno_saving);
|
||||
MU_RUN_TEST(mu_test_furi_primitives);
|
||||
|
||||
Reference in New Issue
Block a user