Skip to content

Commit

Permalink
Fix race condition when window is closed with active notifications
Browse files Browse the repository at this point in the history
A ToxWindow's notifications need to be halted before the window is freed
  • Loading branch information
JFreegman committed Nov 10, 2020
1 parent 16bcb27 commit 3957507
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/chat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
31 changes: 25 additions & 6 deletions src/notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -388,8 +388,27 @@ 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 == NULL) {
continue;
}

if (*actives[i].id_indicator == id) {
memset(&actives[i], 0, sizeof(struct _ActiveNotifications));
}
}

control_unlock();
}

/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
Expand Down Expand Up @@ -450,7 +469,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]);
}

Expand Down
3 changes: 3 additions & 0 deletions src/notify.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 3957507

Please sign in to comment.