mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Introduce free function to rb_concurrent_set_funcs
If we create a key but don't insert it (due to other Ractor winning the race), then it would leak memory if we don't free it. This introduces a new function to free that memory for this case.
This commit is contained in:
parent
061224f3cb
commit
66349692f0
4 changed files with 22 additions and 7 deletions
|
@ -304,6 +304,14 @@ rb_concurrent_set_find_or_insert(VALUE *set_obj_ptr, VALUE key, void *data)
|
||||||
if (set->funcs->cmp(key, curr_key)) {
|
if (set->funcs->cmp(key, curr_key)) {
|
||||||
// We've found a match.
|
// We've found a match.
|
||||||
RB_GC_GUARD(set_obj);
|
RB_GC_GUARD(set_obj);
|
||||||
|
|
||||||
|
if (inserting) {
|
||||||
|
// We created key using set->funcs->create, but we didn't end
|
||||||
|
// up inserting it into the set. Free it here to prevent memory
|
||||||
|
// leaks.
|
||||||
|
if (set->funcs->free) set->funcs->free(key);
|
||||||
|
}
|
||||||
|
|
||||||
return curr_key;
|
return curr_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,11 @@
|
||||||
#include "ruby/atomic.h"
|
#include "ruby/atomic.h"
|
||||||
#include "ruby/ruby.h"
|
#include "ruby/ruby.h"
|
||||||
|
|
||||||
typedef VALUE (*rb_concurrent_set_hash_func)(VALUE key);
|
|
||||||
typedef bool (*rb_concurrent_set_cmp_func)(VALUE a, VALUE b);
|
|
||||||
typedef VALUE (*rb_concurrent_set_create_func)(VALUE key, void *data);
|
|
||||||
|
|
||||||
struct rb_concurrent_set_funcs {
|
struct rb_concurrent_set_funcs {
|
||||||
rb_concurrent_set_hash_func hash;
|
VALUE (*hash)(VALUE key);
|
||||||
rb_concurrent_set_cmp_func cmp;
|
bool (*cmp)(VALUE a, VALUE b);
|
||||||
rb_concurrent_set_create_func create;
|
VALUE (*create)(VALUE key, void *data);
|
||||||
|
void (*free)(VALUE key);
|
||||||
};
|
};
|
||||||
|
|
||||||
VALUE rb_concurrent_set_new(const struct rb_concurrent_set_funcs *funcs, int capacity);
|
VALUE rb_concurrent_set_new(const struct rb_concurrent_set_funcs *funcs, int capacity);
|
||||||
|
|
1
string.c
1
string.c
|
@ -552,6 +552,7 @@ static const struct rb_concurrent_set_funcs fstring_concurrent_set_funcs = {
|
||||||
.hash = fstring_concurrent_set_hash,
|
.hash = fstring_concurrent_set_hash,
|
||||||
.cmp = fstring_concurrent_set_cmp,
|
.cmp = fstring_concurrent_set_cmp,
|
||||||
.create = fstring_concurrent_set_create,
|
.create = fstring_concurrent_set_create,
|
||||||
|
.free = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
9
symbol.c
9
symbol.c
|
@ -315,10 +315,19 @@ sym_set_create(VALUE sym, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sym_set_free(VALUE sym)
|
||||||
|
{
|
||||||
|
if (sym_set_sym_static_p(sym)) {
|
||||||
|
xfree(sym_set_static_sym_untag(sym));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct rb_concurrent_set_funcs sym_set_funcs = {
|
static const struct rb_concurrent_set_funcs sym_set_funcs = {
|
||||||
.hash = sym_set_hash,
|
.hash = sym_set_hash,
|
||||||
.cmp = sym_set_cmp,
|
.cmp = sym_set_cmp,
|
||||||
.create = sym_set_create,
|
.create = sym_set_create,
|
||||||
|
.free = sym_set_free,
|
||||||
};
|
};
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue