bh->pool = pool;
bh->tpool = tpool;
- ks_hash_create(&bh->transports, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+ // @todo this needs to be reviewed, NOLOCK is incorrect, but RWLOCK causes deadlock somewhere
+ ks_hash_create(&bh->transports, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
ks_assert(bh->transports);
- ks_hash_create(&bh->spaces, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+ ks_hash_create(&bh->spaces, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
ks_assert(bh->spaces);
- ks_hash_create(&bh->events, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+ ks_hash_create(&bh->events, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
ks_assert(bh->events);
- ks_hash_create(&bh->connections, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+ ks_hash_create(&bh->connections, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
ks_assert(bh->connections);
- ks_hash_create(&bh->sessions, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+ ks_hash_create(&bh->sessions, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
ks_assert(bh->sessions);
- ks_hash_create(&bh->session_state_callbacks, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+ ks_hash_create(&bh->session_state_callbacks, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
ks_assert(bh->session_state_callbacks);
- ks_hash_create(&bh->requests, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+ ks_hash_create(&bh->requests, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
ks_assert(bh->requests);
*bhP = bh;
ks_assert(bh);
ks_assert(sid);
+ // @todo consider using blade_session_t via reference counting, rather than locking a mutex to simulate a reference count to halt cleanups while in use
+ // using actual reference counting would mean that mutexes would not need to be held locked when looking up a session by id just to prevent cleanup,
+ // instead cleanup would automatically occur when the last reference is actually removed (which SHOULD be at the end of the state machine thread),
+ // which is safer than another thread potentially waiting on the write lock to release while it's being destroyed, or external code forgetting to unlock
+ // then use short lived mutex or rwl for accessing the content of the session while it is referenced
+ // this approach should also be used for blade_connection_t, which has a similar threaded state machine
+
ks_hash_read_lock(bh->sessions);
bs = ks_hash_search(bh->sessions, (void *)sid, KS_UNLOCKED);
if (bs && blade_session_read_lock(bs, KS_FALSE) != KS_STATUS_SUCCESS) bs = NULL;
ks_hash_write_lock(bh->session_state_callbacks);
bhsscr = (blade_handle_session_state_callback_registration_t *)ks_hash_remove(bh->session_state_callbacks, (void *)id);
if (!bhsscr) ret = KS_STATUS_FAIL;
- ks_hash_write_lock(bh->session_state_callbacks);
+ ks_hash_write_unlock(bh->session_state_callbacks);
if (bhsscr) blade_handle_session_state_callback_registration_destroy(&bhsscr);
break;
case KS_MPCL_TEARDOWN:
ks_list_clear(l);
- break;
- case KS_MPCL_DESTROY:
ks_rwl_write_lock(l->lock);
for (unsigned int i = 0; i < l->spareelsnum; i++) ks_pool_free(l->pool, &l->spareels[i]);
l->spareelsnum = 0;
ks_rwl_write_unlock(l->lock);
ks_rwl_destroy(&l->lock);
break;
+ case KS_MPCL_DESTROY:
+ break;
}
}
KS_DECLARE(int) ks_list_delete_iterator(ks_list_t *restrict l) {
struct ks_list_entry_s *delendo;
- if (!l->iter_active || l->iter_pos >= l->numels) return -1;
+ if (!l->iter_active || l->iter_pos > l->numels) return -1;
ks_rwl_write_lock(l->lock);
- delendo = ks_list_findpos(l, l->iter_pos);
-
- ks_list_drop_elem(l, delendo, l->iter_pos);
+ delendo = ks_list_findpos(l, l->iter_pos - 1);
+
+ ks_list_drop_elem(l, delendo, l->iter_pos - 1);
l->numels--;