TokenSpace: fix token wraparound
Fix bug that allocating/freeing a lot of BHandler cause token wraparound and overwriting existing assigned tokens. Change-Id: I12527126644bca1793a8475dc487f131e6f83437 Reviewed-on: https://review.haiku-os.org/c/haiku/+/9533 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
@@ -62,7 +62,7 @@ private:
|
||||
typedef std::map<int32, token_info> TokenMap;
|
||||
|
||||
TokenMap fTokenMap;
|
||||
int32 fTokenCount;
|
||||
int32 fNextToken;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -20,10 +20,20 @@ BTokenSpace gDefaultTokens;
|
||||
// the default token space - all handlers will go into that one
|
||||
|
||||
|
||||
static int32
|
||||
get_next_token(int32 token)
|
||||
{
|
||||
if (token == INT32_MAX)
|
||||
return 1;
|
||||
else
|
||||
return token + 1;
|
||||
}
|
||||
|
||||
|
||||
BTokenSpace::BTokenSpace()
|
||||
:
|
||||
BLocker("token space"),
|
||||
fTokenCount(1)
|
||||
fNextToken(1)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -39,17 +49,24 @@ BTokenSpace::NewToken(int16 type, void* object)
|
||||
BAutolock locker(this);
|
||||
|
||||
token_info tokenInfo = { type, object, NULL };
|
||||
int32 token = fTokenCount;
|
||||
|
||||
int32 wraparoundToken = fNextToken;
|
||||
|
||||
try {
|
||||
fTokenMap[token] = tokenInfo;
|
||||
for (;;) {
|
||||
int32 token = fNextToken;
|
||||
bool done = fTokenMap.insert(std::pair(token, tokenInfo)).second;
|
||||
fNextToken = get_next_token(token);
|
||||
|
||||
if (done)
|
||||
return token;
|
||||
|
||||
if (fNextToken == wraparoundToken)
|
||||
return -1;
|
||||
}
|
||||
} catch (std::bad_alloc& exception) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fTokenCount++;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +90,8 @@ BTokenSpace::SetToken(int32 token, int16 type, void* object)
|
||||
}
|
||||
|
||||
// this makes sure SetToken() plays more or less nice with NewToken()
|
||||
if (token >= fTokenCount)
|
||||
fTokenCount = token + 1;
|
||||
if (token >= fNextToken)
|
||||
fNextToken = get_next_token(token);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user