Fixes nasty bug in event processing.
WALK_LIST_DELSAFE (in ev_run_list) is not safe with regard to deletion of next node. When some events are rescheduled during event execution, it may lead to deletion of next node and some events are skipped. Such skipped nodes remain in temporary list on stack and the last of them contains 'next' pointer to stack area. When this event is later scheduled, it damages stack area trying to remove it from the list, which leads to random crashes with funny backtraces :-) .
This commit is contained in:
parent
35164c5017
commit
b933281ed5
2 changed files with 5 additions and 2 deletions
|
@ -125,13 +125,13 @@ ev_schedule(event *e)
|
|||
int
|
||||
ev_run_list(event_list *l)
|
||||
{
|
||||
node *n, *p;
|
||||
node *n;
|
||||
list tmp_list;
|
||||
|
||||
init_list(&tmp_list);
|
||||
add_tail_list(&tmp_list, l);
|
||||
init_list(l);
|
||||
WALK_LIST_DELSAFE(n, p, tmp_list)
|
||||
WALK_LIST_FIRST(n, tmp_list)
|
||||
{
|
||||
event *e = SKIP_BACK(event, n, n);
|
||||
ev_run(e);
|
||||
|
|
|
@ -37,6 +37,9 @@ typedef struct list { /* In fact two overlayed nodes */
|
|||
n=(void *)((NODE (n))->next))
|
||||
#define WALK_LIST_DELSAFE(n,nxt,list) \
|
||||
for(n=HEAD(list); nxt=(void *)((NODE (n))->next); n=(void *) nxt)
|
||||
/* WALK_LIST_FIRST supposes that called code removes each processed node */
|
||||
#define WALK_LIST_FIRST(n,list) \
|
||||
while(n=HEAD(list), (NODE (n))->next)
|
||||
#define WALK_LIST_BACKWARDS(n,list) for(n=TAIL(list);(NODE (n))->prev; \
|
||||
n=(void *)((NODE (n))->prev))
|
||||
#define WALK_LIST_BACKWARDS_DELSAFE(n,prv,list) \
|
||||
|
|
Loading…
Reference in a new issue