diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-01-04 18:30:33 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-01-04 18:30:33 -0800 |
| commit | 40da92f0fffc7b69f876ca060d9b4e6682e45a8c (patch) | |
| tree | 3147f840adc3815dd55693e440380992f76b1ba9 /src/platform/posix/posix_net.c | |
| parent | c1d11425846baf22e9a07b0f2bf2ad405e0b42e5 (diff) | |
| download | nng-40da92f0fffc7b69f876ca060d9b4e6682e45a8c.tar.gz nng-40da92f0fffc7b69f876ca060d9b4e6682e45a8c.tar.bz2 nng-40da92f0fffc7b69f876ca060d9b4e6682e45a8c.zip | |
Fix close related races (POSIX close is a PITA).
Diffstat (limited to 'src/platform/posix/posix_net.c')
| -rw-r--r-- | src/platform/posix/posix_net.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/src/platform/posix/posix_net.c b/src/platform/posix/posix_net.c index d0cfb49c..151e14f1 100644 --- a/src/platform/posix/posix_net.c +++ b/src/platform/posix/posix_net.c @@ -231,12 +231,35 @@ nni_plat_tcp_setopts(int fd) void -nni_plat_tcp_close(nni_plat_tcpsock *s) +nni_plat_tcp_init(nni_plat_tcpsock *s) { - (void) close(s->fd); s->fd = -1; } + +void +nni_plat_tcp_fini(nni_plat_tcpsock *s) +{ + if (s->fd != -1) { + (void) close(s->fd); + s->fd = -1; + } +} + + +void +nni_plat_tcp_shutdown(nni_plat_tcpsock *s) +{ + if (s->fd != -1) { + (void) shutdown(s->fd, SHUT_RDWR); + // This causes the equivalent of a close. Hopefully waking + // up anything that didn't get the hint with the shutdown. + // (macOS does not see the shtudown). + (void) dup2(nni_plat_devnull, s->fd); + } +} + + // nni_plat_tcp_bind creates a file descriptor bound to the given address. // This basically does the equivalent of socket, bind, and listen. We have // chosen a default value for the listen backlog of 128, which should be @@ -257,7 +280,7 @@ nni_plat_tcp_listen(nni_plat_tcpsock *s, const nni_sockaddr *addr) } #ifdef SOCK_CLOEXEC - fd = socket(ss.ss_family, SOCK_STREAM, SOCK_CLOEXEC); + fd = socket(ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0); #else fd = socket(ss.ss_family, SOCK_STREAM, 0); #endif @@ -305,7 +328,7 @@ nni_plat_tcp_connect(nni_plat_tcpsock *s, const nni_sockaddr *addr, } #ifdef SOCK_CLOEXEC - fd = socket(ss.ss_family, SOCK_STREAM, SOCK_CLOEXEC); + fd = socket(ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0); #else fd = socket(ss.ss_family, SOCK_STREAM, 0); #endif @@ -346,9 +369,9 @@ nni_plat_tcp_accept(nni_plat_tcpsock *s, nni_plat_tcpsock *server) for (;;) { #ifdef NNG_USE_ACCEPT4 - fd = accept4(server, NULL, NULL, SOCK_CLOEXEC); + fd = accept4(server->fd, NULL, NULL, SOCK_CLOEXEC); if ((fd < 0) && ((errrno == ENOSYS) || (errno == ENOTSUP))) { - fd = accept(server, NULL, NULL); + fd = accept(server->fd, NULL, NULL); } #else fd = accept(server->fd, NULL, NULL); @@ -359,6 +382,9 @@ nni_plat_tcp_accept(nni_plat_tcpsock *s, nni_plat_tcpsock *server) // These are not fatal errors, keep trying continue; } + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + continue; + } return (nni_plat_errno(errno)); } else { break; |
