summaryrefslogtreecommitdiff
path: root/src/base
diff options
context:
space:
mode:
authorMitch Hayenga <mitch.hayenga+gem5@gmail.com>2014-01-28 18:00:51 -0600
committerMitch Hayenga <mitch.hayenga+gem5@gmail.com>2014-01-28 18:00:51 -0600
commit55a4ff5f04badfbd458aee48618920f7fa243014 (patch)
treee8df9a71bd6cf64dea96d0c750822528935b47c6 /src/base
parentffbdaa7cce32bfb18f0c97b9c5f19d1aa54da503 (diff)
downloadgem5-55a4ff5f04badfbd458aee48618920f7fa243014.tar.xz
base: Fix race condition in the socket listen function
gem5 makes the incorrect assumption that by binding a socket, it effectively has allocated a port. Linux only allocates ports once you call listen on the given socket, not when you call bind. So even if the port was free when bind was called, another process (gem5 instance) could race in between the bind & listen calls and steal the port. In the current code, if the call to bind fails due to the port being in use (EADDRINUSE), gem5 retries for a different port. However if listen fails, gem5 just panics. The fix is testing the return value of listen and re-trying if it was due to EADDRINUSE. Committed by: Nilay Vaish <nilay@cs.wisc.edu>
Diffstat (limited to 'src/base')
-rw-r--r--src/base/socket.cc9
1 files changed, 6 insertions, 3 deletions
diff --git a/src/base/socket.cc b/src/base/socket.cc
index 0c8903084..c39accd7e 100644
--- a/src/base/socket.cc
+++ b/src/base/socket.cc
@@ -103,11 +103,14 @@ ListenSocket::listen(int port, bool reuse)
return false;
}
- if (::listen(fd, 1) == -1)
- panic("ListenSocket(listen): listen() failed!");
+ if (::listen(fd, 1) == -1) {
+ if (errno != EADDRINUSE)
+ panic("ListenSocket(listen): listen() failed!");
- listening = true;
+ return false;
+ }
+ listening = true;
anyListening = true;
return true;
}