void SocketStreamHandle::beginWaitingForSocketWritability()
{
    if (m_writeReadySource) // Already waiting.
        return;

    m_writeReadySource = adoptGRef(g_pollable_output_stream_create_source(m_outputStream.get(), 0));
    g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), m_id, 0);
    g_source_attach(m_writeReadySource.get(), 0);
}
Пример #2
0
void SocketStreamHandle::beginWaitingForSocketWritability()
{
    if (m_writeReadySource) // Already waiting.
        return;

    m_writeReadySource = adoptGRef(g_pollable_output_stream_create_source(m_outputStream.get(), m_cancellable.get()));
    ref();
    g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), this,
        [](gpointer handle) { static_cast<SocketStreamHandle*>(handle)->deref(); });
    g_source_attach(m_writeReadySource.get(), g_main_context_get_thread_default());
}
Пример #3
0
static void
tls_source_sync (GTlsConnectionBaseSource *tls_source)
{
  GTlsConnectionBase *tls = tls_source->tls;
  gboolean io_waiting, op_waiting;

  /* Was the source destroyed earlier in this main context iteration? */
  if (g_source_is_destroyed ((GSource *) tls_source))
    return;

  g_mutex_lock (&tls->op_mutex);
  if (((tls_source->condition & G_IO_IN) && tls->reading) ||
      ((tls_source->condition & G_IO_OUT) && tls->writing) ||
      (tls->handshaking && !tls->need_finish_handshake))
    op_waiting = TRUE;
  else
    op_waiting = FALSE;

  if (!op_waiting && !tls->need_handshake &&
      !tls->need_finish_handshake)
    io_waiting = TRUE;
  else
    io_waiting = FALSE;
  g_mutex_unlock (&tls->op_mutex);

  if (op_waiting == tls_source->op_waiting &&
      io_waiting == tls_source->io_waiting)
    return;
  tls_source->op_waiting = op_waiting;
  tls_source->io_waiting = io_waiting;

  if (tls_source->child_source)
    {
      g_source_remove_child_source ((GSource *)tls_source,
				    tls_source->child_source);
      g_source_unref (tls_source->child_source);
    }

  if (op_waiting)
    tls_source->child_source = g_cancellable_source_new (tls->waiting_for_op);
  else if (io_waiting && G_IS_POLLABLE_INPUT_STREAM (tls_source->stream))
    tls_source->child_source = g_pollable_input_stream_create_source (tls->base_istream, NULL);
  else if (io_waiting && G_IS_POLLABLE_OUTPUT_STREAM (tls_source->stream))
    tls_source->child_source = g_pollable_output_stream_create_source (tls->base_ostream, NULL);
  else
    tls_source->child_source = g_timeout_source_new (0);

  g_source_set_dummy_callback (tls_source->child_source);
  g_source_add_child_source ((GSource *)tls_source, tls_source->child_source);
}
Пример #4
0
GSource *
soup_message_io_get_source (SoupMessage *msg, GCancellable *cancellable,
			    SoupMessageSourceFunc callback, gpointer user_data)
{
	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
	SoupMessageIOData *io = priv->io_data;
	GSource *base_source, *source;
	SoupMessageSource *message_source;

	if (!io) {
		base_source = g_timeout_source_new (0);
	} else if (io->paused) {
		base_source = NULL;
	} else if (io->async_close_wait) {
		base_source = g_cancellable_source_new (io->async_close_wait);
	} else if (SOUP_MESSAGE_IO_STATE_POLLABLE (io->read_state)) {
		GPollableInputStream *istream;

		if (io->body_istream)
			istream = G_POLLABLE_INPUT_STREAM (io->body_istream);
		else
			istream = G_POLLABLE_INPUT_STREAM (io->istream);
		base_source = g_pollable_input_stream_create_source (istream, cancellable);
	} else if (SOUP_MESSAGE_IO_STATE_POLLABLE (io->write_state)) {
		GPollableOutputStream *ostream;

		if (io->body_ostream)
			ostream = G_POLLABLE_OUTPUT_STREAM (io->body_ostream);
		else
			ostream = G_POLLABLE_OUTPUT_STREAM (io->ostream);
		base_source = g_pollable_output_stream_create_source (ostream, cancellable);
	} else
		base_source = g_timeout_source_new (0);

	source = g_source_new (&message_source_funcs,
			       sizeof (SoupMessageSource));
	g_source_set_name (source, "SoupMessageSource");
	message_source = (SoupMessageSource *)source;
	message_source->msg = g_object_ref (msg);
	message_source->paused = io && io->paused;

	if (base_source) {
		g_source_set_dummy_callback (base_source);
		g_source_add_child_source (source, base_source);
		g_source_unref (base_source);
	}
	g_source_set_callback (source, (GSourceFunc) callback, user_data, NULL);
	return source;
}
Пример #5
0
static void
queue_bytes (CockpitWebResponse *self,
             GBytes *block)
{
  g_queue_push_tail (self->queue, g_bytes_ref (block));

  self->count++;

  if (!self->source)
    {
      self->source = g_pollable_output_stream_create_source (self->out, NULL);
      g_source_set_callback (self->source, (GSourceFunc)on_response_output, self, NULL);
      g_source_attach (self->source, NULL);
    }
}
Пример #6
0
static void
start_output (CockpitStream *self)
{
  GOutputStream *os;

  g_assert (self->priv->out_source == NULL);

  if (self->priv->connecting || self->priv->out_closed || self->priv->closed)
    return;

  g_assert (self->priv->io);

  os = g_io_stream_get_output_stream (self->priv->io);
  self->priv->out_source = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (os), NULL);
  g_source_set_name (self->priv->out_source, "stream-output");
  g_source_set_callback (self->priv->out_source, (GSourceFunc)dispatch_output, self, NULL);
  g_source_attach (self->priv->out_source, self->priv->context);
}
Пример #7
0
static GSource *
soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
			  GPollableSourceFunc callback, gpointer user_data,
			  GCancellable *cancellable)
{
	GSource *watch;
	GMainContext *async_context;

	if (cond == G_IO_IN)
		watch = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (priv->istream), cancellable);
	else
		watch = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (priv->ostream), cancellable);
	g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL);

	if (priv->use_thread_context)
		async_context = g_main_context_get_thread_default ();
	else
		async_context = priv->async_context;

	g_source_attach (watch, async_context);
	g_source_unref (watch);

	return watch;
}
Пример #8
0
static void
test_pollable_cancellation (NiceAddress *addr)
{
  NiceAgent *agent;
  guint stream_id;
  GIOStream *io_stream;
  GInputStream *input_stream;
  GOutputStream *output_stream;
  GPollableInputStream *pollable_input_stream;
  GPollableOutputStream *pollable_output_stream;
  guint8 buf[65536];
  GError *error = NULL;
  GSource *stream_source;
  GCancellable *cancellable;

  agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245);
  nice_agent_add_local_address (agent, addr);

  /* Add a stream. */
  stream_id = nice_agent_add_stream (agent, 1);

  /* Try building an I/O stream around it. */
  io_stream = nice_agent_get_io_stream (agent, stream_id, 1);
  g_assert (G_IS_IO_STREAM (io_stream));
  g_assert (NICE_IS_IO_STREAM (io_stream));

  /* Grab the input and output streams. */
  input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream));
  g_assert (G_IS_POLLABLE_INPUT_STREAM (input_stream));
  pollable_input_stream = G_POLLABLE_INPUT_STREAM (input_stream);

  output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream));
  g_assert (G_IS_POLLABLE_OUTPUT_STREAM (output_stream));
  pollable_output_stream = G_POLLABLE_OUTPUT_STREAM (output_stream);

  /* Check the non-blocking read() and write() return immediately if called with
   * a cancelled cancellable. */
  cancellable = g_cancellable_new ();
  g_cancellable_cancel (cancellable);

  g_assert (
      g_pollable_input_stream_read_nonblocking (pollable_input_stream,
          buf, sizeof (buf), cancellable, &error) == -1);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
  g_clear_error (&error);

  g_assert (
      g_pollable_output_stream_write_nonblocking (pollable_output_stream,
          buf, sizeof (buf), cancellable, &error) == -1);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
  g_clear_error (&error);

  g_object_unref (cancellable);

  /* Check the GSources invoke a callback when run with the cancellable
   * cancelled. */
  cancellable = g_cancellable_new ();
  stream_source =
      g_pollable_input_stream_create_source (pollable_input_stream,
          cancellable);

  check_pollable_source_cancellation (stream_source, cancellable);

  g_source_unref (stream_source);
  g_object_unref (cancellable);

  /* And for the output stream. */
  cancellable = g_cancellable_new ();
  stream_source =
      g_pollable_output_stream_create_source (pollable_output_stream,
          cancellable);

  check_pollable_source_cancellation (stream_source, cancellable);

  g_object_unref (io_stream);
  g_source_unref (stream_source);
  g_object_unref (cancellable);
  g_object_unref (agent);
}
Пример #9
0
static void
test_pollable_properties (NiceAddress *addr)
{
  NiceAgent *agent;
  guint stream_id;
  GIOStream *io_stream;
  GInputStream *input_stream;
  GOutputStream *output_stream;
  GPollableInputStream *pollable_input_stream;
  GPollableOutputStream *pollable_output_stream;
  guint8 buf[65536];
  GError *error = NULL;
  GSource *stream_source;

  agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245);
  nice_agent_add_local_address (agent, addr);

  /* Add a stream. */
  stream_id = nice_agent_add_stream (agent, 1);

  /* Try building an I/O stream around it. */
  io_stream = nice_agent_get_io_stream (agent, stream_id, 1);
  g_assert (G_IS_IO_STREAM (io_stream));
  g_assert (NICE_IS_IO_STREAM (io_stream));

  /* Check the input stream’s properties. */
  input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream));
  g_assert (G_IS_POLLABLE_INPUT_STREAM (input_stream));
  pollable_input_stream = G_POLLABLE_INPUT_STREAM (input_stream);

  g_assert (g_pollable_input_stream_can_poll (pollable_input_stream));
  g_assert (!g_pollable_input_stream_is_readable (pollable_input_stream));

  g_assert (
      g_pollable_input_stream_read_nonblocking (pollable_input_stream,
          buf, sizeof (buf), NULL, &error) == -1);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
  g_clear_error (&error);

  stream_source =
      g_pollable_input_stream_create_source (pollable_input_stream, NULL);
  g_assert (stream_source != NULL);
  g_source_unref (stream_source);

  /* Check the output stream’s properties. */
  output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream));
  g_assert (G_IS_POLLABLE_OUTPUT_STREAM (output_stream));
  pollable_output_stream = G_POLLABLE_OUTPUT_STREAM (output_stream);

  g_assert (g_pollable_output_stream_can_poll (pollable_output_stream));
  g_assert (!g_pollable_output_stream_is_writable (pollable_output_stream));

  g_assert (
      g_pollable_output_stream_write_nonblocking (pollable_output_stream,
          buf, sizeof (buf), NULL, &error) == -1);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
  g_clear_error (&error);

  stream_source =
      g_pollable_output_stream_create_source (pollable_output_stream, NULL);
  g_assert (stream_source != NULL);
  g_source_unref (stream_source);

  /* Remove the component and check that the I/O streams close. */
  nice_agent_remove_stream (agent, stream_id);

  g_assert (!g_pollable_input_stream_is_readable (pollable_input_stream));
  g_assert (!g_pollable_output_stream_is_writable (pollable_output_stream));

  g_assert (
      g_pollable_input_stream_read_nonblocking (pollable_input_stream,
          buf, sizeof (buf), NULL, &error) == 0);
  g_assert_no_error (error);

  g_assert (
      g_pollable_output_stream_write_nonblocking (pollable_output_stream,
          buf, sizeof (buf), NULL, &error) == -1);
  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
  g_clear_error (&error);

  g_object_unref (io_stream);
  g_object_unref (agent);
}
static void do_console_raw_update_events(GVirSandboxConsoleRaw *console)
{
    GVirSandboxConsoleRawPrivate *priv = console->priv;

    if (!priv->attached) /* Closed */
        return;

    if (priv->localStdin) {
        if ((priv->localToConsoleOffset < priv->localToConsoleLength) &&
            (!priv->localEOF)) {
            if (priv->localStdinSource == NULL) {
                priv->localStdinSource = g_pollable_input_stream_create_source
                    (G_POLLABLE_INPUT_STREAM(priv->localStdin), NULL);
                g_source_set_callback(priv->localStdinSource,
                                      (GSourceFunc)do_console_raw_local_read,
                                      console,
                                      NULL);
                g_source_attach(priv->localStdinSource,
                                g_main_context_default());
            }
        } else {
            if (priv->localStdinSource) {
                g_source_destroy(priv->localStdinSource);
                g_source_unref(priv->localStdinSource);
                priv->localStdinSource = NULL;
            }
        }
    }

    /*
     * With raw consoles we can't distinguish stdout/stderr, so everything
     * goes to stdout
     */
    if (priv->localStdout) {
        if (priv->consoleToLocalOffset) {
            if (priv->localStdoutSource == NULL) {
                priv->localStdoutSource = g_pollable_output_stream_create_source
                    (G_POLLABLE_OUTPUT_STREAM(priv->localStdout), NULL);
                g_source_set_callback(priv->localStdoutSource,
                                      (GSourceFunc)do_console_raw_local_write,
                                      console,
                                      NULL);
                g_source_attach(priv->localStdoutSource,
                                g_main_context_default());
            }
        } else {
            if (priv->localStdoutSource) {
                g_source_destroy(priv->localStdoutSource);
                g_source_unref(priv->localStdoutSource);
                priv->localStdoutSource = NULL;
            }
        }
    } else {
        if (priv->consoleToLocalOffset) {
            if (priv->localStderrSource == NULL) {
                priv->localStderrSource = g_pollable_output_stream_create_source
                    (G_POLLABLE_OUTPUT_STREAM(priv->localStderr), NULL);
                g_source_set_callback(priv->localStderrSource,
                                      (GSourceFunc)do_console_raw_local_write,
                                      console,
                                      NULL);
                g_source_attach(priv->localStderrSource,
                                g_main_context_default());
            }
        } else {
            if (priv->localStderrSource) {
                g_source_destroy(priv->localStderrSource);
                g_source_unref(priv->localStderrSource);
                priv->localStderrSource = NULL;
            }
        }
    }

    if (priv->console) {
        GVirStreamIOCondition cond = 0;

        if (priv->localToConsoleOffset)
            cond |= GVIR_STREAM_IO_CONDITION_WRITABLE;
        if (priv->consoleToLocalOffset < priv->consoleToLocalLength)
            cond |= GVIR_STREAM_IO_CONDITION_READABLE;

        if (priv->consoleWatch) {
            g_source_remove(priv->consoleWatch);
            priv->consoleWatch = 0;
        }
        if (cond) {
            priv->consoleWatch = gvir_stream_add_watch(priv->console,
                                                       cond,
                                                       do_console_raw_stream_readwrite,
                                                       console);
        }
    } else {
        if (priv->consoleToLocalOffset < priv->consoleToLocalLength) {
            if (priv->consoleInputSource == NULL) {
                priv->consoleInputSource = g_pollable_input_stream_create_source
                    (G_POLLABLE_INPUT_STREAM(priv->consoleInput), NULL);
                g_source_set_callback(priv->consoleInputSource,
                                      (GSourceFunc)do_console_raw_console_read,
                                      console,
                                      NULL);
                g_source_attach(priv->consoleInputSource,
                                g_main_context_default());
            }
        } else {
            if (priv->consoleInputSource) {
                g_source_destroy(priv->consoleInputSource);
                g_source_unref(priv->consoleInputSource);
                priv->consoleInputSource = NULL;
            }
        }

        if (priv->localToConsoleOffset) {
            if (priv->consoleOutputSource == NULL) {
                priv->consoleOutputSource = g_pollable_output_stream_create_source
                    (G_POLLABLE_OUTPUT_STREAM(priv->consoleOutput), NULL);
                g_source_set_callback(priv->consoleOutputSource,
                                      (GSourceFunc)do_console_raw_console_write,
                                      console,
                                      NULL);
                g_source_attach(priv->consoleOutputSource,
                                g_main_context_default());
            }
        } else {
            if (priv->consoleOutputSource) {
                g_source_destroy(priv->consoleOutputSource);
                g_source_unref(priv->consoleOutputSource);
                priv->consoleOutputSource = NULL;
            }
        }
    }
}