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; }
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); }
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; }
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); }
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); }
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); }
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); }
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; }