Пример #1
0
/**
 * 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 */
}
Пример #2
0
/**
 * 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);
}