aboutsummaryrefslogtreecommitdiff
path: root/src/platform/posix/posix_net.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-01-04 18:30:33 -0800
committerGarrett D'Amore <garrett@damore.org>2017-01-04 18:30:33 -0800
commit40da92f0fffc7b69f876ca060d9b4e6682e45a8c (patch)
tree3147f840adc3815dd55693e440380992f76b1ba9 /src/platform/posix/posix_net.c
parentc1d11425846baf22e9a07b0f2bf2ad405e0b42e5 (diff)
downloadnng-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.c38
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;