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,45 +1327,51 @@ static int
arena_i_dss_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, arena_i_dss_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen) void *newp, size_t newlen)
{ {
int ret, i; int ret;
bool match, err; const char *dss = NULL;
const char *dss;
unsigned arena_ind = mib[1]; unsigned arena_ind = mib[1];
dss_prec_t dss_prec_old = dss_prec_limit; dss_prec_t dss_prec_old = dss_prec_limit;
dss_prec_t dss_prec = dss_prec_limit; dss_prec_t dss_prec = dss_prec_limit;
malloc_mutex_lock(&ctl_mtx); malloc_mutex_lock(&ctl_mtx);
WRITE(dss, const char *); WRITE(dss, const char *);
match = false; if (dss != NULL) {
for (i = 0; i < dss_prec_limit; i++) { int i;
if (strcmp(dss_prec_names[i], dss) == 0) { bool match = false;
dss_prec = i;
match = true; for (i = 0; i < dss_prec_limit; i++) {
break; if (strcmp(dss_prec_names[i], dss) == 0) {
dss_prec = i;
match = true;
break;
}
}
if (match == false) {
ret = EINVAL;
goto label_return;
} }
}
if (match == false) {
ret = EINVAL;
goto label_return;
} }
if (arena_ind < ctl_stats.narenas) { if (arena_ind < ctl_stats.narenas) {
arena_t *arena = arenas[arena_ind]; arena_t *arena = arenas[arena_ind];
if (arena != NULL) { if (arena == NULL || (dss_prec != dss_prec_limit &&
dss_prec_old = arena_dss_prec_get(arena); arena_dss_prec_set(arena, dss_prec))) {
err = arena_dss_prec_set(arena, dss_prec); ret = EFAULT;
} else goto label_return;
err = true; }
dss_prec_old = arena_dss_prec_get(arena);
} else { } 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_prec_old = chunk_dss_prec_get();
err = chunk_dss_prec_set(dss_prec);
} }
dss = dss_prec_names[dss_prec_old]; dss = dss_prec_names[dss_prec_old];
READ(dss, const char *); READ(dss, const char *);
if (err) {
ret = EFAULT;
goto label_return;
}
ret = 0; ret = 0;
label_return: 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, assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old,
sizeof(dss_prec_old)), 0, "Unexpected mallctl() failure"); 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(); mib[1] = narenas_total_get();
dss_prec_new = "disabled"; dss_prec_new = "disabled";
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new, assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new,
sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure"); sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure");
assert_str_ne(dss_prec_old, "primary", assert_str_ne(dss_prec_old, "primary",
"Unexpected default for dss precedence"); "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 TEST_END