Esempio n. 1
0
int api_tcp_accept(api_tcp_listener_t* listener, api_tcp_t* tcp)
{
    api_tcp_listener_accept_t accept;

    if (listener->loop->terminated)
        return API__TERMINATE;

    if (listener->status.closed ||
        listener->status.terminated ||
        listener->status.error != API__OK)
        return listener->status.error;

    accept.task = listener->loop->scheduler.current;
    accept.tcp = tcp;
    accept.success = 0;

    tcp->address.address.ss_family = listener->os_linux.af;
    tcp->address.length = sizeof(tcp->address.address);

    listener->os_linux.reserved = &accept;

    api_loop_read_add(listener->loop, listener->fd, &listener->os_linux.e);

    api_task_sleep(accept.task);

    api_loop_read_del(listener->loop, listener->fd, &listener->os_linux.e);

    listener->os_linux.reserved = 0;

    if (accept.success)
        return API__OK;

    return listener->status.error;
}
Esempio n. 2
0
size_t api_stream_on_read(struct api_filter_t* filter, 
                          char* buffer, size_t length)
{
    api_stream_t* stream = filter->stream;
    api_stream_read_t read;
    api_timer_t timeout;
    struct timespec start, end, elapsed;
    uint64_t timeout_value = stream->read_timeout;

    if (length == 0)
        return length;

    if (stream->status.read_timeout ||
        stream->status.eof ||
        stream->status.error != API__OK ||
        stream->status.closed ||
        stream->status.peer_closed ||
        stream->status.terminated)
        return 0;

    read.buffer = buffer;
    read.length = length;
    read.done = 0;
    read.task = stream->loop->base.scheduler.current;

    stream->os_linux.reserved[0] = &read;

    if (timeout_value > 0)
    {
        memset(&timeout, 0, sizeof(timeout));
        timeout.task = read.task;

        api_timeout_exec(&stream->loop->base.timeouts, &timeout, timeout_value);
    }

    clock_gettime(CLOCK_MONOTONIC, &start);

    api_loop_read_add(stream->loop, stream->fd, &stream->os_linux.e);

    api_task_sleep(read.task);

    api_loop_read_del(stream->loop, stream->fd, &stream->os_linux.e);

    clock_gettime(CLOCK_MONOTONIC, &end);

	if (end.tv_nsec - start.tv_nsec < 0)
    {
		elapsed.tv_sec = end.tv_sec - start.tv_sec - 1;
		elapsed.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
	}
    else
    {
		elapsed.tv_sec = end.tv_sec - start.tv_sec;
		elapsed.tv_nsec = end.tv_nsec - start.tv_nsec;
	}

    if (timeout_value > 0)
        api_timeout_exec(&stream->loop->base.timeouts, &timeout, 0);

    stream->os_linux.reserved[0] = 0;
    stream->read_bandwidth.read += read.done;
    stream->read_bandwidth.period += elapsed.tv_sec * 1000000 + elapsed.tv_nsec / 1000;

    if (timeout_value > 0 && timeout.elapsed)
    {
        stream->status.read_timeout = 1;
        stream->filter_head->on_read_timeout(stream->filter_head);

        return 0;
    }
    else
    {
        return read.done;
    }
}