Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #4
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;
}
Exemple #5
0
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);
  }
}
Exemple #7
0
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;
}
Exemple #9
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;
}