static void cockpit_channel_actual_send (CockpitChannel *self, GBytes *payload, gboolean trust_is_utf8) { GBytes *validated = NULL; guint64 out_sequence; JsonObject *ping; gsize size; g_return_if_fail (self->priv->out_buffer == NULL); g_return_if_fail (self->priv->buffer_timeout == 0); if (!trust_is_utf8) { if (!self->priv->binary_ok) payload = validated = cockpit_unicode_force_utf8 (payload); } cockpit_transport_send (self->priv->transport, self->priv->id, payload); /* A wraparound of our gint64 size? */ if (self->priv->flow_control) { size = g_bytes_get_size (payload); g_return_if_fail (G_MAXINT64 - size > self->priv->out_sequence); /* How many bytes have been sent (queued) */ out_sequence = self->priv->out_sequence + size; /* Every CHANNEL_FLOW_PING bytes we send a ping */ if (out_sequence / CHANNEL_FLOW_PING != self->priv->out_sequence / CHANNEL_FLOW_PING) { ping = json_object_new (); json_object_set_int_member (ping, "sequence", out_sequence); cockpit_channel_control (self, "ping", ping); g_debug ("%s: sending ping with sequence: %" G_GINT64_FORMAT, self->priv->id, out_sequence); json_object_unref (ping); } /* If we've sent more than the window, apply back pressure */ self->priv->out_sequence = out_sequence; if (self->priv->out_sequence > self->priv->out_window) { g_debug ("%s: sent too much data without acknowledgement, emitting back pressure until %" G_GINT64_FORMAT, self->priv->id, self->priv->out_window); cockpit_flow_emit_pressure (COCKPIT_FLOW (self), TRUE); } } if (validated) g_bytes_unref (validated); }
/** * cockpit_channel_send: * @self: a pipe * @payload: the message payload to send * @trust_is_utf8: set to true if sure data is UTF8 * * Called by implementations to send a message over the transport * on the right channel. * * This message is queued, and sent once the transport can. */ void cockpit_channel_send (CockpitChannel *self, GBytes *payload, gboolean trust_is_utf8) { GBytes *validated = NULL; if (!trust_is_utf8) { if (!self->priv->binary_ok) payload = validated = cockpit_unicode_force_utf8 (payload); } cockpit_transport_send (self->priv->transport, self->priv->id, payload); if (validated) g_bytes_unref (validated); }