static void complete_resolve_async (SoupAddressResolveAsyncData *res_data, guint status) { GSource *current_source; GMainContext *current_context; if (res_data->callback) { /* Awful hack; to make soup_socket_connect_async() * with an non-default async_context work correctly, * we need to ensure that the non-default context * (which we're now running in) is the thread-default * when the callbacks are run... */ current_source = g_main_current_source (); if (current_source && !g_source_is_destroyed (current_source)) current_context = g_source_get_context (current_source); else current_context = NULL; g_main_context_push_thread_default (current_context); res_data->callback (res_data->addr, status, res_data->callback_data); g_main_context_pop_thread_default (current_context); } g_object_unref (res_data->addr); g_slice_free (SoupAddressResolveAsyncData, res_data); }
static void cancellable_source_cancelled (GCancellable *cancellable, gpointer user_data) { GSource *source = user_data; g_main_context_wakeup (g_source_get_context (source)); }
/** @internal Send a message to the port. */ int su_source_wakeup(su_port_t *self) { GMainContext *gmc = g_source_get_context(self->sup_source); if (gmc) g_main_context_wakeup(gmc); return 0; }
static void socket_source_detach (SocketSource *source) { nice_debug ("Detaching source %p (socket %p, FD %d) from context %p", source->source, source->socket, (source->socket->fileno != NULL) ? g_socket_get_fd (source->socket->fileno) : 0, (source->source != NULL) ? g_source_get_context (source->source) : 0); if (source->source != NULL) { g_source_destroy (source->source); g_source_unref (source->source); } source->source = NULL; }
static gboolean gst_bus_source_prepare (GSource * source, gint * timeout) { GstBusSource *bsrc = (GstBusSource *) source; /* we do this here now that we know that we're attached to a main context * (we don't support detaching a source from a main context and then * re-attaching it to a different main context) */ if (G_UNLIKELY (!bsrc->inited)) { gst_bus_set_main_context (bsrc->bus, g_source_get_context (source)); bsrc->inited = TRUE; } *timeout = -1; return gst_bus_have_pending (bsrc->bus); }
/** @internal Run the main loop. * * The main loop runs until su_source_break() is called from a callback. * * @param self pointer to port object * */ static void su_source_run(su_port_t *self) { GMainContext *gmc; GMainLoop *gml; enter; gmc = g_source_get_context(self->sup_source); if (gmc && g_main_context_acquire(gmc)) { gml = g_main_loop_new(gmc, TRUE); self->sup_main_loop = gml; g_main_loop_run(gml); g_main_loop_unref(gml); self->sup_main_loop = NULL; g_main_context_release(gmc); } }
static void complete_resolve_async (SoupAddress *addr, guint status) { SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr); SoupAddressResolveAsyncData *res_data; GSList *lookups, *l; GSource *current_source; GMainContext *current_context; lookups = priv->async_lookups; priv->async_lookups = NULL; /* Awful hack; to make soup_socket_connect_async() with an * non-default async_context work correctly, we need to ensure * that the non-default context (which we're now running in) * is the thread-default when the callbacks are run... */ current_source = g_main_current_source (); if (current_source && !g_source_is_destroyed (current_source)) current_context = g_source_get_context (current_source); else current_context = NULL; g_main_context_push_thread_default (current_context); for (l = lookups; l; l = l->next) { res_data = l->data; if (res_data->callback) { res_data->callback (addr, status, res_data->callback_data); } g_slice_free (SoupAddressResolveAsyncData, res_data); } g_slist_free (lookups); g_main_context_pop_thread_default (current_context); g_object_unref (addr); }
/** @internal Block until wait object is signaled or timeout. * * This function waits for wait objects and the timers associated with * the root object. When any wait object is signaled or timer is * expired, it invokes the callbacks. * * This function returns when a callback has been invoked or @c tout * milliseconds is elapsed. * * @param self pointer to port * @param tout timeout in milliseconds * * @Return * Milliseconds to the next invocation of timer, or @c SU_WAIT_FOREVER if * there are no active timers. */ su_duration_t su_source_step(su_port_t *self, su_duration_t tout) { GMainContext *gmc; enter; gmc = g_source_get_context(self->sup_source); if (gmc && g_main_context_acquire(gmc)) { GPollFD *fds = NULL; gint fds_size = 0; gint fds_wait; gint priority = G_MAXINT; gint src_tout = -1; g_main_context_prepare(gmc, &priority); fds_wait = g_main_context_query(gmc, priority, &src_tout, NULL, 0); while (fds_wait > fds_size) { fds = g_alloca(fds_wait * sizeof(fds[0])); fds_size = fds_wait; fds_wait = g_main_context_query(gmc, priority, &src_tout, fds, fds_size); } if (src_tout >= 0 && tout > (su_duration_t)src_tout) tout = src_tout; su_wait((su_wait_t *)fds, fds_wait, tout); g_main_context_check(gmc, priority, fds, fds_wait); g_main_context_dispatch(gmc); g_main_context_release(gmc); } return 0; }
/** * gst_http_client_attach: * @client: a #GstHTTPClient * @channel: a #GIOChannel * * Accept a new connection for @client on the socket in @channel. * * This function should be called when the client properties and urls are fully * configured and the client is ready to start. * * Returns: %TRUE if the client could be accepted. */ gboolean gst_http_client_accept (GstHTTPClient * client, GIOChannel * channel) { int sock, fd; union gst_sockaddr sa; socklen_t slen = sizeof(sa); struct sockaddr_in6 peeraddr; struct sockaddr_in6 servaddr; GSource *source; GMainContext *context; /* a new client connected. */ sock = g_io_channel_unix_get_fd (channel); memset (&sa, 0, slen); fd = accept (sock, &sa.sa, &slen); if (fd == -1) return FALSE; /* get remote endpoint addr */ g_free (client->peer_ip); slen = sizeof(struct sockaddr_in6); memset(&peeraddr, 0, slen); getpeername(fd, (struct sockaddr *) &peeraddr, &slen); client->peer_ip = g_strdup(sa_straddr(&peeraddr)); client->port = peeraddr.sin6_port; /* get local endpoint addr */ g_free (client->serv_ip); slen = sizeof(struct sockaddr_in6); memset(&servaddr, 0, slen); getsockname(fd, (struct sockaddr *) &servaddr, &slen); client->serv_ip = g_strdup(sa_straddr(&servaddr)); GST_DEBUG_OBJECT (client, "Accepted connection %s:%d on %s", client->peer_ip, client->port, client->serv_ip); #if 0 // if we set NONBLOCK we need to check for EAGAIN on each read/write call /* set non-blocking mode so that we can cancel the communication */ fcntl (fd, F_SETFL, O_NONBLOCK); #endif client->sock = fd; /* find the context to add the watch */ if ((source = g_main_current_source ())) context = g_source_get_context (source); else context = NULL; /* create watch for the connection and attach */ channel = g_io_channel_unix_new (fd); client->watch = g_io_create_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL); g_source_attach (client->watch, context); g_io_channel_unref (channel); /* configure the callback */ g_source_set_callback (client->watch, (GSourceFunc) gst_http_client_io_func, g_object_ref (client), (GDestroyNotify) client_watch_destroyed); return TRUE; }