summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2016-07-27 18:57:44 +0200
committerdimitri staessens <[email protected]>2016-07-27 18:57:44 +0200
commit7c18c1c74ac4771ffe9b0533b5bdd447c29e9802 (patch)
tree0229b141341e9c64c91e850469ae31d819f0fdba
parent6c54691d1931118155360ac010671ff554cd4f71 (diff)
downloadouroboros-7c18c1c74ac4771ffe9b0533b5bdd447c29e9802.tar.gz
ouroboros-7c18c1c74ac4771ffe9b0533b5bdd447c29e9802.zip
irmd: Fix shutdown
When a pending accept is shutdown on irmd exit, there are no more threads running, but it should also change the state to NULL. This is now correctly handled in the cleanup of the cancellation point. Also fixed a busy wait with a condition variable.
-rw-r--r--src/irmd/main.c18
-rw-r--r--src/irmd/registry.c21
2 files changed, 17 insertions, 22 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 6cf16505..d7119bac 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -1083,7 +1083,6 @@ static struct irm_flow * flow_req_arr(pid_t api,
struct reg_entry * rne = NULL;
struct irm_flow * pme = NULL;
- bool acc_wait = true;
enum reg_name_state state;
struct spawned_api * c_api;
@@ -1163,6 +1162,7 @@ static struct irm_flow * flow_req_arr(pid_t api,
pthread_rwlock_rdlock(&irmd->reg_lock);
pthread_mutex_lock(&rne->state_lock);
if (rne->state == REG_NAME_DESTROY) {
+ rne->state = REG_NAME_NULL;
pthread_mutex_unlock(&rne->state_lock);
pthread_rwlock_unlock(&irmd->reg_lock);
return NULL;
@@ -1207,14 +1207,14 @@ static struct irm_flow * flow_req_arr(pid_t api,
pthread_rwlock_unlock(&irmd->state_lock);
- while (acc_wait) {
- pthread_rwlock_rdlock(&irmd->state_lock);
- pthread_mutex_lock(&rne->state_lock);
- acc_wait = (rne->state == REG_NAME_FLOW_ARRIVED &&
- irmd->state == IRMD_RUNNING);
- pthread_mutex_unlock(&rne->state_lock);
- pthread_rwlock_unlock(&irmd->state_lock);
- }
+ pthread_cleanup_push((void(*)(void *)) pthread_mutex_unlock,
+ (void *) &rne->state_lock);
+
+ while (rne->state == REG_NAME_FLOW_ARRIVED &&
+ irmd->state == IRMD_RUNNING)
+ pthread_cond_wait(&rne->state_cond, &rne->state_lock);
+
+ pthread_cleanup_pop(true);
return pme;
}
diff --git a/src/irmd/registry.c b/src/irmd/registry.c
index ab47fede..a1d1238d 100644
--- a/src/irmd/registry.c
+++ b/src/irmd/registry.c
@@ -114,6 +114,13 @@ static void reg_api_destroy(struct reg_api * i)
free(i);
}
+static void cleanup_sleeper(void * o) {
+ struct reg_api * i = (struct reg_api *) o;
+ i->state = REG_I_NULL;
+ pthread_cond_signal(&i->state_cond);
+ pthread_mutex_unlock(&i->state_lock);
+}
+
void reg_api_sleep(struct reg_api * i)
{
if (i == NULL)
@@ -127,15 +134,11 @@ void reg_api_sleep(struct reg_api * i)
i->state = REG_I_SLEEP;
- pthread_cleanup_push((void(*)(void *)) pthread_mutex_unlock,
- (void *) &i->state_lock);
+ pthread_cleanup_push(cleanup_sleeper, (void *) i);
while (i->state == REG_I_SLEEP)
pthread_cond_wait(&i->state_cond, &i->state_lock);
- i->state = REG_I_NULL;
- pthread_cond_signal(&i->state_cond);
-
pthread_cleanup_pop(true);
}
@@ -235,8 +238,6 @@ static void reg_entry_destroy(struct reg_entry * e)
struct list_head * pos = NULL;
struct list_head * n = NULL;
- bool wait = true;
-
if (e == NULL)
return;
@@ -247,12 +248,6 @@ static void reg_entry_destroy(struct reg_entry * e)
pthread_cond_broadcast(&e->state_cond);
pthread_mutex_unlock(&e->state_lock);
- while (wait) {
- pthread_mutex_lock(&e->state_lock);
- pthread_cond_broadcast(&e->state_cond);
- pthread_mutex_unlock(&e->state_lock);
- }
-
pthread_mutex_destroy(&e->state_lock);
if (e->name != NULL)