-
-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix memory leak in get_with
and friend methods of future::Cache
#330
Conversation
friends methods are used - Use the correct hash value for an internal waiters map in `future::Cache`. - Also rename variable names for hash values in `sync::Cache` to prevent similar bugs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for finding and fixing this issue so quickly.
From an outsiders perspective, I’m wondering why you are passing these two key/hash pairs explicitly, instead of maybe wrapping them in two different newtypes, so the typesystem enforced that you are using the correct key/hash pair.
I’m also curious why it is necessary to use a TypeId
here as well in the first place? I will have to dig a bit deeper and learn more of the inner working of moka
:-)
Hi. Thank you for the suggestion. Maybe we can change the hash type from bare The reason that we are passing hash explicitly is that a For example,
You may have already seen the answer when creating other pull request, but |
This PR fixes #329, a bug introduced to v0.12.0 causing memory leak in
get_with()
,entry().or_insert_with()
and friend methods infuture::Cache
.It also bumps the crate version to v0.12.1.
Details of the bug
The bug was introduced by PR #294 for v0.12.0 (src/future/value_initializer.rs diff L316-L330). So this PR basically reverts the change.
Here are some backgrounds. An instance of
future::Cache
has a few internal concurrent hash tables (cht), and the following tables are related to this bug:cache
map, which stores cached entries.waiter
map, which stores per-key reader-writer locks used byget_with
and friends methods.The key of
cache
map isArc<K>
, and the key ofwaiter
map is(Arc<K>, TypeId)
. These internal maps take a hash function at creation, and bothcache
map andwaiter
map are given the same hash function.Also, these maps take
hash
value for the key when inserting, getting, or removing an entry (a key-value pair). Thehash
value is supposed to be calculated from the key by the hash function. However, the bug madeget_with
etc. to use a hash value forcache
map for accessingwaiter
map. Since their keys are different, the hash value are also different.Using a wrong hash value still works as long as
waiter
map is using the same memory region where the entry was inserted to. However, once the memory region gets half full with live entries and deleted keys,waiter
map will allocate a new memory region and move live entries to it, using the correct hash values for the keys. Once this happens,get_with
etc. (who use wrong hash) cannot find entries inwaiter
map anymore, leaving them in the map forever. (memory leak)