summaryrefslogtreecommitdiff
path: root/src/irmd/registry.c
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2017-09-30 17:58:18 +0200
committerdimitri staessens <[email protected]>2017-09-30 17:58:18 +0200
commit9405ad97e20686f74c06bcbac9523a8b4f10272e (patch)
treea0489929634ee7588de3ad77a6a1166ce11508e2 /src/irmd/registry.c
parent5e974395fadc5e1922f200855c14ca0538ba50dc (diff)
downloadouroboros-9405ad97e20686f74c06bcbac9523a8b4f10272e.tar.gz
ouroboros-9405ad97e20686f74c06bcbac9523a8b4f10272e.zip
lib: Cancel tpm threads instead of marking exit
This makes the threadpool use pthread_cancel instead of setting an exit flag that threadpool managed threads check periodically. This drastically reduces CPU consumption in the irmd when running a lot of applications. It requires cancellation handlers in the ipcp and irmd to be implemented to ensure safe cancellation during operation and shutdown.
Diffstat (limited to 'src/irmd/registry.c')
-rw-r--r--src/irmd/registry.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/src/irmd/registry.c b/src/irmd/registry.c
index c7e7b52d..f863af6a 100644
--- a/src/irmd/registry.c
+++ b/src/irmd/registry.c
@@ -92,30 +92,13 @@ static int reg_entry_init(struct reg_entry * e,
return 0;
}
-static void reg_entry_destroy(struct reg_entry * e)
+static void cancel_reg_entry_destroy(void * o)
{
- struct list_head * p = NULL;
- struct list_head * h = NULL;
-
- if (e == NULL)
- return;
-
- pthread_mutex_lock(&e->state_lock);
-
- if (e->state == REG_NAME_DESTROY) {
- pthread_mutex_unlock(&e->state_lock);
- return;
- }
-
- if (e->state != REG_NAME_FLOW_ACCEPT)
- e->state = REG_NAME_NULL;
- else
- e->state = REG_NAME_DESTROY;
-
- pthread_cond_broadcast(&e->state_cond);
+ struct reg_entry * e;
+ struct list_head * p;
+ struct list_head * h;
- while (e->state != REG_NAME_NULL)
- pthread_cond_wait(&e->state_cond, &e->state_lock);
+ e = (struct reg_entry *) o;
pthread_mutex_unlock(&e->state_lock);
@@ -148,6 +131,33 @@ static void reg_entry_destroy(struct reg_entry * e)
free(e);
}
+static void reg_entry_destroy(struct reg_entry * e)
+{
+ if (e == NULL)
+ return;
+
+ pthread_mutex_lock(&e->state_lock);
+
+ if (e->state == REG_NAME_DESTROY) {
+ pthread_mutex_unlock(&e->state_lock);
+ return;
+ }
+
+ if (e->state != REG_NAME_FLOW_ACCEPT)
+ e->state = REG_NAME_NULL;
+ else
+ e->state = REG_NAME_DESTROY;
+
+ pthread_cond_broadcast(&e->state_cond);
+
+ pthread_cleanup_push(cancel_reg_entry_destroy, e);
+
+ while (e->state != REG_NAME_NULL)
+ pthread_cond_wait(&e->state_cond, &e->state_lock);
+
+ pthread_cleanup_pop(true);
+}
+
static bool reg_entry_is_local_in_dif(struct reg_entry * e,
const char * dif_name)
{
@@ -459,6 +469,9 @@ int reg_entry_leave_state(struct reg_entry * e,
pthread_mutex_lock(&e->state_lock);
+ pthread_cleanup_push((void *)(void *) pthread_mutex_unlock,
+ &e->state_lock);
+
while (e->state == state && ret != -ETIMEDOUT)
if (timeout)
ret = -pthread_cond_timedwait(&e->state_cond,
@@ -474,7 +487,7 @@ int reg_entry_leave_state(struct reg_entry * e,
pthread_cond_broadcast(&e->state_cond);
}
- pthread_mutex_unlock(&e->state_lock);
+ pthread_cleanup_pop(true);
return ret;
}