mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-04 09:43:08 +02:00
Retry socket bind.
In the case of a rapid restart it is possible that the socket may not be immediately available, so retry until it becomes available. This is particularly useful for testing where sockets are bound and released very rapidly.
This commit is contained in:
parent
ed72c6f9a1
commit
65dfe2407d
@ -186,9 +186,17 @@ sckServerNew(const String *const address, const unsigned int port, const TimeMSe
|
||||
strCat(this->name, addrInfoToName(this->address, this->port, addressFound));
|
||||
|
||||
// Bind the address
|
||||
THROW_ON_SYS_ERROR(
|
||||
bind(this->socket, addressFound->ai_addr, addressFound->ai_addrlen) == -1, FileOpenError,
|
||||
"unable to bind socket");
|
||||
Wait *const wait = waitNew(timeout);
|
||||
int result;
|
||||
|
||||
do
|
||||
{
|
||||
result = bind(this->socket, addressFound->ai_addr, addressFound->ai_addrlen);
|
||||
|
||||
if (result == -1 && !waitMore(wait))
|
||||
THROW_SYS_ERROR(FileOpenError, "unable to bind socket");
|
||||
}
|
||||
while (result == -1);
|
||||
|
||||
// Listen for client connections. It might be a good idea to make the backlog configurable but this value seems OK for now.
|
||||
THROW_ON_SYS_ERROR(listen(this->socket, 100) == -1, FileOpenError, "unable to listen on socket");
|
||||
|
@ -565,6 +565,38 @@ testRun(void)
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
HRN_FORK_END();
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("sckServerNew() retries bind()");
|
||||
|
||||
HRN_FORK_BEGIN(.timeout = 5000)
|
||||
{
|
||||
const unsigned int testPort = hrnServerPortNext();
|
||||
|
||||
HRN_FORK_CHILD_BEGIN(.prefix = "server")
|
||||
{
|
||||
// Bind port and notify parent
|
||||
IoServer *server = sckServerNew(STRDEF("127.0.0.1"), testPort, 5000);
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
|
||||
// Sleep 1000ms then close port
|
||||
sleepMSec(1000);
|
||||
objFree(server);
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
|
||||
HRN_FORK_PARENT_BEGIN(.prefix = "client")
|
||||
{
|
||||
// Wait for parent to bind port before attempting to bind
|
||||
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||
TEST_ERROR(
|
||||
sckServerNew(STRDEF("127.0.0.1"), testPort, 100), FileOpenError,
|
||||
"unable to bind socket: [98] Address already in use");
|
||||
TEST_RESULT_VOID(sckServerNew(STRDEF("127.0.0.1"), testPort, 5000), "bind succeeds with enough retries");
|
||||
}
|
||||
HRN_FORK_PARENT_END();
|
||||
}
|
||||
HRN_FORK_END();
|
||||
}
|
||||
|
||||
// Additional coverage not provided by testing with actual certificates
|
||||
|
Loading…
Reference in New Issue
Block a user