/** * Flush the chunk header by sending it to the wire. * * @return +1 if we were able to flush the whole header, 0 if we need * to be called again and -1 on errors.. */ static ssize_t chunk_flush_header(txdrv_t *tx) { struct attr *attr = tx->opaque; ssize_t offset; /* Offset within head[] for data to TX */ ssize_t r; g_assert(attr->head_len > 0); g_assert(attr->head_remain > 0); offset = attr->head_len - attr->head_remain; g_assert(offset >= 0); r = tx_write(tx->lower, &attr->head[offset], attr->head_remain); /* * If we were unable to flush everything, enable servicing from * the lower layer: it will call our service routine when it is * able to accept more data from us. */ if (r == -1) return -1; /* Bail out, we're probably dead already */ if (r != attr->head_remain) tx_srv_enable(tx->lower); if (r == 0) return 0; attr->head_remain -= r; g_assert(attr->head_remain >= 0); return 0 == attr->head_remain ? +1 : 0; /* +1 if we sent everything */ }
/** * Write ready-to-be-sent buffer to the lower layer. */ static void deflate_send(txdrv_t *tx) { struct attr *attr = tx->opaque; struct buffer *b; size_t len; /**< Amount of bytes to send */ ssize_t r; g_assert(attr->send_idx >= 0); /* We have something to send */ g_assert(attr->send_idx < BUFFER_COUNT); /* * Compute data to be sent. */ b = &attr->buf[attr->send_idx]; /* Buffer to send */ len = b->wptr - b->rptr; g_assert(len > 0 && len <= INT_MAX); /* * Write as much as possible. */ r = tx_write(tx->lower, b->rptr, len); if (tx_deflate_debugging(9)) { g_debug("TX %s: (%s) wrote %zu/%zu bytes (buffer #%d) [%c%c]", G_STRFUNC, gnet_host_to_string(&tx->host), r, len, attr->send_idx, (attr->flags & DF_FLOWC) ? 'C' : '-', (attr->flags & DF_FLUSH) ? 'f' : '-'); } if ((ssize_t) -1 == r) { tx_error(tx); return; } /* * If we wrote everything, we're done. */ if ((size_t) r == len) { if (tx_deflate_debugging(9)) { g_debug("TX %s: (%s) buffer #%d is empty", G_STRFUNC, gnet_host_to_string(&tx->host), attr->send_idx); } attr->send_idx = -1; /* Signals: is now free */ b->wptr = b->rptr = b->arena; /* Buffer is now empty */ return; } /* * We were unable to send the whole buffer. Enable servicing when * the lower layer will be ready for more input. */ b->rptr += r; g_assert(b->rptr < b->wptr); /* We haven't written everything */ tx_srv_enable(tx->lower); }