Beispiel #1
0
size_t Buffer_send(Buffer *buffer, int fd)
{
    DEBUG(("Buffer_send fd: %d, position: %d, limit: %d, remaining: %d\n", fd, buffer->position, buffer->limit, Buffer_remaining(buffer)));
    size_t bytes_written = write(fd, buffer->data + buffer->position, Buffer_remaining(buffer));
    DEBUG(("Buffer_send fd: %d, bytes_written: %d\n", fd, bytes_written));
    if(bytes_written != -1) {
        buffer->position += bytes_written;
    }
    return bytes_written;
}
Beispiel #2
0
size_t Buffer_recv(Buffer *buffer, int fd)
{
    Buffer_ensure_remaining(buffer, (buffer->capacity * 256) / 2048); //make sure we have still 1/8 remaining
    DEBUG(("Buffer_recv fd: %d, position: %d, limit: %d, remaining: %d\n", fd, buffer->position, buffer->limit, Buffer_remaining(buffer)));
    size_t bytes_read = read(fd, buffer->data + buffer->position, Buffer_remaining(buffer));
    DEBUG(("Buffer_recv fd: %d, bytes_read: %d\n", fd, bytes_read));
    if(bytes_read != -1) {
        buffer->position += bytes_read;
    }
    return bytes_read;
}
Beispiel #3
0
void Buffer_ensure_remaining(Buffer *buffer, int min_remaining)
{
    DEBUG(("Buffer %p ensure remaining: position: %d, limit: %d, cap: %d\n", (void *)buffer, buffer->position, buffer->limit, buffer->capacity));
    assert(buffer->limit == buffer->capacity);
    while(Buffer_remaining(buffer) < min_remaining) {
        buffer->limit *= 2;
    }
    assert(buffer->limit >= buffer->capacity);
    if(buffer->limit > buffer->capacity) {
        if(buffer->capacity == buffer->buff_size) {
            DEBUG(("growing buffer first time, new cap: %d, old cap: %d\n", buffer->limit, buffer->capacity));
            buffer->data = Alloc_alloc(buffer->limit);
            memcpy(buffer->data, buffer->buff, buffer->capacity);
        }
        else {
            DEBUG(("growing buffer second or more time, new cap: %d, old cap: %d\n", buffer->limit, buffer->capacity));
            buffer->data = Alloc_realloc(buffer->data, buffer->limit, buffer->capacity);
        }
        buffer->capacity = buffer->limit;
    }
    assert(buffer->limit == buffer->capacity);
}
Beispiel #4
0
void Connection_write_data(Connection *connection, int ordinal)
{
	DEBUG(("connection write_data fd: %d\n", connection->sockfd));
	assert(connection->current_batch != NULL);
	assert(connection->current_executor != NULL);
	if(CS_ABORTED == connection->state) {
		return;
	}

	if(CS_CLOSED == connection->state) {
		if(-1 == Connection_create_socket(connection)) {
			//already aborted in create_socket
			return;
		}
		//connect the socket
		struct addrinfo *addrinfo = connection->addrinfo;
		if(-1 == connect(connection->sockfd, addrinfo->ai_addr, addrinfo->ai_addrlen)) {
			//open the connection
			if(EINPROGRESS == errno) {
				//normal async connect
				connection->state = CS_CONNECTING;
				DEBUG(("async connecting, adding write event\n"));
				Executor_notify_event(connection->current_executor, connection, EVENT_WRITE, ordinal);
				DEBUG(("write event added, now returning\n"));
				return;
			}
			else {
				Connection_abort(connection, "connect error 1, errno [%d] %s", errno, strerror(errno));
				return;
			}
		}
		else {
			//immediate connect succeeded
			DEBUG(("sync connected\n"));
			connection->state = CS_CONNECTED;
		}
	}

	if(CS_CONNECTING == connection->state) {
		//now check for error to see if we are really connected
		int error;
		socklen_t len = sizeof(int);
		if(-1 == getsockopt(connection->sockfd, SOL_SOCKET, SO_ERROR, &error, &len)) {
			Connection_abort(connection, "getsockopt error for connect result, errno: [%d] %s", errno, strerror(errno));
			return;
		}
		if(error != 0) {
			Connection_abort(connection, "connect error 2, error: [%d] %s", error, strerror(error));
			return;
		}
		else {
			connection->state = CS_CONNECTED;
			Executor_notify_event(connection->current_executor, connection, EVENT_READ, ordinal);
		}
	}

	if(CS_CONNECTED == connection->state) {

		Buffer *buffer = Batch_write_buffer(connection->current_batch);
		assert(buffer != NULL);
		while(Buffer_remaining(buffer)) {
			//still something to write
			size_t res = Buffer_send(buffer, connection->sockfd);
			DEBUG(("bfr send res: %d\n", res));
			if(res == -1) {
				if(errno == EAGAIN) {
					Executor_notify_event(connection->current_executor, connection, EVENT_WRITE, ordinal);
					return;
				}
				else {
					Connection_abort(connection, "write error, errno: [%d] %s", errno, strerror(errno));
					return;
				}
			}
		}
	}
}