Fix arena.<i>.dss mallctl to handle read-only calls.

This commit is contained in:
Jason Evans 2014-08-15 12:20:20 -07:00
parent 070b3c3fbd
commit 586c8ede42
2 changed files with 42 additions and 23 deletions

View File

@ -1327,16 +1327,18 @@ static int
arena_i_dss_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen)
{
int ret, i;
bool match, err;
const char *dss;
int ret;
const char *dss = NULL;
unsigned arena_ind = mib[1];
dss_prec_t dss_prec_old = dss_prec_limit;
dss_prec_t dss_prec = dss_prec_limit;
malloc_mutex_lock(&ctl_mtx);
WRITE(dss, const char *);
match = false;
if (dss != NULL) {
int i;
bool match = false;
for (i = 0; i < dss_prec_limit; i++) {
if (strcmp(dss_prec_names[i], dss) == 0) {
dss_prec = i;
@ -1344,28 +1346,32 @@ arena_i_dss_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
break;
}
}
if (match == false) {
ret = EINVAL;
goto label_return;
}
}
if (arena_ind < ctl_stats.narenas) {
arena_t *arena = arenas[arena_ind];
if (arena != NULL) {
dss_prec_old = arena_dss_prec_get(arena);
err = arena_dss_prec_set(arena, dss_prec);
} else
err = true;
} else {
dss_prec_old = chunk_dss_prec_get();
err = chunk_dss_prec_set(dss_prec);
}
dss = dss_prec_names[dss_prec_old];
READ(dss, const char *);
if (err) {
if (arena == NULL || (dss_prec != dss_prec_limit &&
arena_dss_prec_set(arena, dss_prec))) {
ret = EFAULT;
goto label_return;
}
dss_prec_old = arena_dss_prec_get(arena);
} else {
if (dss_prec != dss_prec_limit &&
chunk_dss_prec_set(dss_prec)) {
ret = EFAULT;
goto label_return;
}
dss_prec_old = chunk_dss_prec_get();
}
dss = dss_prec_names[dss_prec_old];
READ(dss, const char *);
ret = 0;
label_return:

View File

@ -268,12 +268,25 @@ TEST_BEGIN(test_arena_i_dss)
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old,
sizeof(dss_prec_old)), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, NULL, 0), 0,
"Unexpected mallctl() failure");
assert_str_ne(dss_prec_old, "primary",
"Unexpected value for dss precedence");
mib[1] = narenas_total_get();
dss_prec_new = "disabled";
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new,
sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure");
assert_str_ne(dss_prec_old, "primary",
"Unexpected default for dss precedence");
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old,
sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, NULL, 0), 0,
"Unexpected mallctl() failure");
assert_str_ne(dss_prec_old, "primary",
"Unexpected value for dss precedence");
}
TEST_END