Skip to content

Commit da105b4

Browse files
committed
fix possible segfaults
1 parent 2065026 commit da105b4

1 file changed

Lines changed: 24 additions & 13 deletions

File tree

src/core/db.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -266,20 +266,28 @@ void db_lru_cleanup_percent(int* bytes_to_remove){
266266

267267
static int db_expire_cursor_table(db_table* table){
268268
int ret = 0;
269-
for (khiter_t ke = kh_begin(table->cache_hash_set); ke != kh_end(table->cache_hash_set); ++ke){
269+
270+
for (khiter_t ke = kh_begin(table->cache_hash_set); ke < kh_end(table->cache_hash_set); ++ke){
270271
if (kh_exist(table->cache_hash_set, ke)) {
271272
ret++;
272273
cache_entry* l = kh_value(table->cache_hash_set, ke);
273274
if (l->expires != 0 && l->expires < time_seconds){
275+
bool end_early = kh_size(table->cache_hash_set) == 1;
274276
if (l->refs == 0)
275277
{
276278
db_entry_incref(l);
277279
db_entry_handle_delete(l);
278280
db_entry_deref(l);
281+
end_early |= true;
279282
}
280283
else
281284
{
282285
db_entry_handle_delete(l);
286+
end_early |= true;
287+
}
288+
289+
if (end_early){
290+
break;
283291
}
284292
}
285293
}
@@ -310,7 +318,7 @@ void db_expire_cursor(){
310318
done += db_expire_cursor_table(table);
311319
}
312320
db.table_gc++;
313-
if (db.table_gc == kh_end(db.tables)){
321+
if (db.table_gc >= kh_end(db.tables)){
314322
db.table_gc = kh_begin(db.tables);
315323
}
316324
} while (db.table_gc != start && done < 1000);
@@ -932,20 +940,23 @@ void db_target_write_allocate(struct cache_target* target, uint32_t data_length)
932940
static void db_close_table_key_space(){
933941
db_table* table;
934942

935-
//tables and key space
936-
for (khiter_t ke = kh_begin(db.tables); ke != kh_end(db.tables); ++ke){
937-
if (kh_exist(db.tables, ke)) {
938-
table = kh_val(db.tables, ke);
943+
//make 128 attempts to clear the tablespace
944+
//table deletions can cause resizing and tables to be skipped in the iteration
945+
for (int i = 0; i < 128 && kh_size(db.tables); i++){
946+
for (khiter_t ke = kh_begin(db.tables); ke < kh_end(db.tables); ++ke){
947+
if (kh_exist(db.tables, ke)) {
948+
table = kh_val(db.tables, ke);
939949

940-
//All other refernces should have been de-refed before db_close is called
941-
//and hence anything pending deletion will have been cleaned up already
942-
assert(!table->deleted);
950+
//All other refernces should have been de-refed before db_close is called
951+
//and hence anything pending deletion will have been cleaned up already
952+
assert(!table->deleted);
943953

944-
//Check reference count (should be 1)
945-
assert(table->refs == 1);
954+
//Check reference count (should be 1)
955+
assert(table->refs == 1);
946956

947-
//Actually delete
948-
db_table_handle_delete(table);
957+
//Actually delete
958+
db_table_handle_delete(table);
959+
}
949960
}
950961
}
951962
kh_destroy(table, db.tables);

0 commit comments

Comments
 (0)