static void _write_ready(GObject *source_object, GAsyncResult *res, gpointer user_data) { GOutputStream *output_stream = G_OUTPUT_STREAM(source_object); GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT(user_data); IdleServerConnection *conn = IDLE_SERVER_CONNECTION(g_async_result_get_source_object(G_ASYNC_RESULT(result))); IdleServerConnectionPrivate *priv = IDLE_SERVER_CONNECTION_GET_PRIVATE(conn); gssize nwrite; GError *error = NULL; g_object_unref(conn); nwrite = g_output_stream_write_finish(output_stream, res, &error); if (nwrite == -1) { IDLE_DEBUG("g_output_stream_write failed : %s", error->message); g_simple_async_result_set_error(result, TP_ERROR, TP_ERROR_NETWORK_ERROR, "%s", error->message); g_error_free(error); goto cleanup; } priv->nwritten += nwrite; if (priv->nwritten < priv->count) { g_output_stream_write_async(output_stream, priv->output_buffer + priv->nwritten, priv->count - priv->nwritten, G_PRIORITY_DEFAULT, priv->cancellable, _write_ready, result); return; } cleanup: if (priv->cancellable != NULL) { g_object_unref(priv->cancellable); priv->cancellable = NULL; } g_simple_async_result_complete(result); g_object_unref(result); }
/* TODO: Does it make sense to use buffer and count? We should probably * provide a better wrapper that simply pumps out buffer while count hasn't * been reached, calling the callback with the bytes written, then with the * result. */ static VALUE rg_write_async(int argc, VALUE *argv, VALUE self) { VALUE rbbuffer, rbcount, rbio_priority, rbcancellable, block; const gchar *buffer; gsize count; int io_priority; GCancellable *cancellable; rb_scan_args(argc, argv, "22&", &rbbuffer, &rbcount, &rbio_priority, &rbcancellable, &block); buffer = RVAL2CSTR(rbbuffer); count = RVAL2GSIZE(rbcount); io_priority = RVAL2IOPRIORITYDEFAULT(rbio_priority); cancellable = RVAL2GCANCELLABLE(rbcancellable); SAVE_BLOCK(block); g_output_stream_write_async(_SELF(self), buffer, count, io_priority, cancellable, rbgio_async_ready_callback, (gpointer)block); return self; }
static void write_all_async (GOutputStream *stream, const void *buffer, gsize count, int io_priority, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *simple; WriteAllData *write_data; write_data = g_slice_new0 (WriteAllData); write_data->buffer = buffer; write_data->count = count; write_data->io_priority = io_priority; if (cancellable) write_data->cancellable = g_object_ref (cancellable); simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, write_all_async); g_simple_async_result_set_op_res_gpointer (simple, write_data, (GDestroyNotify)free_write_all_data); g_output_stream_write_async (stream, buffer, count, io_priority, cancellable, write_all_cb, simple); }
void IOChannel::write(size_t offset, const Data& data, WorkQueue*, std::function<void (int error)> completionHandler) { ASSERT(m_outputStream || m_ioStream); GOutputStream* stream = m_outputStream ? m_outputStream.get() : g_io_stream_get_output_stream(G_IO_STREAM(m_ioStream.get())); WriteAsyncData* asyncData = new WriteAsyncData { this, data.soupBuffer(), completionHandler }; // FIXME: implement offset. g_output_stream_write_async(stream, asyncData->buffer->data, data.size(), G_PRIORITY_DEFAULT, nullptr, reinterpret_cast<GAsyncReadyCallback>(outputStreamWriteReadyCallback), asyncData); }
static void do_write (GAsyncReadyCallback callback, GTask *task, ConnectAsyncData *data) { GOutputStream *out; out = g_io_stream_get_output_stream (data->io_stream); g_output_stream_write_async (out, data->buffer + data->offset, data->length - data->offset, g_task_get_priority (task), g_task_get_cancellable (task), callback, task); }
static void identd_read_ready (GInputStream *in_stream, GAsyncResult *res, ident_info *info) { GSocketAddress *sok_addr; GOutputStream *out_stream; guint64 local, remote; gchar buf[512], *p; if (g_input_stream_read_finish (in_stream, res, NULL)) { local = g_ascii_strtoull (info->read_buf, NULL, 0); p = strchr (info->read_buf, ','); if (!p) goto cleanup; remote = g_ascii_strtoull (p + 1, NULL, 0); if (!local || !remote || local > G_MAXUINT16 || remote > G_MAXUINT16) goto cleanup; info->username = g_strdup (g_hash_table_lookup (responses, GINT_TO_POINTER (local))); if (!info->username) goto cleanup; g_hash_table_remove (responses, GINT_TO_POINTER (local)); if ((sok_addr = g_socket_connection_get_remote_address (info->conn, NULL))) { GInetAddress *inet_addr; gchar *addr; inet_addr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (sok_addr)); addr = g_inet_address_to_string (inet_addr); hextor_printf (ph, _("*\tServicing ident request from %s as %s"), addr, info->username); g_object_unref (sok_addr); g_object_unref (inet_addr); g_free (addr); } g_snprintf (buf, sizeof (buf), "%"G_GUINT16_FORMAT", %"G_GUINT16_FORMAT" : USERID : UNIX : %s\r\n", (guint16)local, (guint16)remote, info->username); out_stream = g_io_stream_get_output_stream (G_IO_STREAM (info->conn)); g_output_stream_write_async (out_stream, buf, strlen (buf), G_PRIORITY_DEFAULT, NULL, (GAsyncReadyCallback)identd_write_ready, info); } return; cleanup: g_object_unref (info->conn); g_free (info); }
static void kick_write(SpiceVDAgent *self) { Msg *msg = g_queue_peek_head(self->outq); if (!msg || self->writing) return; GOutputStream *out = g_io_stream_get_output_stream(self->connection); g_output_stream_write_async(out, msg->data + self->pos, msg->size - self->pos, G_PRIORITY_DEFAULT, self->cancellable, msg_write_cb, self); self->writing = TRUE; }
static void tunnel_wrote_cb (GObject *object, GAsyncResult *result, gpointer user_data) { Tunnel *tunnel = user_data; TunnelEnd *write_end, *read_end; GError *error = NULL; gssize nwrote; nwrote = g_output_stream_write_finish (G_OUTPUT_STREAM (object), result, &error); if (nwrote <= 0) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_error_free (error); return; } else if (error) { g_print ("Tunnel write failed: %s\n", error->message); g_error_free (error); } tunnel_close (tunnel); return; } if (object == (GObject *)tunnel->client.ostream) { write_end = &tunnel->client; read_end = &tunnel->server; } else { write_end = &tunnel->server; read_end = &tunnel->client; } write_end->nwrote += nwrote; if (write_end->nwrote < read_end->nread) { g_output_stream_write_async (write_end->ostream, read_end->buffer + write_end->nwrote, read_end->nread - write_end->nwrote, G_PRIORITY_DEFAULT, tunnel->cancellable, tunnel_wrote_cb, tunnel); } else { g_input_stream_read_async (read_end->istream, read_end->buffer, BUFSIZE, G_PRIORITY_DEFAULT, tunnel->cancellable, tunnel_read_cb, tunnel); } }
static void async_write_data_write (AsyncWriteData *write_data) { GdkWaylandSelection *selection = write_data->selection; gsize buf_len; guchar *buf; buf = selection->stored_selection.data; buf_len = selection->stored_selection.data_len; g_output_stream_write_async (write_data->stream, &buf[write_data->index], buf_len - write_data->index, G_PRIORITY_DEFAULT, selection->stored_selection.cancellable, async_write_data_cb, write_data); }
/* Called by gpgme to write data */ static ssize_t vfs_data_write (void *handle, const void *buffer, size_t size) { VfsAsyncHandle* ah = (VfsAsyncHandle*)handle; ssize_t sz = 0; /* If the file isn't open yet, then do that now */ if (!ah->ostream && ah->state == VFS_ASYNC_READY) vfs_data_open_helper (ah); /* Just in case we have an operation, like open */ if (!vfs_data_wait_results(ah, TRUE)) return -1; g_assert (ah->state == VFS_ASYNC_READY); /* Start async operation */ ah->buffer = (gpointer)buffer; ah->state = VFS_ASYNC_PROCESSING; ah->operation = VFS_OP_WRITING; g_output_stream_write_async (ah->ostream, buffer, size, G_PRIORITY_DEFAULT, ah->cancellable, vfs_data_write_done, ah); /* Wait for it */ if (!vfs_data_wait_results(ah, TRUE)) return -1; /* Return results */ sz = (ssize_t)ah->processed; ah->buffer = NULL; ah->processed = 0; /* Sadly GPGME doesn't support errors on close, so we have to flush after each write */ ah->state = VFS_ASYNC_PROCESSING; ah->operation = VFS_OP_FLUSHING; g_output_stream_flush_async (ah->ostream, G_PRIORITY_DEFAULT, ah->cancellable, vfs_data_flush_done, ah); /* Wait for it */ if (!vfs_data_wait_results(ah, TRUE)) return -1; return sz; }
static void write_to_outputstream (GcrCertificateExporter *self, GOutputStream *os) { gtk_widget_hide (GTK_WIDGET (self->pv->chooser_dialog)); g_assert (GTK_IS_WIDGET (self->pv->chooser_dialog)); /* Are we all done? */ g_assert (self->pv->buffer_at <= self->pv->buffer->len); if (self->pv->buffer_at == self->pv->buffer->len) { g_output_stream_close_async (os, G_PRIORITY_DEFAULT, self->pv->cancellable, on_outputstream_closed, self); return; } g_output_stream_write_async (os, self->pv->buffer->data + self->pv->buffer_at, self->pv->buffer->len - self->pv->buffer_at, G_PRIORITY_DEFAULT, self->pv->cancellable, on_outputstream_write_ready, self); }
static void outputStreamWriteReadyCallback(GOutputStream* stream, GAsyncResult* result, gpointer userData) { std::unique_ptr<WriteAsyncData> asyncData(static_cast<WriteAsyncData*>(userData)); gssize bytesWritten = g_output_stream_write_finish(stream, result, nullptr); if (bytesWritten == -1) { asyncData->completionHandler(-1); return; } gssize pendingBytesToWrite = asyncData->buffer->length - bytesWritten; if (!pendingBytesToWrite) { asyncData->completionHandler(0); return; } asyncData->buffer = adoptGRef(soup_buffer_new_subbuffer(asyncData->buffer.get(), bytesWritten, pendingBytesToWrite)); // Use a local variable for the data buffer to pass it to g_output_stream_write_async(), because WriteAsyncData is released. auto data = asyncData->buffer->data; g_output_stream_write_async(stream, data, pendingBytesToWrite, G_PRIORITY_DEFAULT, nullptr, reinterpret_cast<GAsyncReadyCallback>(outputStreamWriteReadyCallback), asyncData.release()); }
void idle_server_connection_send_async(IdleServerConnection *conn, const gchar *cmd, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { IdleServerConnectionPrivate *priv = IDLE_SERVER_CONNECTION_GET_PRIVATE(conn); GOutputStream *output_stream; GSimpleAsyncResult *result; gsize output_buffer_size = sizeof(priv->output_buffer); if (priv->state != SERVER_CONNECTION_STATE_CONNECTED || priv->io_stream == NULL) { IDLE_DEBUG("connection was not open!"); g_simple_async_report_error_in_idle(G_OBJECT(conn), callback, user_data, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "connection was not open!"); return; } priv->count = strlen(cmd); if (priv->count > output_buffer_size) priv->count = output_buffer_size; /* We only need to copy priv->count bytes, but padding the rest * with null bytes gives us cleaner debug messages, without * affecting the readability of the code. */ strncpy(priv->output_buffer, cmd, output_buffer_size); priv->nwritten = 0; if (cancellable != NULL) { priv->cancellable = cancellable; g_object_ref(priv->cancellable); } output_stream = g_io_stream_get_output_stream(priv->io_stream); result = g_simple_async_result_new(G_OBJECT(conn), callback, user_data, idle_server_connection_send_async); g_output_stream_write_async(output_stream, priv->output_buffer, priv->count, G_PRIORITY_DEFAULT, cancellable, _write_ready, result); IDLE_DEBUG("sending \"%s\" to OutputStream %p", priv->output_buffer, output_stream); }
static void g_filter_output_stream_write_async (GOutputStream *stream, const void *buffer, gsize count, int io_priority, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer data) { GFilterOutputStream *filter_stream; filter_stream = G_FILTER_OUTPUT_STREAM (stream); g_output_stream_write_async (filter_stream->base_stream, buffer, count, io_priority, cancellable, callback, data); }
//------------------------------------------------------------------------------ gboolean OnTimer(gpointer data) { //const char *msg = "{'T':10}"; char *msg = gMeasures.toJson(); g_print("timer\n"); gMeasures.update(); if (ostream != NULL) { // start async write // g_output_stream_write_async(ostream, msg, strlen(msg), G_PRIORITY_DEFAULT, NULL, onWritten, data); } return TRUE; }
static void soup_cache_input_stream_write_next_buffer (SoupCacheInputStream *istream) { SoupCacheInputStreamPrivate *priv = istream->priv; SoupBuffer *buffer = g_queue_pop_head (priv->buffer_queue); int priority; g_assert (priv->output_stream && !g_output_stream_is_closed (priv->output_stream)); g_clear_pointer (&priv->current_writing_buffer, soup_buffer_free); priv->current_writing_buffer = buffer; if (priv->buffer_queue->length > 10) priority = G_PRIORITY_DEFAULT; else priority = G_PRIORITY_LOW; g_output_stream_write_async (priv->output_stream, buffer->data, buffer->length, priority, priv->cancellable, (GAsyncReadyCallback) write_ready_cb, g_object_ref (istream)); }
static void tunnel_read_cb (GObject *object, GAsyncResult *result, gpointer user_data) { Tunnel *tunnel = user_data; TunnelEnd *read_end, *write_end; GError *error = NULL; gssize nread; nread = g_input_stream_read_finish (G_INPUT_STREAM (object), result, &error); if (nread <= 0) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_error_free (error); return; } else if (error) { g_print ("Tunnel read failed: %s\n", error->message); g_error_free (error); } tunnel_close (tunnel); return; } if (object == (GObject *)tunnel->client.istream) { read_end = &tunnel->client; write_end = &tunnel->server; } else { read_end = &tunnel->server; write_end = &tunnel->client; } read_end->nread = nread; write_end->nwrote = 0; g_output_stream_write_async (write_end->ostream, read_end->buffer, read_end->nread, G_PRIORITY_DEFAULT, tunnel->cancellable, tunnel_wrote_cb, tunnel); }
static void write_all_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GOutputStream *stream = G_OUTPUT_STREAM (source_object); GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); gssize bytes_written; GError *err = NULL; WriteAllData *write_data; bytes_written = g_output_stream_write_finish (stream, res, &err); if (bytes_written == -1) { g_simple_async_result_take_error (simple, err); goto done; } write_data = g_simple_async_result_get_op_res_gpointer (simple); write_data->bytes_written += bytes_written; if (write_data->bytes_written < write_data->count) { g_output_stream_write_async (stream, (const guint8 *)write_data->buffer + write_data->bytes_written, write_data->count - write_data->bytes_written, write_data->io_priority, write_data->cancellable, write_all_cb, simple); return; } done: g_simple_async_result_complete (simple); g_object_unref (simple); }
static void identd_read_ready (GDataInputStream *in_stream, GAsyncResult *res, ident_info *info) { GSocketAddress *sok_addr; GOutputStream *out_stream; guint64 local, remote; gchar *read_buf, buf[512], *p; if ((read_buf = g_data_input_stream_read_line_finish (in_stream, res, NULL, NULL))) { local = g_ascii_strtoull (read_buf, NULL, 0); p = strchr (read_buf, ','); if (!p) { g_free (read_buf); goto cleanup; } remote = g_ascii_strtoull (p + 1, NULL, 0); g_free (read_buf); g_snprintf (buf, sizeof (buf), "%"G_GUINT16_FORMAT", %"G_GUINT16_FORMAT" : ", (guint16)MIN(local, G_MAXUINT16), (guint16)MIN(remote, G_MAXUINT16)); if (!local || !remote || local > G_MAXUINT16 || remote > G_MAXUINT16) { g_strlcat (buf, "ERROR : INVALID-PORT\r\n", sizeof (buf)); g_debug ("Identd: Received invalid port"); } else { info->username = g_hash_table_lookup (responses, GINT_TO_POINTER (local)); if (!info->username) { g_strlcat (buf, "ERROR : NO-USER\r\n", sizeof (buf)); g_debug ("Identd: Received invalid local port"); } else { const gsize len = strlen (buf); g_hash_table_steal (responses, GINT_TO_POINTER (local)); g_snprintf (buf + len, sizeof (buf) - len, "USERID : UNIX : %s\r\n", info->username); if ((sok_addr = g_socket_connection_get_remote_address (info->conn, NULL))) { GInetAddress *inet_addr; gchar *addr; inet_addr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (sok_addr)); addr = g_inet_address_to_string (inet_addr); hexchat_printf (ph, _("*\tServicing ident request from %s as %s"), addr, info->username); g_object_unref (sok_addr); g_object_unref (inet_addr); g_free (addr); } } } out_stream = g_io_stream_get_output_stream (G_IO_STREAM (info->conn)); g_output_stream_write_async (out_stream, buf, strlen (buf), G_PRIORITY_DEFAULT, NULL, (GAsyncReadyCallback)identd_write_ready, info); } return; cleanup: ident_info_free (info); }