Implemented exponential backoff for shared memory related waits
This commit is contained in:
parent
35a54dbd61
commit
9993dfafa2
3 changed files with 25 additions and 8 deletions
|
@ -100,7 +100,7 @@ namespace IPC{
|
||||||
}
|
}
|
||||||
if (!(*this)){
|
if (!(*this)){
|
||||||
if (GetLastError() == ERROR_FILE_NOT_FOUND && !noWait){// Error code 2
|
if (GetLastError() == ERROR_FILE_NOT_FOUND && !noWait){// Error code 2
|
||||||
Util::wait(500);
|
Util::wait(Util::expBackoffMs(timer-1, 10, 5000));
|
||||||
}else{
|
}else{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ namespace IPC{
|
||||||
}
|
}
|
||||||
if (!(*this)){
|
if (!(*this)){
|
||||||
if (errno == ENOENT && !noWait){
|
if (errno == ENOENT && !noWait){
|
||||||
Util::wait(500);
|
Util::wait(Util::expBackoffMs(timer-1, 10, 5000));
|
||||||
}else{
|
}else{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -458,10 +458,10 @@ namespace IPC{
|
||||||
}else{
|
}else{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
do{
|
do{
|
||||||
if (i != 0){Util::wait(1000);}
|
if (i != 0){Util::wait(Util::expBackoffMs(i-1, 10, 10000));}
|
||||||
handle = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, name.c_str());
|
handle = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, name.c_str());
|
||||||
i++;
|
i++;
|
||||||
}while (i < 10 && !handle && autoBackoff);
|
}while (i <= 10 && !handle && autoBackoff);
|
||||||
}
|
}
|
||||||
if (!handle){
|
if (!handle){
|
||||||
MEDIUM_MSG("%s for page %s failed with error code %u",
|
MEDIUM_MSG("%s for page %s failed with error code %u",
|
||||||
|
@ -489,9 +489,9 @@ namespace IPC{
|
||||||
handle = shm_open(name.c_str(), O_CREAT | O_RDWR, ACCESSPERMS);
|
handle = shm_open(name.c_str(), O_CREAT | O_RDWR, ACCESSPERMS);
|
||||||
}else{
|
}else{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < 10 && handle == -1 && autoBackoff){
|
while (i < 11 && handle == -1 && autoBackoff){
|
||||||
i++;
|
i++;
|
||||||
Util::wait(1000);
|
Util::wait(Util::expBackoffMs(i-1, 10, 10000));
|
||||||
handle = shm_open(name.c_str(), O_RDWR, ACCESSPERMS);
|
handle = shm_open(name.c_str(), O_RDWR, ACCESSPERMS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -620,9 +620,9 @@ namespace IPC{
|
||||||
O_CREAT | O_TRUNC | O_RDWR, (mode_t)0600);
|
O_CREAT | O_TRUNC | O_RDWR, (mode_t)0600);
|
||||||
}else{
|
}else{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < 10 && handle == -1 && autoBackoff){
|
while (i < 11 && handle == -1 && autoBackoff){
|
||||||
i++;
|
i++;
|
||||||
Util::wait(1000);
|
Util::wait(Util::expBackoffMs(i-1, 10, 10000));
|
||||||
handle = open(std::string(Util::getTmpFolder() + name).c_str(), O_RDWR, (mode_t)0600);
|
handle = open(std::string(Util::getTmpFolder() + name).c_str(), O_RDWR, (mode_t)0600);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
lib/util.cpp
15
lib/util.cpp
|
@ -149,6 +149,21 @@ namespace Util{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Returns the time to wait in milliseconds for exponential back-off waiting.
|
||||||
|
//If currIter > maxIter, always returns 5ms to prevent tight eternal loops when mistakes are made
|
||||||
|
//Otherwise, exponentially increases wait time for a total of maxWait milliseconds after maxIter calls.
|
||||||
|
//Wildly inaccurate for very short max durations and/or very large maxIter values, but otherwise works as expected.
|
||||||
|
int64_t expBackoffMs(const size_t currIter, const size_t maxIter, const int64_t maxWait){
|
||||||
|
if (currIter > maxIter){return 5;}
|
||||||
|
int64_t w = maxWait >> 1;
|
||||||
|
for (size_t i = maxIter; i > currIter; --i){
|
||||||
|
w >>= 1;
|
||||||
|
if (w < 2){w = 2;}
|
||||||
|
}
|
||||||
|
DONTEVEN_MSG("Waiting %" PRId64 " ms out of %" PRId64 " for iteration %zu/%zu", w, maxWait, currIter, maxIter);
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
/// 64-bits version of ftell
|
/// 64-bits version of ftell
|
||||||
uint64_t ftell(FILE *stream){
|
uint64_t ftell(FILE *stream){
|
||||||
/// \TODO Windows implementation (e.g. _ftelli64 ?)
|
/// \TODO Windows implementation (e.g. _ftelli64 ?)
|
||||||
|
|
|
@ -14,6 +14,8 @@ namespace Util{
|
||||||
bool stringScan(const std::string &src, const std::string &pattern, std::deque<std::string> &result);
|
bool stringScan(const std::string &src, const std::string &pattern, std::deque<std::string> &result);
|
||||||
void stringToLower(std::string &val);
|
void stringToLower(std::string &val);
|
||||||
|
|
||||||
|
int64_t expBackoffMs(const size_t currIter, const size_t maxIter, const int64_t maxWait);
|
||||||
|
|
||||||
uint64_t ftell(FILE *stream);
|
uint64_t ftell(FILE *stream);
|
||||||
uint64_t fseek(FILE *stream, uint64_t offset, int whence);
|
uint64_t fseek(FILE *stream, uint64_t offset, int whence);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue