diff options
author | dimitri staessens <dimitri.staessens@ugent.be> | 2017-07-20 15:56:46 +0200 |
---|---|---|
committer | dimitri staessens <dimitri.staessens@ugent.be> | 2017-07-20 15:56:46 +0200 |
commit | d9faf7baf424667acbcb936f935d1ca22ea0eb6b (patch) | |
tree | a1948c4b26e494bc1ec3944b011ce5f0936e18c5 /src | |
parent | 7a993023669945399b174cff5d182ac3dcaadf7f (diff) | |
download | ouroboros-d9faf7baf424667acbcb936f935d1ca22ea0eb6b.tar.gz ouroboros-d9faf7baf424667acbcb936f935d1ca22ea0eb6b.zip |
lib: Fix destruction of CDAP instances
The received message list was not correctly freed upon destruction of
the CDAP object. There was also still a rare case in which thread
cancellation would keep a lock, blocking the IPCP shutdown, which is
also fixed.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/cdap.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/src/lib/cdap.c b/src/lib/cdap.c index 16f2c078..c1209138 100644 --- a/src/lib/cdap.c +++ b/src/lib/cdap.c @@ -268,7 +268,7 @@ static void cdap_rcvd_destroy(struct cdap * instance) pthread_mutex_lock(&instance->rcvd_lock); - list_for_each_safe(p, h, &instance->sent) { + list_for_each_safe(p, h, &instance->rcvd) { struct cdap_rcvd * r = list_entry(p, struct cdap_rcvd, next); list_del(&r->next); if (r->data != NULL) @@ -578,15 +578,8 @@ int cdap_del_flow(struct cdap * instance, pthread_rwlock_wrlock(&instance->flows_lock); - pthread_mutex_lock(&instance->mtx); - - while (instance->proc) - pthread_cond_wait(&instance->cond, &instance->mtx); - flow_set_del(instance->set, fd); - pthread_mutex_unlock(&instance->mtx); - list_for_each_safe(p, h, &instance->flows) { struct fd_el * e = list_entry(p, struct fd_el, next); if (e->fd == fd) { @@ -600,6 +593,16 @@ int cdap_del_flow(struct cdap * instance, pthread_rwlock_unlock(&instance->flows_lock); + pthread_mutex_lock(&instance->mtx); + + pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock, + (void *) &instance->mtx); + + while (instance->proc) + pthread_cond_wait(&instance->cond, &instance->mtx); + + pthread_cleanup_pop(true); + return 0; } |