mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 23:46:17 +01:00
avoid quadratic behavior of GMainLoop when all fd's have the same priority
https://bugzilla.gnome.org/show_bug.cgi?id=640518
This commit is contained in:
parent
1e88c5321c
commit
c5d9a46394
47
glib/gmain.c
47
glib/gmain.c
@ -227,7 +227,7 @@ struct _GMainContext
|
|||||||
GSource *source_list;
|
GSource *source_list;
|
||||||
gint in_check_or_prepare;
|
gint in_check_or_prepare;
|
||||||
|
|
||||||
GPollRec *poll_records;
|
GPollRec *poll_records, *poll_records_tail;
|
||||||
guint n_poll_records;
|
guint n_poll_records;
|
||||||
GPollFD *cached_poll_array;
|
GPollFD *cached_poll_array;
|
||||||
guint cached_poll_array_size;
|
guint cached_poll_array_size;
|
||||||
@ -302,6 +302,7 @@ struct _GUnixSignalWatchSource
|
|||||||
struct _GPollRec
|
struct _GPollRec
|
||||||
{
|
{
|
||||||
GPollFD *fd;
|
GPollFD *fd;
|
||||||
|
GPollRec *prev;
|
||||||
GPollRec *next;
|
GPollRec *next;
|
||||||
gint priority;
|
gint priority;
|
||||||
};
|
};
|
||||||
@ -3530,7 +3531,7 @@ g_main_context_add_poll_unlocked (GMainContext *context,
|
|||||||
gint priority,
|
gint priority,
|
||||||
GPollFD *fd)
|
GPollFD *fd)
|
||||||
{
|
{
|
||||||
GPollRec *lastrec, *pollrec;
|
GPollRec *prevrec, *nextrec;
|
||||||
GPollRec *newrec = g_slice_new (GPollRec);
|
GPollRec *newrec = g_slice_new (GPollRec);
|
||||||
|
|
||||||
/* This file descriptor may be checked before we ever poll */
|
/* This file descriptor may be checked before we ever poll */
|
||||||
@ -3538,20 +3539,26 @@ g_main_context_add_poll_unlocked (GMainContext *context,
|
|||||||
newrec->fd = fd;
|
newrec->fd = fd;
|
||||||
newrec->priority = priority;
|
newrec->priority = priority;
|
||||||
|
|
||||||
lastrec = NULL;
|
prevrec = context->poll_records_tail;
|
||||||
pollrec = context->poll_records;
|
nextrec = NULL;
|
||||||
while (pollrec && priority >= pollrec->priority)
|
while (prevrec && priority < prevrec->priority)
|
||||||
{
|
{
|
||||||
lastrec = pollrec;
|
nextrec = prevrec;
|
||||||
pollrec = pollrec->next;
|
prevrec = prevrec->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastrec)
|
if (prevrec)
|
||||||
lastrec->next = newrec;
|
prevrec->next = newrec;
|
||||||
else
|
else
|
||||||
context->poll_records = newrec;
|
context->poll_records = newrec;
|
||||||
|
|
||||||
newrec->next = pollrec;
|
newrec->prev = prevrec;
|
||||||
|
newrec->next = nextrec;
|
||||||
|
|
||||||
|
if (nextrec)
|
||||||
|
nextrec->prev = newrec;
|
||||||
|
else
|
||||||
|
context->poll_records_tail = newrec;
|
||||||
|
|
||||||
context->n_poll_records++;
|
context->n_poll_records++;
|
||||||
|
|
||||||
@ -3590,27 +3597,33 @@ static void
|
|||||||
g_main_context_remove_poll_unlocked (GMainContext *context,
|
g_main_context_remove_poll_unlocked (GMainContext *context,
|
||||||
GPollFD *fd)
|
GPollFD *fd)
|
||||||
{
|
{
|
||||||
GPollRec *pollrec, *lastrec;
|
GPollRec *pollrec, *prevrec, *nextrec;
|
||||||
|
|
||||||
lastrec = NULL;
|
prevrec = NULL;
|
||||||
pollrec = context->poll_records;
|
pollrec = context->poll_records;
|
||||||
|
|
||||||
while (pollrec)
|
while (pollrec)
|
||||||
{
|
{
|
||||||
|
nextrec = pollrec->next;
|
||||||
if (pollrec->fd == fd)
|
if (pollrec->fd == fd)
|
||||||
{
|
{
|
||||||
if (lastrec != NULL)
|
if (prevrec != NULL)
|
||||||
lastrec->next = pollrec->next;
|
prevrec->next = nextrec;
|
||||||
else
|
else
|
||||||
context->poll_records = pollrec->next;
|
context->poll_records = nextrec;
|
||||||
|
|
||||||
|
if (nextrec != NULL)
|
||||||
|
nextrec->prev = prevrec;
|
||||||
|
else
|
||||||
|
context->poll_records_tail = prevrec;
|
||||||
|
|
||||||
g_slice_free (GPollRec, pollrec);
|
g_slice_free (GPollRec, pollrec);
|
||||||
|
|
||||||
context->n_poll_records--;
|
context->n_poll_records--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lastrec = pollrec;
|
prevrec = pollrec;
|
||||||
pollrec = pollrec->next;
|
pollrec = nextrec;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_THREADS_ENABLED
|
#ifdef G_THREADS_ENABLED
|
||||||
|
Loading…
Reference in New Issue
Block a user