fixes #922 Client wakes up every 100ms in the pubsub demo
diff --git a/src/core/sock.c b/src/core/sock.c
index e257ca9..da32930 100644
--- a/src/core/sock.c
+++ b/src/core/sock.c
@@ -1,7 +1,8 @@
/*
Copyright (c) 2012-2014 Martin Sustrik All rights reserved.
Copyright (c) 2013 GoPivotal, Inc. All rights reserved.
- Copyright 2016 Garrett D'Amore <garrett@damore.org>
+ Copyright 2017 Garrett D'Amore <garrett@damore.org>
+ Copyright 2017 Capitar IT Group BV <info@capitar.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
@@ -223,6 +224,14 @@
/* At this point, we can be reasonably certain that no other thread
has any references to the socket. */
+ /* Close the event FDs entirely. */
+ if (!(self->socktype->flags & NN_SOCKTYPE_FLAG_NORECV)) {
+ nn_efd_term (&self->rcvfd);
+ }
+ if (!(self->socktype->flags & NN_SOCKTYPE_FLAG_NOSEND)) {
+ nn_efd_term (&self->sndfd);
+ }
+
nn_fsm_stopped_noevent (&self->fsm);
nn_fsm_term (&self->fsm);
nn_sem_term (&self->termsem);
@@ -904,14 +913,6 @@
sock->sockbase->vfptr->destroy (sock->sockbase);
sock->state = NN_SOCK_STATE_FINI;
- /* Close the event FDs entirely. */
- if (!(sock->socktype->flags & NN_SOCKTYPE_FLAG_NORECV)) {
- nn_efd_term (&sock->rcvfd);
- }
- if (!(sock->socktype->flags & NN_SOCKTYPE_FLAG_NOSEND)) {
- nn_efd_term (&sock->sndfd);
- }
-
/* Now we can unblock the application thread blocked in
the nn_close() call. */
nn_sem_post (&sock->termsem);
diff --git a/src/utils/efd.c b/src/utils/efd.c
index b4ff4ba..04d53e3 100644
--- a/src/utils/efd.c
+++ b/src/utils/efd.c
@@ -1,7 +1,9 @@
/*
Copyright (c) 2012-2013 Martin Sustrik All rights reserved.
- Copyright 2016 Garrett D'Amore <garrett@damore.org>
Copyright (c) 2015-2016 Jack R. Dunaway. All rights reserved.
+ Copyright 2017 Garrett D'Amore <garrett@damore.org>
+ Copyright 2017 Capitar IT Group BV <info@capitar.com>
+
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
@@ -45,60 +47,20 @@
{
int rc;
struct pollfd pfd;
- uint64_t expire;
- if (timeout > 0) {
- expire = nn_clock_ms() + timeout;
- } else {
- expire = timeout;
+ pfd.fd = nn_efd_getfd (self);
+ pfd.events = POLLIN;
+ if (pfd.fd < 0)
+ return -EBADF;
+
+ rc = poll (&pfd, 1, timeout);
+ switch (rc) {
+ case 0:
+ return -ETIMEDOUT;
+ case -1:
+ return (-errno);
}
-
- /* In order to solve a problem where the poll call doesn't wake up
- when a file is closed, we sleep a maximum of 100 msec. This is
- a somewhat unfortunate band-aid to prevent hangs caused by a race
- condition involving nn_close. In the future this code should be
- replaced by a simpler design using condition variables. */
- for (;;) {
- pfd.fd = nn_efd_getfd (self);
- pfd.events = POLLIN;
- if (nn_slow (pfd.fd < 0))
- return -EBADF;
-
- switch (expire) {
- case 0:
- /* poll once */
- timeout = 0;
- break;
-
- case (uint64_t)-1:
- /* infinite wait */
- timeout = 100;
- break;
-
- default:
- /* bounded wait */
- timeout = (int)(expire - nn_clock_ms());
- if (timeout < 0) {
- return -ETIMEDOUT;
- }
- if (timeout > 100) {
- timeout = 100;
- }
- }
- rc = poll (&pfd, 1, timeout);
- if (nn_slow (rc < 0 && errno == EINTR))
- return -EINTR;
- errno_assert (rc >= 0);
- if (nn_slow (rc == 0)) {
- if (expire == 0)
- return -ETIMEDOUT;
- if ((expire != (uint64_t)-1) && (expire < nn_clock_ms())) {
- return -ETIMEDOUT;
- }
- continue;
- }
- return 0;
- }
+ return 0;
}
#elif defined NN_HAVE_WINDOWS
@@ -106,68 +68,31 @@
int nn_efd_wait (struct nn_efd *self, int timeout)
{
int rc;
- struct timeval tv;
- SOCKET fd = self->r;
- uint64_t expire;
+ WSAPOLLFD pfd;
- if (timeout > 0) {
- expire = nn_clock_ms() + timeout;
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = timeout % 1000 * 1000;
- } else {
- expire = timeout;
+ pfd.fd = self->r;
+ if (nn_slow (pfd.fd == INVALID_SOCKET)) {
+ return -EBADF;
}
+ pfd.events = POLLIN;
+ rc = WSAPoll(&pfd, 1, timeout);
- for (;;) {
- if (nn_slow (fd == INVALID_SOCKET)) {
- return -EBADF;
+ switch (rc) {
+ case 0:
+ return -ETIMEDOUT;
+ case SOCKET_ERROR:
+ rc = nn_err_wsa_to_posix (WSAGetLastError ());
+ errno = rc;
+
+ /* Treat these as a non-fatal errors, typically occuring when the
+ socket is being closed from a separate thread during a blocking
+ I/O operation. */
+ if (rc == EINTR || rc == ENOTSOCK) {
+ return self->r == INVALID_SOCKET ? -EBADF : -EINTR;
}
- FD_SET (fd, &self->fds);
- switch (expire) {
- case 0:
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- break;
- case (uint64_t)-1:
- tv.tv_sec = 0;
- tv.tv_usec = 100000;
- break;
- default:
- timeout = (int)(expire - nn_clock_ms());
- if (timeout < 0) {
- return -ETIMEDOUT;
- }
- if (timeout > 100) {
- tv.tv_sec = 0;
- tv.tv_usec = 100000;
- } else {
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = timeout % 1000 * 1000;
- }
- }
- rc = select (0, &self->fds, NULL, NULL, &tv);
-
- if (nn_slow (rc == SOCKET_ERROR)) {
- rc = nn_err_wsa_to_posix (WSAGetLastError ());
- errno = rc;
-
- /* Treat these as a non-fatal errors, typically occuring when the
- socket is being closed from a separate thread during a blocking
- I/O operation. */
- if (rc == EINTR || rc == ENOTSOCK)
- return self->r == INVALID_SOCKET ? -EBADF : -EINTR;
- } else if (rc == 0) {
- if (expire == 0)
- return -ETIMEDOUT;
- if ((expire != (uint64_t)-1) && (expire < nn_clock_ms())) {
- return -ETIMEDOUT;
- }
- continue;
- }
-
- wsa_assert (rc >= 0);
- return 0;
+ return (-rc);
}
+ return (0);
}
#else
diff --git a/src/utils/efd_win.h b/src/utils/efd_win.h
index 988d4fe..360502a 100644
--- a/src/utils/efd_win.h
+++ b/src/utils/efd_win.h
@@ -1,5 +1,7 @@
/*
Copyright (c) 2012-2013 Martin Sustrik All rights reserved.
+ Copyright 2017 Garrett D'Amore <garrett@damore.org>
+ Copyright 2017 Capitar IT Group BV <info@capitar.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
@@ -25,6 +27,5 @@
struct nn_efd {
SOCKET r;
SOCKET w;
- fd_set fds;
};
diff --git a/src/utils/efd_win.inc b/src/utils/efd_win.inc
index 03abbb1..3a7ea66 100644
--- a/src/utils/efd_win.inc
+++ b/src/utils/efd_win.inc
@@ -1,6 +1,8 @@
/*
Copyright (c) 2012-2013 Martin Sustrik All rights reserved.
- Copyright 2015 Garrett D'Amore <garrett@damore.org>
+ Copyright 2017 Garrett D'Amore <garrett@damore.org>
+ Copyright 2017 Capitar IT Group BV <info@capitar.com>
+
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
@@ -186,9 +188,6 @@
rc = ioctlsocket (self->r, FIONBIO, &nonblock);
wsa_assert (rc != SOCKET_ERROR);
- /* Initialise the pre-allocated pollset. */
- FD_ZERO (&self->fds);
-
return 0;
wsafail: