Merge pull request #12367 from keszybz/accept-check
Put a limit on the loop to flush connections
This commit is contained in:
commit
0a6001c134
|
@ -1219,6 +1219,10 @@ fallback:
|
|||
return (ssize_t) k;
|
||||
}
|
||||
|
||||
/* Put a limit on how many times will attempt to call accept4(). We loop
|
||||
* only on "transient" errors, but let's make sure we don't loop forever. */
|
||||
#define MAX_FLUSH_ITERATIONS 1024
|
||||
|
||||
int flush_accept(int fd) {
|
||||
|
||||
struct pollfd pollfd = {
|
||||
|
@ -1228,21 +1232,21 @@ int flush_accept(int fd) {
|
|||
int r, b;
|
||||
socklen_t l = sizeof(b);
|
||||
|
||||
/* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately
|
||||
* closing them. */
|
||||
/* Similar to flush_fd() but flushes all incoming connections by accepting and immediately closing
|
||||
* them. */
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &b, &l) < 0)
|
||||
return -errno;
|
||||
|
||||
assert(l == sizeof(b));
|
||||
if (!b) /* Let's check if this is a socket accepting connections before calling accept(). That's
|
||||
* because accept4() can return EOPNOTSUPP in the fd we are called on is not a listening
|
||||
* socket, or in case the incoming TCP connection transiently triggered that (see accept(2)
|
||||
* man page for details). The latter case is a transient error we should continue looping
|
||||
* on. The former case however is fatal. */
|
||||
if (!b) /* Let's check if this socket accepts connections before calling accept(). accept4() can
|
||||
* return EOPNOTSUPP if the fd is not a listening socket, which we should treat as a fatal
|
||||
* error, or in case the incoming TCP connection triggered a network issue, which we want to
|
||||
* treat as a transient error. Thus, let's rule out the first reason for EOPNOTSUPP early, so
|
||||
* we can loop safely on transient errors below. */
|
||||
return -ENOTTY;
|
||||
|
||||
for (;;) {
|
||||
for (unsigned iteration = 0;; iteration++) {
|
||||
int cfd;
|
||||
|
||||
r = poll(&pollfd, 1, 0);
|
||||
|
@ -1255,6 +1259,10 @@ int flush_accept(int fd) {
|
|||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
if (iteration >= MAX_FLUSH_ITERATIONS)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBUSY),
|
||||
"Failed to flush connections within " STRINGIFY(MAX_FLUSH_ITERATIONS) " iterations.");
|
||||
|
||||
cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
|
||||
if (cfd < 0) {
|
||||
if (errno == EAGAIN)
|
||||
|
|
Loading…
Reference in a new issue