Skip to content

Commit 4af81f9

Browse files
committed
CDRIVER-756: Repeat the [WSA]poll() on failure until we get the event we want or hit the timeout
1 parent 68f6565 commit 4af81f9

File tree

1 file changed

+42
-20
lines changed

1 file changed

+42
-20
lines changed

src/mongoc/mongoc-socket.c

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -119,22 +119,12 @@ _mongoc_socket_wait (int sd, /* IN */
119119
#endif
120120
int ret;
121121
int timeout;
122+
int64_t now;
122123

123124
ENTRY;
124125

125126
bson_return_val_if_fail (events, false);
126127

127-
if (expire_at < 0) {
128-
timeout = -1;
129-
} else if (expire_at == 0) {
130-
timeout = 0;
131-
} else {
132-
timeout = (int)((expire_at - bson_get_monotonic_time ()) / 1000L);
133-
if (timeout < 0) {
134-
timeout = 0;
135-
}
136-
}
137-
138128
pfd.fd = sd;
139129
#ifdef _WIN32
140130
pfd.events = events;
@@ -143,25 +133,57 @@ _mongoc_socket_wait (int sd, /* IN */
143133
#endif
144134
pfd.revents = 0;
145135

136+
now = bson_get_monotonic_time();
137+
138+
for (;;) {
139+
if (expire_at < 0) {
140+
timeout = -1;
141+
} else if (expire_at == 0) {
142+
timeout = 0;
143+
} else {
144+
timeout = (int)((expire_at - now) / 1000L);
145+
if (timeout < 0) {
146+
timeout = 0;
147+
}
148+
}
149+
146150
#ifdef _WIN32
147-
ret = WSAPoll (&pfd, 1, timeout);
148-
if (ret == SOCKET_ERROR) {
151+
ret = WSAPoll (&pfd, 1, timeout);
152+
if (ret == SOCKET_ERROR) {
149153
errno = WSAGetLastError();
150154
ret = -1;
151-
}
155+
}
152156
#else
153-
ret = poll (&pfd, 1, timeout);
157+
ret = poll (&pfd, 1, timeout);
154158
#endif
155159

156-
if (ret > 0) {
160+
if (ret > 0) {
161+
/* Something happened, so return that */
157162
#ifdef _WIN32
158-
RETURN (0 != (pfd.revents & (events | POLLHUP | POLLERR)));
163+
RETURN (0 != (pfd.revents & (events | POLLHUP | POLLERR)));
159164
#else
160-
RETURN (0 != (pfd.revents & events));
165+
RETURN (0 != (pfd.revents & events));
161166
#endif
162-
}
167+
} else if (ret < 0) {
168+
/* poll itself failed */
169+
170+
if (MONGOC_ERRNO_IS_AGAIN(errno)) {
171+
now = bson_get_monotonic_time();
163172

164-
RETURN (false);
173+
if (expire_at < now) {
174+
RETURN (false);
175+
} else {
176+
continue;
177+
}
178+
} else {
179+
/* poll failed for some non-transient reason */
180+
RETURN (false);
181+
}
182+
} else {
183+
/* poll timed out */
184+
RETURN (false);
185+
}
186+
}
165187
}
166188

167189

0 commit comments

Comments
 (0)