From 752fc6d61950bf13fa6a157a4525aeda74afbb0a Mon Sep 17 00:00:00 2001 From: jfreegman Date: Tue, 10 Nov 2020 17:20:40 -0500 Subject: [PATCH] Fix race condition when window is closed with active notifications A ToxWindow's notifications need to be halted before the window is freed --- src/chat.c | 1 + src/conference.c | 1 + src/notify.c | 42 ++++++++++++++++++++++++++++++++++++------ src/notify.h | 3 +++ 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/chat.c b/src/chat.c index 162d55e..0856eb9 100644 --- a/src/chat.c +++ b/src/chat.c @@ -152,6 +152,7 @@ void kill_chat_window(ToxWindow *self, Tox *m) free(statusbar); disable_chatwin(self->num); + kill_notifs(self->active_box); del_window(self); } diff --git a/src/conference.c b/src/conference.c index 09fd1c2..9ba81a1 100644 --- a/src/conference.c +++ b/src/conference.c @@ -116,6 +116,7 @@ static void kill_conference_window(ToxWindow *self) free(ctx->log); free(ctx); free(self->help); + kill_notifs(self->active_box); del_window(self); } diff --git a/src/notify.c b/src/notify.c index 47c4960..6e3acec 100644 --- a/src/notify.c +++ b/src/notify.c @@ -193,7 +193,7 @@ void graceful_clear(void) while (1) { int i; - for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) { + for (i = 0; i < ACTIVE_NOTIFS_MAX; ++i) { if (actives[i].active) { #ifdef BOX_NOTIFY @@ -249,7 +249,7 @@ void *do_playing(void *_p) bool test_active_notify = false; int i; - for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) { + for (i = 0; i < ACTIVE_NOTIFS_MAX; ++i) { if (actives[i].looping) { has_looping = true; @@ -315,7 +315,7 @@ int play_source(uint32_t source, uint32_t buffer, bool looping) { int i = 0; - for (; i < ACTIVE_NOTIFS_MAX && actives[i].active; i ++); + for (; i < ACTIVE_NOTIFS_MAX && actives[i].active; ++i); if (i == ACTIVE_NOTIFS_MAX) { return -1; /* Full */ @@ -346,7 +346,7 @@ void *do_playing(void *_p) int i; - for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) { + for (i = 0; i < ACTIVE_NOTIFS_MAX; ++i) { if (actives[i].box && time(NULL) >= actives[i].n_timeout) { GError *ignore; notify_notification_close(actives[i].box, &ignore); @@ -372,7 +372,7 @@ void graceful_clear(void) int i; control_lock(); - for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) { + for (i = 0; i < ACTIVE_NOTIFS_MAX; ++i) { if (actives[i].box) { GError *ignore; notify_notification_close(actives[i].box, &ignore); @@ -388,8 +388,38 @@ void graceful_clear(void) control_unlock(); } + #endif /* SOUND_NOTIFY */ +/* Kills all notifications for `id`. This must be called before freeing a ToxWindow. */ +void kill_notifs(int id) +{ + control_lock(); + + for (size_t i = 0; i < ACTIVE_NOTIFS_MAX; ++i) { + if (!actives[i].id_indicator) { + continue; + } + + if (*actives[i].id_indicator == id) { +#ifdef BOX_NOTIFY + + if (actives[i].box) { + GError *ignore; + notify_notification_close(actives[i].box, &ignore); + } + +#endif // BOX_NOTIFY + + actives[i] = (struct _ActiveNotifications) { + 0 + }; + } + } + + control_unlock(); +} + /**********************************************************************************/ /**********************************************************************************/ /**********************************************************************************/ @@ -450,7 +480,7 @@ void terminate_notify(void) #ifdef SOUND_NOTIFY int i = 0; - for (; i < SOUNDS_SIZE; i ++) { + for (; i < SOUNDS_SIZE; ++i) { free(Control.sounds[i]); } diff --git a/src/notify.h b/src/notify.h index 3b29fe6..3adba0f 100644 --- a/src/notify.h +++ b/src/notify.h @@ -62,6 +62,9 @@ typedef enum _Flags { int init_notify(int login_cooldown, int notification_timeout); void terminate_notify(void); +/* Kills all notifications for `id`. This must be called before freeing a ToxWindow. */ +void kill_notifs(int id); + int sound_notify(ToxWindow *self, Notification notif, uint64_t flags, int *id_indicator); int sound_notify2(ToxWindow *self, Notification notif, uint64_t flags, int id);