Ejemplo n.º 1
0
/* writes <len> bytes from message <msg> to the channel's buffer. Returns -1 in
 * case of success, -2 if the message is larger than the buffer size, or the
 * number of bytes available otherwise. The send limit is automatically
 * adjusted to the amount of data written. FIXME-20060521: handle unaligned
 * data. Note: this function appends data to the buffer's output and possibly
 * overwrites any pending input data which are assumed not to exist.
 */
int bo_inject(struct channel *chn, const char *msg, int len)
{
	int max;

	if (len == 0)
		return -1;

	if (len > chn->buf->size) {
		/* we can't write this chunk and will never be able to, because
		 * it is larger than the buffer. This must be reported as an
		 * error. Then we return -2 so that writers that don't care can
		 * ignore it and go on, and others can check for this value.
		 */
		return -2;
	}

	max = buffer_realign(chn->buf);

	if (len > max)
		return max;

	memcpy(chn->buf->p, msg, len);
	chn->buf->o += len;
	chn->buf->p = b_ptr(chn->buf, len);
	chn->total += len;
	return -1;
}
Ejemplo n.º 2
0
int tcpclient_sendall(tcpclient_t *client, const char *buf, size_t len) {
	buffer_t *sendq = &client->send_queue;

	if (client->addr == NULL) {
		stats_error_log("tcpclient[%s]: Cannot send before connect!", client->name);
		return 1;
	} else {
		// Does nothing if we're already connected, triggers a
		// reconnect if backoff has expired.
		tcpclient_connect(client);
	}

	if (buffer_datacount(&client->send_queue) >= client->config->max_send_queue) {
		if (client->failing == 0) {
			stats_error_log("tcpclient[%s]: send queue for %s client is full (at %zd bytes, max is %" PRIu64 " bytes), dropping data",
					client->name,
					tcpclient_state_name[client->state],
					buffer_datacount(&client->send_queue),
					client->config->max_send_queue);
			client->failing = 1;
		}
		return 2;
	}
	if (buffer_spacecount(sendq) < len) {
		if (buffer_realign(sendq) != 0) {
			stats_error_log("tcpclient[%s]: Unable to realign send queue", client->name);
			return 3;
		}
	}
	while (buffer_spacecount(sendq) < len) {
		if (buffer_expand(sendq) != 0) {
			stats_error_log("tcpclient[%s]: Unable to allocate additional memory for send queue, dropping data", client->name);
			return 4;
		}
	}
	memcpy(buffer_tail(sendq), buf, len);
	buffer_produced(sendq, len);

	if (client->state == STATE_CONNECTED) {
		client->write_watcher.started = true;
		ev_io_start(client->loop, &client->write_watcher.watcher);
	}
	return 0;
}