aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2016-02-05 15:15:30 -0600
committerPeter Seebach <peter.seebach@windriver.com>2016-02-05 15:15:30 -0600
commit8a75f99a652c362b64a14a11d4007690dc7f20d5 (patch)
tree9463e43c26e40eca1093311539db52c516187d3a
parent4c56d54337251049ca6fbc248d1e364fa8184fba (diff)
downloadpseudo-8a75f99a652c362b64a14a11d4007690dc7f20d5.tar.gz
pseudo-8a75f99a652c362b64a14a11d4007690dc7f20d5.tar.bz2
pseudo-8a75f99a652c362b64a14a11d4007690dc7f20d5.zip
pseudo_client.c: retry after a couple of milliseconds
Race conditions exist when the server shutdown takes long enough for three attempts to access the server to fail. Solution: Add a slight delay to the retry. Delay is variable (using getpid()%5). (Not "random" because I have no evidence that the process the client is running in will have seeded RNG, and I don't want to seed it and possibly screw them up).
-rw-r--r--ChangeLog.txt1
-rw-r--r--pseudo_client.c13
2 files changed, 10 insertions, 4 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index d76bd0b..9841594 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -2,6 +2,7 @@
* (seebs) don't abort search for server on first try.
* (seebs) new clients cancel a shutdown request.
* (seebs) sort xattrs when returning list.
+ * (seebs) add retry interval, rather than instant retries.
2016-01-22:
* (seebs) Mask in S_IFREG when mknod called with no S_IFMT bits.
diff --git a/pseudo_client.c b/pseudo_client.c
index 570c861..89c0c07 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
+#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
@@ -1200,7 +1201,11 @@ pseudo_client_setup(void) {
}
pseudo_debug(PDBGF_CLIENT, "server seems to be gone, trying to restart\n");
if (client_spawn_server()) {
- pseudo_debug(PDBGF_CLIENT, "failed to spawn server, giving up.\n");
+ int ms = (getpid() % 5) + 3;
+ struct timespec delay = { .tv_sec = 0, .tv_nsec = ms * 1000000 };
+ nanosleep(&delay, NULL);
+
+ pseudo_debug(PDBGF_CLIENT, "failed to spawn server, waiting for retry.\n");
return 1;
} else {
pseudo_debug(PDBGF_CLIENT, "restarted, new pid %d\n", server_pid);
@@ -1208,7 +1213,7 @@ pseudo_client_setup(void) {
return 0;
}
}
- pseudo_debug(PDBGF_CLIENT, "couldn't get a server, giving up.\n");
+ pseudo_debug(PDBGF_CLIENT, "couldn't get or spawn a server.\n");
return 1;
}
@@ -1231,13 +1236,13 @@ pseudo_client_request(pseudo_msg_t *msg, size_t len, const char *path) {
rc,
rc == -1 ? " (sigpipe)" :
" (short write)");
- pseudo_debug(PDBGF_CLIENT, "trying to get server\n");
- pseudo_client_setup();
++tries;
if (tries > 3) {
pseudo_debug(PDBGF_CLIENT, "Can't get server going again.\n");
return 0;
}
+ pseudo_debug(PDBGF_CLIENT, "trying to get server, try %d\n", tries);
+ pseudo_client_setup();
}
} while (rc != 0);
pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sent!\n");