Exemple #1
0
int
lthread_close(int fd)
{
    struct lthread *lt = NULL;

    /* wake up the lthreads waiting on this fd and notify them of close */
    lt = _lthread_desched_event(fd, LT_EV_READ);
    if (lt) {
        TAILQ_INSERT_TAIL(&lthread_get_sched()->ready, lt, ready_next);
        lt->state |= BIT(LT_ST_FDEOF);
    }

    lt = _lthread_desched_event(fd, LT_EV_WRITE);
    if (lt) {
        TAILQ_INSERT_TAIL(&lthread_get_sched()->ready, lt, ready_next);
        lt->state |= BIT(LT_ST_FDEOF);
    }

    /* clear the eof bit of the calling lthread */
    lt = lthread_get_sched()->current_lthread;
    if (lt->state & BIT(LT_ST_FDEOF)) {
        lt->state &= CLEARBIT(LT_ST_FDEOF);
    }

    /* closing fd removes its registered events from poller */
    return (close(fd));
}
Exemple #2
0
int
lthread_sendfile(int fd, int s, off_t offset, size_t nbytes,
    struct sf_hdtr *hdtr)
{

    off_t sbytes = 0;
    int ret = 0;
    lthread_t *lt = lthread_get_sched()->current_lthread;

    do {
        ret = sendfile(fd, s, offset, nbytes, hdtr, &sbytes, 0);

        if (ret == 0)
            return 0;

        if (sbytes)
            offset += sbytes;

        sbytes = 0;

        if (ret == -1 && EAGAIN == errno)
            _lthread_wait_for(lt, s, LT_WRITE);
        else if (ret == -1)
            return -1;

    } while (1);
}
Exemple #3
0
int
lthread_connect(int fd, struct sockaddr *name, socklen_t namelen, uint64_t timeout)
{

    int ret = 0;
    lthread_t *lt = lthread_get_sched()->current_lthread;

    while (1) {
        _lthread_renice(lt);
        ret = connect(fd, name, namelen);
        if (ret == 0)
            break;
        if (ret == -1 && (errno == EAGAIN || 
            errno == EWOULDBLOCK ||
            errno == EINPROGRESS)) {
            if (timeout)
                _sched_lthread(lt, timeout);
            _lthread_wait_for(lt, fd, LT_WRITE);
            if (lt->state & bit(LT_EXPIRED))
                return -2;
            
            ret = 0;
            break;
        } else {
            break;
        }
    }

    return ret;
}
Exemple #4
0
ssize_t
lthread_writev(int fd, struct iovec *iov, int iovcnt)
{
    LTHREAD_SOCKET_CHECK_SCHED(writev(fd, iov, iovcnt));
    ssize_t total = 0;
    int iov_index = 0;
    struct lthread *lt = lthread_get_sched()->current_lthread;

    do {
        _lthread_renice(lt);
        ssize_t n = writev(fd, iov + iov_index, iovcnt - iov_index);
        if (n > 0) {
            int i = 0;
            total += n;
            for (i = iov_index; i < iovcnt && n > 0; i++) {
                if (n < iov[i].iov_len) {
                    iov[i].iov_base += n;
                    iov[i].iov_len -= n;
                    n = 0;
                } else {
                    n -= iov[i].iov_len;
                    iov_index++;
                }
            }
        } else if (-1 == n && EAGAIN == errno) {
            _lthread_sched_event(lt, fd, LT_EV_WRITE, 0);
        } else {
            return (n);
        }
    } while (iov_index < iovcnt);

    return (total);
}
Exemple #5
0
int
lthread_connect(int fd, struct sockaddr *name, socklen_t namelen,
    uint64_t timeout)
{

    int ret = 0;
    struct lthread *lt = lthread_get_sched()->current_lthread;

    while (1) {
        _lthread_renice(lt);
        ret = connect(fd, name, namelen);
        if (ret == 0)
            break;
        if (ret == -1 && (errno == EAGAIN ||
            errno == EWOULDBLOCK ||
            errno == EINPROGRESS ||
            errno == EALREADY)) {
            _lthread_sched_event(lt, fd, LT_EV_WRITE, timeout);
            if (lt->state & BIT(LT_ST_EXPIRED))
                return (-2);

            continue;
        } else {
            break;
        }
    }

    return (ret);
}
Exemple #6
0
void
bd_lt_listener(lthread_t *lt, int args)
{
	lthread_t *lt_new;
	socklen_t addrlen;
	int s_fd, c_fd;
	struct   sockaddr_in cin;

	DEFINE_LTHREAD(lt);
	s_fd = e_listener("0.0.0.0", 5557);
	if (!s_fd) {
		perror("Cannot listen on socket");
		return;
	}
	while (1) {
		c_fd = lthread_accept(lt, s_fd, (struct sockaddr *)&cin,
		    &addrlen);

		if (!c_fd) {
			continue;
		}

		lthread_create(lthread_get_sched(lt), &lt_new, bd_lt_cli,
		    (void *)c_fd);
	}
}
Exemple #7
0
inline void
_lthread_poller_ev_clear_trigger(void)
{
    uint64_t tmp;
    struct lthread_sched *sched = lthread_get_sched();
    assert(read(sched->eventfd, &tmp, sizeof(uint64_t)) == sizeof(uint64_t));
}
Exemple #8
0
ssize_t
lthread_writev(int fd, struct iovec *iov, int iovcnt)
{
    ssize_t total = 0;
    int iov_index = 0;
    lthread_t *lt = lthread_get_sched()->current_lthread;

    do {
        _lthread_renice(lt);
        ssize_t n = writev(fd, iov + iov_index, iovcnt - iov_index);
        if (n > 0) {
            int i = 0;
            total += n;
            for (i = iov_index; i < iovcnt && n > 0; i++) {
                if (n < iov[i].iov_len) {
                    iov[i].iov_base += n;
                    iov[i].iov_len -= n;
                    n = 0;
                } else {
                    n -= iov[i].iov_len;
                    iov_index++;
                }
            }
        } else if (-1 == n && EAGAIN == errno) {
            _lthread_wait_for(lt, fd, LT_WRITE);
        } else {
            return n;
        }
    } while (iov_index < iovcnt);
    return total;
}
Exemple #9
0
inline int
poll_events(struct timespec t)
{
    sched_t *sched = lthread_get_sched();
    return kevent(sched->poller, sched->changelist, sched->nevents,
        sched->eventlist, LT_MAX_EVENTS, &t);
}
Exemple #10
0
static inline int
_lthread_connect(int fd, struct sockaddr *name, socklen_t namelen,
    uint64_t timeout)
{
    LTHREAD_SOCKET_CHECK_SCHED(connect(fd, name, namelen));
    int ret = 0;
    struct lthread *lt = lthread_get_sched()->current_lthread;

    while (1) {
        _lthread_renice(lt);
        ret = connect(fd, name, namelen);
        if (ret == 0)
            break;
        if (ret == -1 && (errno == EAGAIN || 
            errno == EWOULDBLOCK ||
            errno == EINPROGRESS)) {
            _lthread_sched_event(lt, fd, LT_EV_WRITE, timeout);
            if (lt->state & BIT(LT_ST_EXPIRED)) {
                errno = ETIMEDOUT;
                return (-1);
            }

            continue;
        } else {
            break;
        }
    }

    return (ret);
}
Exemple #11
0
inline void
register_wr_interest(int fd)
{
    sched_t *sched = lthread_get_sched();
    EV_SET(&sched->changelist[sched->nevents++], fd, EVFILT_WRITE,
        EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, sched->current_lthread);
    sched->current_lthread->state |= bit(LT_WAIT_WRITE);
}
Exemple #12
0
inline int
_lthread_poller_poll(struct timespec t)
{
    struct lthread_sched *sched = lthread_get_sched();

    return (epoll_wait(sched->poller_fd, sched->eventlist, LT_MAX_EVENTS,
        t.tv_sec*1000.0 + t.tv_nsec/1000000.0));
}
Exemple #13
0
void
cmd_ls(cmd_opt_t *cmd)
{
	char *tmp = lthread_summary(lthread_get_sched(cmd->lt));
	lthread_send(cmd->lt, cmd->fd, tmp, strlen(tmp), 0);
	free(tmp);

	return;
}
Exemple #14
0
int lthread_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
    if (timeout == 0)
        return poll(fds, nfds, 0);

    LTHREAD_SOCKET_CHECK_SCHED(poll(fds, nfds, timeout));
    struct lthread *lt = lthread_get_sched()->current_lthread;
    _lthread_renice(lt); /* doubt if it's necessary */

    return _lthread_sched_events_poll(lt, fds, nfds, timeout);
}
Exemple #15
0
int
lthread_close(int fd)
{
    lthread_t *lt = lthread_get_sched()->current_lthread;
    
    close(fd);
    _desched_lthread(lt);
    clear_rd_wr_state(lt);

    return 0;
}
Exemple #16
0
inline void
_lthread_poller_ev_clear_wr(int fd)
{
    struct epoll_event ev;
    int ret = 0;
    struct lthread_sched *sched = lthread_get_sched();

    ev.data.u64 = 0;
    ev.data.fd = fd;
    ev.events = EPOLLOUT | EPOLLONESHOT | EPOLLRDHUP;
    ret = epoll_ctl(sched->poller_fd, EPOLL_CTL_DEL, fd, &ev);
    assert(ret != -1);
}
Exemple #17
0
inline void
_lthread_poller_ev_clear_rd(int fd)
{
    struct epoll_event ev;
    int ret = 0;
    struct lthread_sched *sched = lthread_get_sched();

    ev.data.u64 = 0; /* without it, there s uninitialised variable warning with valgrind */
    ev.data.fd = fd;
    ev.events = EPOLLIN | EPOLLONESHOT | EPOLLRDHUP;
    ret = epoll_ctl(sched->poller_fd, EPOLL_CTL_DEL, fd, &ev);
    assert(ret != -1);
}
Exemple #18
0
int
lthread_close(int fd)
{
    LTHREAD_SOCKET_CHECK_SCHED(close(fd));
    struct lthread *lt = NULL;

    /* wake up the lthreads waiting on this fd and notify them of close */
    lt = _lthread_desched_event(fd, LT_EV_READ);
    if (lt) {
        TAILQ_INSERT_TAIL(&lthread_get_sched()->ready, lt, ready_next);
        lt->state |= BIT(LT_ST_FDEOF);
    }

    lt = _lthread_desched_event(fd, LT_EV_WRITE);
    if (lt) {
        TAILQ_INSERT_TAIL(&lthread_get_sched()->ready, lt, ready_next);
        lt->state |= BIT(LT_ST_FDEOF);
    }

    /* closing fd removes its registered events from poller */ 
    return (close(fd));
}
Exemple #19
0
inline void
_lthread_poller_ev_register_rd(int fd)
{
    struct epoll_event ev;
    int ret = 0;
    struct lthread_sched *sched = lthread_get_sched();

    ev.events = EPOLLIN | EPOLLONESHOT | EPOLLRDHUP;
    ev.data.u64 = 0;
    ev.data.fd = fd;
    ret = epoll_ctl(sched->poller_fd, EPOLL_CTL_MOD, fd, &ev);
    if (ret < 0)
        ret = epoll_ctl(sched->poller_fd, EPOLL_CTL_ADD, fd, &ev);
    assert(ret != -1);
}
Exemple #20
0
inline void
_lthread_poller_ev_register_trigger(void)
{
    struct lthread_sched *sched = lthread_get_sched();
    int ret = 0;
    struct epoll_event ev;

    if (!sched->eventfd) {
        sched->eventfd = eventfd(0, EFD_NONBLOCK);
        assert(sched->eventfd != -1);
    }
    ev.events = EPOLLIN;
    ev.data.u64 = 0;
    ev.data.fd = sched->eventfd;
    ret = epoll_ctl(sched->poller_fd, EPOLL_CTL_ADD, sched->eventfd, &ev);
    assert(ret != -1);
}
Exemple #21
0
inline void
clear_interest(int fd)
{
    struct kevent change;
    struct kevent event;
    struct timespec tm = {0, 0};
    int ret = 0;
    sched_t *sched = lthread_get_sched();

    //printf("sched is %p and fd is %d\n", sched, fd);
    /*EV_SET(&sched->changelist[sched->nevents++],
        fd, 0, EV_DELETE, 0, 0, NULL);*/
    EV_SET(&change, fd, EVFILT_READ|EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
    ret = kevent(sched->poller, &change, 1, &event, 0, &tm);
    //assert(ret == 0);

}
Exemple #22
0
int
lthread_accept(int fd, struct sockaddr *addr, socklen_t *len)
{
    LTHREAD_SOCKET_CHECK_SCHED(accept(fd, addr, len));
    int ret = -1;
    struct lthread *lt = lthread_get_sched()->current_lthread;

    while (1) {
        _lthread_renice(lt);
        ret = accept(fd, addr, len);
        if (ret == -1 && 
            (errno == ENFILE || 
            errno == EWOULDBLOCK ||
            errno == EMFILE)) {
            _lthread_sched_event(lt, fd, LT_EV_READ, 0);
            continue;
        }

        if (ret > 0)
            break;

        if (ret == -1 && errno == ECONNABORTED)  {
            perror("Cannot accept connection");
            continue;
        }

        if (ret == -1 && errno != EWOULDBLOCK) {
            fprintf(stderr, "Cannot accept connection on %d: %s\n", fd, strerror(errno));
            return (-1);
        }

    }

#ifndef __FreeBSD__
    if ((fcntl(ret, F_SETFL, O_NONBLOCK)) == -1) {
        close(ret);
        perror("Failed to set socket properties");
        return (-1);
    }
#endif

    return (ret);
}
Exemple #23
0
int
lthread_accept(int fd, struct sockaddr *addr, socklen_t *len)
{
    int ret = -1;
    lthread_t *lt = lthread_get_sched()->current_lthread;

    while (1) {
        _lthread_renice(lt);
        ret = accept(fd, addr, len);
        if (ret == -1 && 
            (errno == ENFILE || 
            errno == EWOULDBLOCK ||
            errno == EMFILE)) {
            _lthread_wait_for(lt, fd, LT_READ);
            continue;
        }

        if (ret > 0)
            break;

        if (ret == -1 && errno == ECONNABORTED)  {
            perror("Cannot accept connection");
            continue;
        }

        if (ret == -1 && errno != EWOULDBLOCK) {
            perror("Cannot accept connection");
            return -1;
        }

    }

#ifndef __FreeBSD__
    if ((fcntl(ret, F_SETFL, O_NONBLOCK)) == -1) {
        close(fd);
        perror("Failed to set socket properties");
        return -1;
    }
#endif

    return ret;
}
Exemple #24
0
int
lthread_poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
    int i = 0;
    if (timeout == 0)
        return poll(fds, nfds, 0);

    struct lthread *lt = lthread_get_sched()->current_lthread;
    /* schedule fd events, pass -1 to avoid yielding */
    for (i = 0; i < nfds; i++) {
        if (fds[i].events & POLLIN)
            _lthread_sched_event(lt, fds[i].fd, LT_EV_READ, -1);
        else if (fds[i].events & POLLOUT)
            _lthread_sched_event(lt, fds[i].fd, LT_EV_WRITE, -1);
        else
            assert(0);
    }

    lt->ready_fds = 0;
    lt->fd_wait = -1;
    /* clear wait_read/write flags set by _lthread_sched_event */
    lt->state &= CLEARBIT(LT_ST_WAIT_READ);
    lt->state &= CLEARBIT(LT_ST_WAIT_WRITE);
    /* we are waiting on multiple fd events */
    lt->state |= BIT(LT_ST_WAIT_MULTI);

    lt->pollfds = fds;
    lt->nfds = nfds;

    /* go to sleep until one or more of the fds are ready or until we timeout */
    _lthread_sched_sleep(lt, (uint64_t)timeout);

    lt->pollfds = NULL;
    lt->nfds = 0;
    lt->state &= CLEARBIT(LT_ST_WAIT_MULTI);

    if (lt->state & BIT(LT_ST_EXPIRED))
        return (0);

    return (lt->ready_fds);
}