diff --git a/src/ckdb.h b/src/ckdb.h index 86f407d4..cfc78143 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -58,7 +58,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.7" -#define CKDB_VERSION DB_VERSION"-2.704" +#define CKDB_VERSION DB_VERSION"-2.710" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ diff --git a/src/klist.c b/src/klist.c index a33a7e9c..cdad46c5 100644 --- a/src/klist.c +++ b/src/klist.c @@ -206,7 +206,21 @@ K_STORE *_k_new_store(K_LIST *list, KLIST_FFL_ARGS) store->lock = NULL; store->name = list->name; store->do_tail = list->do_tail; - list->stores++; + store->prev_store = NULL; + // Only tracked for lists with a lock + if (store->master->lock == NULL) { + store->next_store = NULL; + store->master->stores++; + } else { + K_WLOCK(list); + // In the master list, next is the head + if (list->next_store) + list->next_store->prev_store = store; + store->next_store = list->next_store; + list->next_store = store; + list->stores++; + K_WUNLOCK(list); + } return store; } @@ -255,6 +269,7 @@ K_LIST *_k_new_list(const char *name, size_t siz, int allocate, int limit, list->limit = limit; list->do_tail = do_tail; list->cull_limit = cull_limit; + list->next_store = list->prev_store = NULL; if (!(list->is_lock_only)) k_alloc_items(list, KLIST_FFL_PASS); @@ -718,7 +733,21 @@ K_STORE *_k_free_store(K_STORE *store, KLIST_FFL_ARGS) store->name, __func__, KLIST_FFL_PASS); } - store->master->stores--; + if (store->master->lock == NULL) + store->master->stores--; + else { + K_WLOCK(store->master); + // unlink store from the list + if (store->prev_store) + store->prev_store->next_store = store->next_store; + if (store->next_store) + store->next_store->prev_store = store->prev_store; + // correct the head if we are the head + if (store->master->next_store == store) + store->master->next_store = store->next_store; + store->master->stores--; + K_WUNLOCK(store->master); + } free(store); diff --git a/src/klist.h b/src/klist.h index ee8a021f..e009d708 100644 --- a/src/klist.h +++ b/src/klist.h @@ -154,6 +154,8 @@ typedef struct k_list { int cull_limit; // <1 means don't cull, otherwise total to cull at int cull_count; // number of times culled uint64_t ram; // ram allocated for data pointers - code must manage it + struct k_list *next_store; // list of all stores - the head is next_store in the list master + struct k_list *prev_store; // the stores themselves have their prev and next int stores; // how many stores it currently has #if LOCK_CHECK // Since each thread has it's own k_lock no locking is required on this