summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2003-06-06 03:54:03 +0000
committerOwen Taylor <otaylor@src.gnome.org>2003-06-06 03:54:03 +0000
commit4a21238fef329d10c4114a64f7e9e6959aeaa17a (patch)
treee9644510682d0a6bf73cd43df4014f9b8aafb179
parentcc777da9c1476d436f6f96d877a99c0c614a528d (diff)
downloadglib-4a21238fef329d10c4114a64f7e9e6959aeaa17a.tar.gz
glib-4a21238fef329d10c4114a64f7e9e6959aeaa17a.tar.bz2
glib-4a21238fef329d10c4114a64f7e9e6959aeaa17a.zip
When dispatching a source that is !CAN_RECURSE, temporarily remove any
Thu Jun 5 23:40:31 2003 Owen Taylor <otaylor@redhat.com> * 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)
-rw-r--r--ChangeLog14
-rw-r--r--ChangeLog.pre-2-1014
-rw-r--r--ChangeLog.pre-2-1214
-rw-r--r--ChangeLog.pre-2-414
-rw-r--r--ChangeLog.pre-2-614
-rw-r--r--ChangeLog.pre-2-814
-rw-r--r--glib/gmain.c95
7 files changed, 160 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index b6d1fe849..7fb979051 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Thu Jun 5 23:40:31 2003 Owen Taylor <otaylor@redhat.com>
+
+ * 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 <maclas@gmx.de>
* glib/gstring.c (g_string_append_printf_internal): Use
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index b6d1fe849..7fb979051 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,17 @@
+Thu Jun 5 23:40:31 2003 Owen Taylor <otaylor@redhat.com>
+
+ * 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 <maclas@gmx.de>
* glib/gstring.c (g_string_append_printf_internal): Use
diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12
index b6d1fe849..7fb979051 100644
--- a/ChangeLog.pre-2-12
+++ b/ChangeLog.pre-2-12
@@ -1,3 +1,17 @@
+Thu Jun 5 23:40:31 2003 Owen Taylor <otaylor@redhat.com>
+
+ * 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 <maclas@gmx.de>
* glib/gstring.c (g_string_append_printf_internal): Use
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index b6d1fe849..7fb979051 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,17 @@
+Thu Jun 5 23:40:31 2003 Owen Taylor <otaylor@redhat.com>
+
+ * 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 <maclas@gmx.de>
* glib/gstring.c (g_string_append_printf_internal): Use
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index b6d1fe849..7fb979051 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,17 @@
+Thu Jun 5 23:40:31 2003 Owen Taylor <otaylor@redhat.com>
+
+ * 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 <maclas@gmx.de>
* glib/gstring.c (g_string_append_printf_internal): Use
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index b6d1fe849..7fb979051 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,17 @@
+Thu Jun 5 23:40:31 2003 Owen Taylor <otaylor@redhat.com>
+
+ * 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 <maclas@gmx.de>
* glib/gstring.c (g_string_append_printf_internal): Use
diff --git a/glib/gmain.c b/glib/gmain.c
index 4a66ee095..45ecb5ff6 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))