From f4ce5a285167e7656037096f77f04ab80a010453 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sat, 14 Jan 2017 13:00:55 -0800 Subject: Windows TCP now working. There are lots of changes here, mostly stuff we did in support of Windows TCP. However, there are some bugs that were fixed, and we added some new error codes, and generalized the handling of some failures during accept. Windows IPC (NamedPipes) is still missing. --- src/platform/posix/posix_debug.c | 61 +++++++++++++++++++-------------------- src/platform/posix/posix_ipc.c | 7 +++-- src/platform/posix/posix_net.c | 34 ++++++++-------------- src/platform/posix/posix_thread.c | 23 ++++++++++++++- 4 files changed, 68 insertions(+), 57 deletions(-) (limited to 'src/platform/posix') diff --git a/src/platform/posix/posix_debug.c b/src/platform/posix/posix_debug.c index 71006b25..6199df1d 100644 --- a/src/platform/posix/posix_debug.c +++ b/src/platform/posix/posix_debug.c @@ -40,8 +40,6 @@ nni_plat_strerror(int errnum) } -#define NNI_ERR(x, y) { x, y }, - // There are of course other errors than these, but these are the ones // that we might reasonably expect and want to handle "cleanly". Most of // the others should be handled by the system error code. Note that EFAULT @@ -55,35 +53,36 @@ static struct { int nng_err; } nni_plat_errnos[] = { - NNI_ERR(EINTR, NNG_EINTR) - NNI_ERR(EINVAL, NNG_EINVAL) - NNI_ERR(ENOMEM, NNG_ENOMEM) - NNI_ERR(EACCES, NNG_EPERM) - NNI_ERR(EADDRINUSE, NNG_EADDRINUSE) - NNI_ERR(EADDRNOTAVAIL, NNG_EADDRINVAL) - NNI_ERR(EAFNOSUPPORT, NNG_ENOTSUP) - NNI_ERR(EAGAIN, NNG_EAGAIN) - NNI_ERR(EBADF, NNG_ECLOSED) - NNI_ERR(EBUSY, NNG_EBUSY) - NNI_ERR(ECONNABORTED, NNG_ECLOSED) - NNI_ERR(ECONNREFUSED, NNG_ECONNREFUSED) - NNI_ERR(ECONNRESET, NNG_ECLOSED) - NNI_ERR(EHOSTUNREACH, NNG_EUNREACHABLE) - NNI_ERR(ENETUNREACH, NNG_EUNREACHABLE) - NNI_ERR(ENAMETOOLONG, NNG_EINVAL) - NNI_ERR(ENOENT, NNG_ENOENT) - NNI_ERR(ENOBUFS, NNG_ENOMEM) - NNI_ERR(ENOPROTOOPT, NNG_ENOTSUP) - NNI_ERR(ENOSYS, NNG_ENOTSUP) - NNI_ERR(ENOTSUP, NNG_ENOTSUP) - NNI_ERR(EPERM, NNG_EPERM) - NNI_ERR(EPIPE, NNG_ECLOSED) - NNI_ERR(EPROTO, NNG_EPROTO) - NNI_ERR(EPROTONOSUPPORT, NNG_ENOTSUP) - NNI_ERR(ETIME, NNG_ETIMEDOUT) - NNI_ERR(ETIMEDOUT, NNG_ETIMEDOUT) - NNI_ERR(EWOULDBLOCK, NNG_EAGAIN) - NNI_ERR(0, 0) // must be last + { EINTR, NNG_EINTR }, + { EINVAL, NNG_EINVAL }, + { ENOMEM, NNG_ENOMEM }, + { EACCES, NNG_EPERM }, + { EADDRINUSE, NNG_EADDRINUSE }, + { EADDRNOTAVAIL, NNG_EADDRINVAL }, + { EAFNOSUPPORT, NNG_ENOTSUP }, + { EAGAIN, NNG_EAGAIN }, + { EBADF, NNG_ECLOSED }, + { EBUSY, NNG_EBUSY }, + { ECONNABORTED, NNG_ECONNABORTED }, + { ECONNREFUSED, NNG_ECONNREFUSED }, + { ECONNRESET, NNG_ECONNRESET }, + { EHOSTUNREACH, NNG_EUNREACHABLE }, + { ENETUNREACH, NNG_EUNREACHABLE }, + { ENAMETOOLONG, NNG_EINVAL }, + { ENOENT, NNG_ENOENT }, + { ENOBUFS, NNG_ENOMEM }, + { ENOPROTOOPT, NNG_ENOTSUP }, + { ENOSYS, NNG_ENOTSUP }, + { ENOTSUP, NNG_ENOTSUP }, + { EPERM, NNG_EPERM }, + { EPIPE, NNG_ECLOSED }, + { EPROTO, NNG_EPROTO }, + { EPROTONOSUPPORT, NNG_ENOTSUP }, + { ETIME, NNG_ETIMEDOUT }, + { ETIMEDOUT, NNG_ETIMEDOUT }, + { EWOULDBLOCK, NNG_EAGAIN }, + // must be last + { 0, 0 }, }; int diff --git a/src/platform/posix/posix_ipc.c b/src/platform/posix/posix_ipc.c index 8c40397a..6044280e 100644 --- a/src/platform/posix/posix_ipc.c +++ b/src/platform/posix/posix_ipc.c @@ -73,7 +73,7 @@ nni_plat_ipc_send(nni_plat_ipcsock *s, nni_iov *iovs, int cnt) i = 0; while (resid) { - rv = writev(s->fd, iov, cnt); + rv = writev(s->fd, &iov[i], cnt); if (rv < 0) { if (rv == EINTR) { continue; @@ -121,7 +121,7 @@ nni_plat_ipc_recv(nni_plat_ipcsock *s, nni_iov *iovs, int cnt) } i = 0; while (resid) { - rv = readv(s->fd, iov, cnt); + rv = readv(s->fd, &iov[i], cnt); if (rv < 0) { if (errno == EINTR) { continue; @@ -171,10 +171,11 @@ nni_plat_ipc_setopts(int fd) } -void +int nni_plat_ipc_init(nni_plat_ipcsock *s) { s->fd = -1; + return (0); } diff --git a/src/platform/posix/posix_net.c b/src/platform/posix/posix_net.c index 76a40259..f9720b66 100644 --- a/src/platform/posix/posix_net.c +++ b/src/platform/posix/posix_net.c @@ -23,6 +23,12 @@ #include #include +#ifdef SOCK_CLOEXEC +#define NNI_TCP_SOCKTYPE (SOCK_STREAM | SOCK_CLOEXEC) +#else +#define NNI_TCP_SOCKTYPE SOCK_STREAM +#endif + static int nni_plat_to_sockaddr(struct sockaddr_storage *ss, const nni_sockaddr *sa) { @@ -128,7 +134,7 @@ nni_plat_tcp_send(nni_plat_tcpsock *s, nni_iov *iovs, int cnt) i = 0; while (resid) { - rv = writev(s->fd, iov, cnt); + rv = writev(s->fd, &iov[i], cnt); if (rv < 0) { if (rv == EINTR) { continue; @@ -177,7 +183,7 @@ nni_plat_tcp_recv(nni_plat_tcpsock *s, nni_iov *iovs, int cnt) i = 0; while (resid) { - rv = readv(s->fd, iov, cnt); + rv = readv(s->fd, &iov[i], cnt); if (rv < 0) { if (errno == EINTR) { continue; @@ -233,10 +239,11 @@ nni_plat_tcp_setopts(int fd) } -void +int nni_plat_tcp_init(nni_plat_tcpsock *s) { s->fd = -1; + return (0); } @@ -282,12 +289,7 @@ nni_plat_tcp_listen(nni_plat_tcpsock *s, const nni_sockaddr *addr) return (NNG_EADDRINVAL); } -#ifdef SOCK_CLOEXEC - fd = socket(ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0); -#else - fd = socket(ss.ss_family, SOCK_STREAM, 0); -#endif - if (fd < 0) { + if ((fd = socket(ss.ss_family, NNI_TCP_SOCKTYPE, 0)) < 0) { return (nni_plat_errno(errno)); } @@ -330,12 +332,7 @@ nni_plat_tcp_connect(nni_plat_tcpsock *s, const nni_sockaddr *addr, return (NNG_EADDRINVAL); } -#ifdef SOCK_CLOEXEC - fd = socket(ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0); -#else - fd = socket(ss.ss_family, SOCK_STREAM, 0); -#endif - if (fd < 0) { + if ((fd = socket(ss.ss_family, NNI_TCP_SOCKTYPE, 0)) < 0) { return (nni_plat_errno(errno)); } @@ -381,13 +378,6 @@ nni_plat_tcp_accept(nni_plat_tcpsock *s, nni_plat_tcpsock *server) #endif if (fd < 0) { - if ((errno == EINTR) || (errno == ECONNABORTED)) { - // These are not fatal errors, keep trying - continue; - } - if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - continue; - } return (nni_plat_errno(errno)); } else { break; diff --git a/src/platform/posix/posix_thread.c b/src/platform/posix/posix_thread.c index a429e071..7b4dbbdc 100644 --- a/src/platform/posix/posix_thread.c +++ b/src/platform/posix/posix_thread.c @@ -28,6 +28,7 @@ static int nni_plat_forked = 0; pthread_condattr_t nni_cvattr; pthread_mutexattr_t nni_mxattr; +static pthread_attr_t nni_pthread_attr; // We open a /dev/null file descriptor so that we can dup2() it to // cause MacOS X to wakeup. This gives us a "safe" close semantic. @@ -189,7 +190,8 @@ nni_plat_thr_init(nni_plat_thr *thr, void (*fn)(void *), void *arg) thr->arg = arg; // POSIX wants functions to return a void *, but we don't care. - rv = pthread_create(&thr->tid, NULL, nni_plat_thr_main, thr); + rv = pthread_create(&thr->tid, &nni_pthread_attr, + nni_plat_thr_main, thr); if (rv != 0) { //nni_printf("pthread_create: %s", strerror(rv)); return (NNG_ENOMEM); @@ -263,9 +265,27 @@ nni_plat_init(int (*helper)(void)) return (NNG_ENOMEM); } + rv = pthread_attr_init(&nni_pthread_attr); + if (rv != 0) { + pthread_mutex_unlock(&nni_plat_lock); + (void) close(nni_plat_devnull); + pthread_mutexattr_destroy(&nni_mxattr); + pthread_condattr_destroy(&nni_cvattr); + return (NNG_ENOMEM); + } + + // We don't force this, but we want to have it small... we could + // probably get by with even just 8k, but Linux usually wants 16k + // as a minimum. If this fails, its not fatal, just we won't be + // as scalable / thrifty with our use of VM. + (void) pthread_attr_setstacksize(&nni_pthread_attr, 16384); + if (pthread_atfork(NULL, NULL, nni_atfork_child) != 0) { pthread_mutex_unlock(&nni_plat_lock); (void) close(nni_plat_devnull); + pthread_mutexattr_destroy(&nni_mxattr); + pthread_condattr_destroy(&nni_cvattr); + pthread_attr_destroy(&nni_pthread_attr); return (NNG_ENOMEM); } if ((rv = helper()) == 0) { @@ -284,6 +304,7 @@ nni_plat_fini(void) if (nni_plat_inited) { pthread_mutexattr_destroy(&nni_mxattr); pthread_condattr_destroy(&nni_cvattr); + pthread_attr_destroy(&nni_pthread_attr); (void) close(nni_plat_devnull); nni_plat_devnull = -1; nni_plat_inited = 0; -- cgit v1.2.3-70-g09d2