mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-04-25 08:06:30 +00:00
[client] overlay/msg: fix race condition in render
Some checks are pending
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / module (push) Waiting to run
build / host-linux (push) Waiting to run
build / host-windows-cross (push) Waiting to run
build / host-windows-native (push) Waiting to run
build / obs (clang) (push) Waiting to run
build / obs (gcc) (push) Waiting to run
build / docs (push) Waiting to run
Some checks are pending
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / module (push) Waiting to run
build / host-linux (push) Waiting to run
build / host-windows-cross (push) Waiting to run
build / host-windows-native (push) Waiting to run
build / obs (clang) (push) Waiting to run
build / obs (gcc) (push) Waiting to run
build / docs (push) Waiting to run
If an overlay is closed with overlayMsg_close, the message can be freed while it is still being used by msg_render, resulting in a segfault. Lock the message list for the duration of msg_render to fix this.
This commit is contained in:
parent
7e9e38faa5
commit
03ca20d3e4
@ -85,9 +85,14 @@ static bool msg_needsOverlay(void * udata)
|
|||||||
static int msg_render(void * udata, bool interactive, struct Rect * windowRects,
|
static int msg_render(void * udata, bool interactive, struct Rect * windowRects,
|
||||||
int maxRects)
|
int maxRects)
|
||||||
{
|
{
|
||||||
|
ll_lock(l_msg.messages);
|
||||||
|
|
||||||
struct Msg * msg;
|
struct Msg * msg;
|
||||||
if (!ll_peek_head(l_msg.messages, (void **)&msg))
|
if (!ll_peek_head_nl(l_msg.messages, (void **)&msg))
|
||||||
|
{
|
||||||
|
ll_unlock(l_msg.messages);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ImVec2 * screen = overlayGetScreenSize();
|
ImVec2 * screen = overlayGetScreenSize();
|
||||||
igSetNextWindowBgAlpha(0.8f);
|
igSetNextWindowBgAlpha(0.8f);
|
||||||
@ -163,7 +168,7 @@ static int msg_render(void * udata, bool interactive, struct Rect * windowRects,
|
|||||||
|
|
||||||
if (destroy)
|
if (destroy)
|
||||||
{
|
{
|
||||||
(void)ll_shift(l_msg.messages, NULL);
|
(void)ll_shift_nl(l_msg.messages, NULL);
|
||||||
freeMsg(msg);
|
freeMsg(msg);
|
||||||
app_invalidateOverlay(false);
|
app_invalidateOverlay(false);
|
||||||
}
|
}
|
||||||
@ -171,6 +176,7 @@ static int msg_render(void * udata, bool interactive, struct Rect * windowRects,
|
|||||||
overlayGetImGuiRect(windowRects);
|
overlayGetImGuiRect(windowRects);
|
||||||
igEnd();
|
igEnd();
|
||||||
|
|
||||||
|
ll_unlock(l_msg.messages);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,11 +41,14 @@ struct ll
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ll * ll_new(void);
|
struct ll * ll_new(void);
|
||||||
void ll_free (struct ll * list);
|
void ll_free (struct ll * list);
|
||||||
void ll_push (struct ll * list, void * data);
|
void ll_push (struct ll * list, void * data);
|
||||||
bool ll_shift (struct ll * list, void ** data);
|
bool ll_shift (struct ll * list, void ** data);
|
||||||
bool ll_peek_head(struct ll * list, void ** data);
|
bool ll_shift_nl (struct ll * list, void ** data);
|
||||||
bool ll_peek_tail(struct ll * list, void ** data);
|
bool ll_peek_head (struct ll * list, void ** data);
|
||||||
|
bool ll_peek_head_nl(struct ll * list, void ** data);
|
||||||
|
bool ll_peek_tail (struct ll * list, void ** data);
|
||||||
|
bool ll_peek_tail_nl(struct ll * list, void ** data);
|
||||||
|
|
||||||
#define ll_lock(ll) LG_LOCK((ll)->lock)
|
#define ll_lock(ll) LG_LOCK((ll)->lock)
|
||||||
#define ll_unlock(ll) LG_UNLOCK((ll)->lock)
|
#define ll_unlock(ll) LG_UNLOCK((ll)->lock)
|
||||||
|
@ -83,15 +83,18 @@ void ll_push(struct ll * list, void * data)
|
|||||||
bool ll_shift(struct ll * list, void ** data)
|
bool ll_shift(struct ll * list, void ** data)
|
||||||
{
|
{
|
||||||
LG_LOCK(list->lock);
|
LG_LOCK(list->lock);
|
||||||
|
bool result = ll_shift_nl(list, data);
|
||||||
|
LG_UNLOCK(list->lock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ll_shift_nl(struct ll * list, void ** data)
|
||||||
|
{
|
||||||
if (!list->head)
|
if (!list->head)
|
||||||
{
|
|
||||||
LG_UNLOCK(list->lock);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
struct ll_item * item = list->head;
|
struct ll_item * item = list->head;
|
||||||
ll_removeNL(list, item);
|
ll_removeNL(list, item);
|
||||||
LG_UNLOCK(list->lock);
|
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
*data = item->data;
|
*data = item->data;
|
||||||
@ -103,29 +106,31 @@ bool ll_shift(struct ll * list, void ** data)
|
|||||||
bool ll_peek_head(struct ll * list, void ** data)
|
bool ll_peek_head(struct ll * list, void ** data)
|
||||||
{
|
{
|
||||||
LG_LOCK(list->lock);
|
LG_LOCK(list->lock);
|
||||||
if (!list->head)
|
bool result = ll_peek_head_nl(list, data);
|
||||||
{
|
|
||||||
LG_UNLOCK(list->lock);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*data = list->head->data;
|
|
||||||
LG_UNLOCK(list->lock);
|
LG_UNLOCK(list->lock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ll_peek_head_nl(struct ll * list, void ** data)
|
||||||
|
{
|
||||||
|
if (!list->head)
|
||||||
|
return false;
|
||||||
|
*data = list->head->data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ll_peek_tail(struct ll * list, void ** data)
|
bool ll_peek_tail(struct ll * list, void ** data)
|
||||||
{
|
{
|
||||||
LG_LOCK(list->lock);
|
LG_LOCK(list->lock);
|
||||||
if (!list->tail)
|
bool result = ll_peek_tail_nl(list, data);
|
||||||
{
|
|
||||||
LG_UNLOCK(list->lock);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*data = list->tail->data;
|
|
||||||
LG_UNLOCK(list->lock);
|
LG_UNLOCK(list->lock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ll_peek_tail_nl(struct ll * list, void ** data)
|
||||||
|
{
|
||||||
|
if (!list->tail)
|
||||||
|
return false;
|
||||||
|
*data = list->tail->data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user