1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-06-26 20:57:48 +02:00

Fix race condition when window is closed with active notifications

A ToxWindow's notifications need to be halted before the window is freed
This commit is contained in:
jfreegman 2020-11-10 17:20:40 -05:00
parent 16bcb27ca7
commit 752fc6d619
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
4 changed files with 41 additions and 6 deletions

View File

@ -152,6 +152,7 @@ void kill_chat_window(ToxWindow *self, Tox *m)
free(statusbar); free(statusbar);
disable_chatwin(self->num); disable_chatwin(self->num);
kill_notifs(self->active_box);
del_window(self); del_window(self);
} }

View File

@ -116,6 +116,7 @@ static void kill_conference_window(ToxWindow *self)
free(ctx->log); free(ctx->log);
free(ctx); free(ctx);
free(self->help); free(self->help);
kill_notifs(self->active_box);
del_window(self); del_window(self);
} }

View File

@ -193,7 +193,7 @@ void graceful_clear(void)
while (1) { while (1) {
int i; int i;
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) { for (i = 0; i < ACTIVE_NOTIFS_MAX; ++i) {
if (actives[i].active) { if (actives[i].active) {
#ifdef BOX_NOTIFY #ifdef BOX_NOTIFY
@ -249,7 +249,7 @@ void *do_playing(void *_p)
bool test_active_notify = false; bool test_active_notify = false;
int i; int i;
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) { for (i = 0; i < ACTIVE_NOTIFS_MAX; ++i) {
if (actives[i].looping) { if (actives[i].looping) {
has_looping = true; has_looping = true;
@ -315,7 +315,7 @@ int play_source(uint32_t source, uint32_t buffer, bool looping)
{ {
int i = 0; 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) { if (i == ACTIVE_NOTIFS_MAX) {
return -1; /* Full */ return -1; /* Full */
@ -346,7 +346,7 @@ void *do_playing(void *_p)
int i; 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) { if (actives[i].box && time(NULL) >= actives[i].n_timeout) {
GError *ignore; GError *ignore;
notify_notification_close(actives[i].box, &ignore); notify_notification_close(actives[i].box, &ignore);
@ -372,7 +372,7 @@ void graceful_clear(void)
int i; int i;
control_lock(); control_lock();
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) { for (i = 0; i < ACTIVE_NOTIFS_MAX; ++i) {
if (actives[i].box) { if (actives[i].box) {
GError *ignore; GError *ignore;
notify_notification_close(actives[i].box, &ignore); notify_notification_close(actives[i].box, &ignore);
@ -388,8 +388,38 @@ void graceful_clear(void)
control_unlock(); control_unlock();
} }
#endif /* SOUND_NOTIFY */ #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 #ifdef SOUND_NOTIFY
int i = 0; int i = 0;
for (; i < SOUNDS_SIZE; i ++) { for (; i < SOUNDS_SIZE; ++i) {
free(Control.sounds[i]); free(Control.sounds[i]);
} }

View File

@ -62,6 +62,9 @@ typedef enum _Flags {
int init_notify(int login_cooldown, int notification_timeout); int init_notify(int login_cooldown, int notification_timeout);
void terminate_notify(void); 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_notify(ToxWindow *self, Notification notif, uint64_t flags, int *id_indicator);
int sound_notify2(ToxWindow *self, Notification notif, uint64_t flags, int id); int sound_notify2(ToxWindow *self, Notification notif, uint64_t flags, int id);