GList *source_lists;
gint in_check_or_prepare;
- GPollRec *poll_records, *poll_records_tail;
+ GPollRec *poll_records;
guint n_poll_records;
GPollFD *cached_poll_array;
guint cached_poll_array_size;
GSource *source;
GList *sl_iter;
GSourceList *list;
- gint i;
+ guint i;
g_return_if_fail (context != NULL);
g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
*
* It is permitted to call this function multiple times, but is not
* recommended due to the potential performance impact. For example,
- * one could change the name in the "check" function of a #GSourceFuncs
+ * one could change the name in the "check" function of a #GSourceFuncs
* to include details like the event type in the source name.
*
+ * Use caution if changing the name while another thread may be
+ * accessing it with g_source_get_name(); that function does not copy
+ * the value, and changing the value will free it while the other thread
+ * may be attempting to use it.
+ *
* Since: 2.26
**/
void
g_source_set_name (GSource *source,
const char *name)
{
+ GMainContext *context;
+
g_return_if_fail (source != NULL);
+ context = source->context;
+
+ if (context)
+ LOCK_CONTEXT (context);
+
/* setting back to NULL is allowed, just because it's
* weird if get_name can return NULL but you can't
* set that.
g_free (source->name);
source->name = g_strdup (name);
+
+ if (context)
+ UNLOCK_CONTEXT (context);
}
/**
* g_source_get_name:
* @source: a #GSource
*
- * Gets a name for the source, used in debugging and profiling.
- * The name may be #NULL if it has never been set with
- * g_source_set_name().
+ * Gets a name for the source, used in debugging and profiling. The
+ * name may be #NULL if it has never been set with g_source_set_name().
*
* Returns: the name of the source
+ *
* Since: 2.26
**/
const char *
g_slist_free_full (source->priv->fds, g_free);
+ while (source->priv->child_sources)
+ {
+ GSource *child_source = source->priv->child_sources->data;
+
+ source->priv->child_sources =
+ g_slist_remove (source->priv->child_sources, child_source);
+ child_source->priv->parent_source = NULL;
+
+ g_source_unref_internal (child_source, context, have_lock);
+ }
+
g_slice_free (GSourcePrivate, source->priv);
source->priv = NULL;
g_main_context_prepare (GMainContext *context,
gint *priority)
{
- gint i;
+ guint i;
gint n_ready = 0;
gint current_priority = G_MAXINT;
GSource *source;
gint n_fds)
{
gint n_poll;
- GPollRec *pollrec;
+ GPollRec *pollrec, *lastpollrec;
+ gushort events;
LOCK_CONTEXT (context);
- pollrec = context->poll_records;
n_poll = 0;
- while (pollrec && max_priority >= pollrec->priority)
+ lastpollrec = NULL;
+ for (pollrec = context->poll_records; pollrec; pollrec = pollrec->next)
{
- /* We need to include entries with fd->events == 0 in the array because
- * otherwise if the application changes fd->events behind our back and
- * makes it non-zero, we'll be out of sync when we check the fds[] array.
- * (Changing fd->events after adding an FD wasn't an anticipated use of
- * this API, but it occurs in practice.) */
- if (n_poll < n_fds)
- {
- fds[n_poll].fd = pollrec->fd->fd;
- /* In direct contradiction to the Unix98 spec, IRIX runs into
- * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
- * flags in the events field of the pollfd while it should
- * just ignoring them. So we mask them out here.
- */
- fds[n_poll].events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
- fds[n_poll].revents = 0;
- }
+ if (pollrec->priority > max_priority)
+ continue;
+
+ /* In direct contradiction to the Unix98 spec, IRIX runs into
+ * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
+ * flags in the events field of the pollfd while it should
+ * just ignoring them. So we mask them out here.
+ */
+ events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
- pollrec = pollrec->next;
- n_poll++;
+ if (lastpollrec && pollrec->fd->fd == lastpollrec->fd->fd)
+ {
+ if (n_poll - 1 < n_fds)
+ fds[n_poll - 1].events |= events;
+ }
+ else
+ {
+ if (n_poll < n_fds)
+ {
+ fds[n_poll].fd = pollrec->fd->fd;
+ fds[n_poll].events = events;
+ fds[n_poll].revents = 0;
+ }
+
+ n_poll++;
+ }
+
+ lastpollrec = pollrec;
}
context->poll_changed = FALSE;
UNLOCK_CONTEXT (context);
return FALSE;
}
-
+
pollrec = context->poll_records;
i = 0;
- while (i < n_fds)
+ while (pollrec && i < n_fds)
{
- if (pollrec->fd->events)
- pollrec->fd->revents = fds[i].revents;
+ while (pollrec && pollrec->fd->fd == fds[i].fd)
+ {
+ if (pollrec->priority <= max_priority)
+ {
+ pollrec->fd->revents =
+ fds[i].revents & (pollrec->fd->events | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
+ }
+ pollrec = pollrec->next;
+ }
- pollrec = pollrec->next;
i++;
}
newrec->fd = fd;
newrec->priority = priority;
- prevrec = context->poll_records_tail;
- nextrec = NULL;
- while (prevrec && priority < prevrec->priority)
+ prevrec = NULL;
+ nextrec = context->poll_records;
+ while (nextrec)
{
- nextrec = prevrec;
- prevrec = prevrec->prev;
+ if (nextrec->fd->fd > fd->fd)
+ break;
+ prevrec = nextrec;
+ nextrec = nextrec->next;
}
if (prevrec)
if (nextrec)
nextrec->prev = newrec;
- else
- context->poll_records_tail = newrec;
context->n_poll_records++;
if (nextrec != NULL)
nextrec->prev = prevrec;
- else
- context->poll_records_tail = prevrec;
g_slice_free (GPollRec, pollrec);