mirror of
https://github.com/yshui/picom.git
synced 2024-11-11 13:51:02 -05:00
Avoid using window id as identifier in finish_destroy_win
Under extreme race conditions (window A close at the same time as window B create), there can be multiple windows with same id in compton's window list. If at this point window B closes itself as well, finish_destroy_win might destroy a different window as what's passed to destroy_callback. This can be a problem because someone can still hold a reference to that window (e.g. 't' in paint_preprocess), and there's no way to clear that reference. If finish_destroy_win always destroy the same window passed to destroy_callback, this will not be a problem.
This commit is contained in:
parent
f4f39d1989
commit
cfdb946992
2 changed files with 9 additions and 8 deletions
|
@ -3206,17 +3206,18 @@ circulate_win(session_t *ps, XCirculateEvent *ce) {
|
|||
}
|
||||
|
||||
static void
|
||||
finish_destroy_win(session_t *ps, Window id) {
|
||||
win **prev = NULL, *w = NULL;
|
||||
finish_destroy_win(session_t *ps, win *w) {
|
||||
assert(w->destroyed);
|
||||
win **prev = NULL, *i = NULL;
|
||||
|
||||
#ifdef DEBUG_EVENTS
|
||||
printf_dbgf("(%#010lx): Starting...\n", id);
|
||||
printf_dbgf("(%#010lx): Starting...\n", w->id);
|
||||
#endif
|
||||
|
||||
for (prev = &ps->list; (w = *prev); prev = &w->next) {
|
||||
if (w->id == id && w->destroyed) {
|
||||
for (prev = &ps->list; (i = *prev); prev = &i->next) {
|
||||
if (w == i) {
|
||||
#ifdef DEBUG_EVENTS
|
||||
printf_dbgf("(%#010lx \"%s\"): %p\n", id, w->name, w);
|
||||
printf_dbgf("(%#010lx \"%s\"): %p\n", w->id, w->name, w);
|
||||
#endif
|
||||
|
||||
finish_unmap_win(ps, w);
|
||||
|
@ -3242,7 +3243,7 @@ finish_destroy_win(session_t *ps, Window id) {
|
|||
|
||||
static void
|
||||
destroy_callback(session_t *ps, win *w) {
|
||||
finish_destroy_win(ps, w->id);
|
||||
finish_destroy_win(ps, w);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -919,7 +919,7 @@ static void
|
|||
circulate_win(session_t *ps, XCirculateEvent *ce);
|
||||
|
||||
static void
|
||||
finish_destroy_win(session_t *ps, Window id);
|
||||
finish_destroy_win(session_t *ps, win *w);
|
||||
|
||||
static void
|
||||
destroy_callback(session_t *ps, win *w);
|
||||
|
|
Loading…
Reference in a new issue