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); }
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()); }
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); }
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; }
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); } }
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); }
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; }
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); }
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; } } } }