From: Owen Taylor Date: Fri, 6 Jun 2003 03:54:03 +0000 (+0000) Subject: When dispatching a source that is !CAN_RECURSE, temporarily remove any X-Git-Tag: GLIB_2_3_0~171 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4a21238fef329d10c4114a64f7e9e6959aeaa17a;p=platform%2Fupstream%2Fglib.git When dispatching a source that is !CAN_RECURSE, temporarily remove any Thu Jun 5 23:40:31 2003 Owen Taylor * glib/gmain.c: When dispatching a source that is !CAN_RECURSE, temporarily remove any file descriptors that that source has registered from the main loop, to keep recursive main loops from busy-waiting if input becomes available on one of those file descriptors. (#112222, Christian Krause) * glib/gmain.c (g_source_set_priority): Properly remove the source from the context's source list and reinsert it sorted, rather than simply setting source->next/prev to NULL! (#114274) --- diff --git a/ChangeLog b/ChangeLog index b6d1fe8..7fb9790 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Thu Jun 5 23:40:31 2003 Owen Taylor + + * glib/gmain.c: When dispatching a source that is + !CAN_RECURSE, temporarily remove any file descriptors + that that source has registered from the main loop, to keep + recursive main loops from busy-waiting if input + becomes available on one of those file descriptors. + (#112222, Christian Krause) + + * glib/gmain.c (g_source_set_priority): Properly + remove the source from the context's source list + and reinsert it sorted, rather than simply setting + source->next/prev to NULL! (#114274) + 2003-06-06 Matthias Clasen * glib/gstring.c (g_string_append_printf_internal): Use diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index b6d1fe8..7fb9790 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,17 @@ +Thu Jun 5 23:40:31 2003 Owen Taylor + + * glib/gmain.c: When dispatching a source that is + !CAN_RECURSE, temporarily remove any file descriptors + that that source has registered from the main loop, to keep + recursive main loops from busy-waiting if input + becomes available on one of those file descriptors. + (#112222, Christian Krause) + + * glib/gmain.c (g_source_set_priority): Properly + remove the source from the context's source list + and reinsert it sorted, rather than simply setting + source->next/prev to NULL! (#114274) + 2003-06-06 Matthias Clasen * glib/gstring.c (g_string_append_printf_internal): Use diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index b6d1fe8..7fb9790 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,17 @@ +Thu Jun 5 23:40:31 2003 Owen Taylor + + * glib/gmain.c: When dispatching a source that is + !CAN_RECURSE, temporarily remove any file descriptors + that that source has registered from the main loop, to keep + recursive main loops from busy-waiting if input + becomes available on one of those file descriptors. + (#112222, Christian Krause) + + * glib/gmain.c (g_source_set_priority): Properly + remove the source from the context's source list + and reinsert it sorted, rather than simply setting + source->next/prev to NULL! (#114274) + 2003-06-06 Matthias Clasen * glib/gstring.c (g_string_append_printf_internal): Use diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index b6d1fe8..7fb9790 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,17 @@ +Thu Jun 5 23:40:31 2003 Owen Taylor + + * glib/gmain.c: When dispatching a source that is + !CAN_RECURSE, temporarily remove any file descriptors + that that source has registered from the main loop, to keep + recursive main loops from busy-waiting if input + becomes available on one of those file descriptors. + (#112222, Christian Krause) + + * glib/gmain.c (g_source_set_priority): Properly + remove the source from the context's source list + and reinsert it sorted, rather than simply setting + source->next/prev to NULL! (#114274) + 2003-06-06 Matthias Clasen * glib/gstring.c (g_string_append_printf_internal): Use diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index b6d1fe8..7fb9790 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,17 @@ +Thu Jun 5 23:40:31 2003 Owen Taylor + + * glib/gmain.c: When dispatching a source that is + !CAN_RECURSE, temporarily remove any file descriptors + that that source has registered from the main loop, to keep + recursive main loops from busy-waiting if input + becomes available on one of those file descriptors. + (#112222, Christian Krause) + + * glib/gmain.c (g_source_set_priority): Properly + remove the source from the context's source list + and reinsert it sorted, rather than simply setting + source->next/prev to NULL! (#114274) + 2003-06-06 Matthias Clasen * glib/gstring.c (g_string_append_printf_internal): Use diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index b6d1fe8..7fb9790 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,17 @@ +Thu Jun 5 23:40:31 2003 Owen Taylor + + * glib/gmain.c: When dispatching a source that is + !CAN_RECURSE, temporarily remove any file descriptors + that that source has registered from the main loop, to keep + recursive main loops from busy-waiting if input + becomes available on one of those file descriptors. + (#112222, Christian Krause) + + * glib/gmain.c (g_source_set_priority): Properly + remove the source from the context's source list + and reinsert it sorted, rather than simply setting + source->next/prev to NULL! (#114274) + 2003-06-06 Matthias Clasen * glib/gstring.c (g_string_append_printf_internal): Use diff --git a/glib/gmain.c b/glib/gmain.c index 4a66ee0..45ecb5f 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -175,6 +175,8 @@ struct _GPollRec #endif #define SOURCE_DESTROYED(source) (((source)->flags & G_HOOK_FLAG_ACTIVE) == 0) +#define SOURCE_BLOCKED(source) (((source)->flags & G_HOOK_FLAG_IN_CALL) != 0 && \ + ((source)->flags & G_SOURCE_CAN_RECURSE) == 0) #define SOURCE_UNREF(source, context) \ G_STMT_START { \ @@ -887,14 +889,17 @@ g_source_destroy_internal (GSource *source, old_cb_funcs->unref (old_cb_data); LOCK_CONTEXT (context); } - - tmp_list = source->poll_fds; - while (tmp_list) + + if (!SOURCE_BLOCKED (source)) { - g_main_context_remove_poll_unlocked (context, tmp_list->data); - tmp_list = tmp_list->next; + tmp_list = source->poll_fds; + while (tmp_list) + { + g_main_context_remove_poll_unlocked (context, tmp_list->data); + tmp_list = tmp_list->next; + } } - + g_source_unref_internal (source, context, TRUE); } @@ -1000,7 +1005,8 @@ g_source_add_poll (GSource *source, if (context) { - g_main_context_add_poll_unlocked (context, source->priority, fd); + if (!SOURCE_BLOCKED (source)) + g_main_context_add_poll_unlocked (context, source->priority, fd); UNLOCK_CONTEXT (context); } } @@ -1032,7 +1038,8 @@ g_source_remove_poll (GSource *source, if (context) { - g_main_context_remove_poll_unlocked (context, fd); + if (!SOURCE_BLOCKED (source)) + g_main_context_remove_poll_unlocked (context, fd); UNLOCK_CONTEXT (context); } } @@ -1186,16 +1193,22 @@ g_source_set_priority (GSource *source, if (context) { - source->next = NULL; - source->prev = NULL; - - tmp_list = source->poll_fds; - while (tmp_list) + /* Remove the source from the context's source and then + * add it back so it is sorted in the correct plcae + */ + g_source_list_remove (source, source->context); + g_source_list_add (source, source->context); + + if (!SOURCE_BLOCKED (source)) { - g_main_context_remove_poll_unlocked (context, tmp_list->data); - g_main_context_add_poll_unlocked (context, priority, tmp_list->data); - - tmp_list = tmp_list->next; + tmp_list = source->poll_fds; + while (tmp_list) + { + g_main_context_remove_poll_unlocked (context, tmp_list->data); + g_main_context_add_poll_unlocked (context, priority, tmp_list->data); + + tmp_list = tmp_list->next; + } } UNLOCK_CONTEXT (source->context); @@ -1622,6 +1635,43 @@ g_get_current_time (GTimeVal *result) /* Running the main loop */ +/* Temporarily remove all this source's file descriptors from the + * poll(), so that if data comes available for one of the file descriptors + * we don't continually spin in the poll() + */ +/* HOLDS: source->context's lock */ +void +block_source (GSource *source) +{ + GSList *tmp_list; + + g_return_if_fail (!SOURCE_BLOCKED (source)); + + tmp_list = source->poll_fds; + while (tmp_list) + { + g_main_context_remove_poll_unlocked (source->context, tmp_list->data); + tmp_list = tmp_list->next; + } +} + +/* HOLDS: source->context's lock */ +void +unblock_source (GSource *source) +{ + GSList *tmp_list; + + g_return_if_fail (!SOURCE_BLOCKED (source)); /* Source already unblocked */ + g_return_if_fail (!SOURCE_DESTROYED (source)); + + tmp_list = source->poll_fds; + while (tmp_list) + { + g_main_context_add_poll_unlocked (source->context, source->priority, tmp_list->data); + tmp_list = tmp_list->next; + } +} + /* HOLDS: context's lock */ static void g_main_dispatch (GMainContext *context) @@ -1657,6 +1707,9 @@ g_main_dispatch (GMainContext *context) if (cb_funcs) cb_funcs->ref (cb_data); + if ((source->flags & G_SOURCE_CAN_RECURSE) == 0) + block_source (source); + was_in_call = source->flags & G_HOOK_FLAG_IN_CALL; source->flags |= G_HOOK_FLAG_IN_CALL; @@ -1676,6 +1729,10 @@ g_main_dispatch (GMainContext *context) if (!was_in_call) source->flags &= ~G_HOOK_FLAG_IN_CALL; + if ((source->flags & G_SOURCE_CAN_RECURSE) == 0 && + !SOURCE_DESTROYED (source)) + unblock_source (source); + /* Note: this depends on the fact that we can't switch * sources from one main context to another */ @@ -1964,7 +2021,7 @@ g_main_context_prepare (GMainContext *context, SOURCE_UNREF (source, context); break; } - if ((source->flags & G_HOOK_FLAG_IN_CALL) && !(source->flags & G_SOURCE_CAN_RECURSE)) + if (SOURCE_BLOCKED (source)) goto next; if (!(source->flags & G_SOURCE_READY)) @@ -2152,7 +2209,7 @@ g_main_context_check (GMainContext *context, SOURCE_UNREF (source, context); break; } - if ((source->flags & G_HOOK_FLAG_IN_CALL) && !(source->flags & G_SOURCE_CAN_RECURSE)) + if (SOURCE_BLOCKED (source)) goto next; if (!(source->flags & G_SOURCE_READY))