aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2018-06-15 18:43:08 +0200
committerSverker Eriksson <[email protected]>2018-06-15 18:43:08 +0200
commit360b68d76d8c297d950616f088458b7c239be7ee (patch)
tree033e1dd3adf83cb8622d0dfcd74f0d0f563408e0 /erts
parentd6cd7d17e3b0dbcb9aac7bddb4bda31ffe4b598e (diff)
parentac9ed8e2575dca9e5ebe2f7af00dfe4da87b1bcc (diff)
downloadotp-360b68d76d8c297d950616f088458b7c239be7ee.tar.gz
otp-360b68d76d8c297d950616f088458b7c239be7ee.tar.bz2
otp-360b68d76d8c297d950616f088458b7c239be7ee.zip
Merge branch 'sverker/macos-select-fd-bug'
* sverker/macos-select-fd-bug: erts: Fix MacOS pollset bug
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/sys/common/erl_poll.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index ced8a4a2a7..e3f27caea7 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -141,12 +141,26 @@ typedef struct {
size_t sz;
fd_set* ptr;
}ERTS_fd_set;
-# define ERTS_FD_CLR(fd, fds) FD_CLR((fd), (fds)->ptr)
-# define ERTS_FD_SET(fd, fds) FD_SET((fd), (fds)->ptr)
-# define ERTS_FD_ISSET(fd,fds) FD_ISSET((fd), (fds)->ptr)
+
# define ERTS_FD_ZERO(fds) memset((fds)->ptr, 0, (fds)->sz)
# define ERTS_FD_SIZE(n) ((((n)+NFDBITS-1)/NFDBITS)*sizeof(fd_mask))
+static ERTS_INLINE void ERTS_FD_CLR(int fd, ERTS_fd_set *fds)
+{
+ ASSERT(ERTS_FD_SIZE(fd+1) <= fds->sz);
+ FD_CLR(fd, fds->ptr);
+}
+static ERTS_INLINE void ERTS_FD_SET(int fd, ERTS_fd_set *fds)
+{
+ ASSERT(ERTS_FD_SIZE(fd+1) <= fds->sz);
+ FD_SET(fd, fds->ptr);
+}
+static ERTS_INLINE int ERTS_FD_ISSET(int fd, ERTS_fd_set *fds)
+{
+ ASSERT(ERTS_FD_SIZE(fd+1) <= fds->sz);
+ return FD_ISSET(fd, fds->ptr);
+}
+
static void ERTS_FD_COPY(ERTS_fd_set *src, ERTS_fd_set *dst)
{
if (dst->sz != src->sz) {
@@ -626,8 +640,15 @@ ensure_select_fds(int fd, ERTS_fd_set* in, ERTS_fd_set* out)
grow_select_fds(fd, out);
}
}
+static ERTS_INLINE int
+check_select_fds(int fd, ERTS_fd_set* in, ERTS_fd_set* out)
+{
+ ASSERT(in->sz == out->sz);
+ return (ERTS_FD_SIZE(fd+1) <= in->sz);
+}
#else
# define ensure_select_fds(fd, in, out) do {} while(0)
+# define check_select_fds(fd, in, out) (1)
#endif /* _DARWIN_UNLIMITED_SELECT */
#if !ERTS_POLL_USE_CONCURRENT_UPDATE
@@ -1085,8 +1106,10 @@ static int update_pollset(ErtsPollSet *ps, ErtsPollResFd pr[], int fd)
res++;
}
- ERTS_FD_CLR(fd, &ps->input_fds);
- ERTS_FD_CLR(fd, &ps->output_fds);
+ if (check_select_fds(fd, &ps->input_fds, &ps->output_fds)) {
+ ERTS_FD_CLR(fd, &ps->input_fds);
+ ERTS_FD_CLR(fd, &ps->output_fds);
+ }
if (ps->fds_status[fd].used_events) {
erts_atomic_dec_nob(&ps->no_of_user_fds);