diff options
Diffstat (limited to 'src/irmd/reg/proc.c')
-rw-r--r-- | src/irmd/reg/proc.c | 266 |
1 files changed, 94 insertions, 172 deletions
diff --git a/src/irmd/reg/proc.c b/src/irmd/reg/proc.c index ede69b8a..24d10fc1 100644 --- a/src/irmd/reg/proc.c +++ b/src/irmd/reg/proc.c @@ -6,256 +6,178 @@ * Dimitri Staessens <dimitri@ouroboros.rocks> * Sander Vrijders <sander@ouroboros.rocks> * - * This program is free software; you can redistribute it and/or modify + * This procram is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful, + * This procram is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * along with this procram; if not, write to the Free Software * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#if defined(__linux__) || defined(__CYGWIN__) -#define _DEFAULT_SOURCE -#else -#define _POSIX_C_SOURCE 200112L -#endif +#define _POSIX_C_SOURCE 200809L -#include "config.h" +#define OUROBOROS_PREFIX "reg/proc" -#include <ouroboros/list.h> -#include <ouroboros/errno.h> -#include <ouroboros/time_utils.h> +#include <ouroboros/logs.h> #include "proc.h" -#include "name.h" -#include <stdlib.h> -#include <unistd.h> -#include <limits.h> #include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +struct name_entry { + struct list_head next; + char * name; +}; -struct reg_proc * reg_proc_create(pid_t pid, - const char * prog) +static void __free_name_entry(struct name_entry * entry) { - struct reg_proc * proc; - pthread_condattr_t cattr; + assert(entry != NULL); + assert(entry->name != NULL); - assert(prog); + free(entry->name); + free(entry); +} - proc = malloc(sizeof(*proc)); - if (proc == NULL) - goto fail_malloc; +static void __reg_proc_clear_names(struct reg_proc * proc) +{ + struct list_head * p; + struct list_head * h; - if (pthread_condattr_init(&cattr)) - goto fail_condattr; + assert(proc != NULL); -#ifndef __APPLE__ - pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK); -#endif + list_for_each_safe(p, h, &proc->names) { + struct name_entry * entry; + entry = list_entry(p, struct name_entry, next); + list_del(&entry->next); + __free_name_entry(entry); + proc->n_names--; + } +} - if (pthread_mutex_init(&proc->lock, NULL)) - goto fail_mutex; +struct reg_proc * reg_proc_create(const struct proc_info * info) +{ + struct reg_proc * proc; - if (pthread_cond_init(&proc->cond, &cattr)) - goto fail_cond; + assert(info != NULL); - proc->set = shm_flow_set_create(pid); - if (proc->set == NULL) - goto fail_set; + proc = malloc(sizeof(*proc)); + if (proc == NULL) { + log_err("Failed to malloc proc."); + goto fail_malloc; + } - proc->prog = strdup(prog); - if(proc->prog == NULL) - goto fail_prog; + proc->set = shm_flow_set_create(info->pid); + if (proc->set == NULL) { + log_err("Failed to create flow set for %d.", info->pid); + goto fail_set; + } list_head_init(&proc->next); list_head_init(&proc->names); - proc->pid = pid; - proc->name = NULL; - proc->state = PROC_INIT; + proc->info = *info; + proc->n_names = 0; return proc; - fail_prog: - shm_flow_set_destroy(proc->set); fail_set: - pthread_cond_destroy(&proc->cond);; - fail_cond: - pthread_mutex_destroy(&proc->lock); - fail_mutex: - pthread_condattr_destroy(&cattr); - fail_condattr: free(proc); fail_malloc: return NULL; } -static void cancel_reg_proc(void * o) -{ - struct reg_proc * proc = (struct reg_proc *) o; - - proc->state = PROC_NULL; - - pthread_mutex_unlock(&proc->lock); -} - void reg_proc_destroy(struct reg_proc * proc) { - struct list_head * p; - struct list_head * h; + assert(proc != NULL); - assert(proc); - - pthread_mutex_lock(&proc->lock); - - if (proc->state == PROC_DESTROY) { - pthread_mutex_unlock(&proc->lock); - return; - } - - if (proc->state == PROC_SLEEP) - proc->state = PROC_DESTROY; - - pthread_cond_signal(&proc->cond); + shm_flow_set_destroy(proc->set); - pthread_cleanup_push(cancel_reg_proc, proc); + __reg_proc_clear_names(proc); - while (proc->state != PROC_INIT) - pthread_cond_wait(&proc->cond, &proc->lock); + assert(list_is_empty(&proc->next)); - pthread_cleanup_pop(false); + assert(proc->n_names == 0); - pthread_mutex_unlock(&proc->lock); + assert(list_is_empty(&proc->names)); - shm_flow_set_destroy(proc->set); + free(proc); +} - pthread_cond_destroy(&proc->cond); - pthread_mutex_destroy(&proc->lock); +static struct name_entry * __reg_proc_get_name(const struct reg_proc * proc, + const char * name) +{ + struct list_head * p; - list_for_each_safe(p, h, &proc->names) { - struct str_el * n = list_entry(p, struct str_el, next); - list_del(&n->next); - if (n->str != NULL) - free(n->str); - free(n); + list_for_each(p, &proc->names) { + struct name_entry * entry; + entry = list_entry(p, struct name_entry, next); + if (strcmp(entry->name, name) == 0) + return entry; } - free(proc->prog); - free(proc); + return NULL; } int reg_proc_add_name(struct reg_proc * proc, const char * name) { - struct str_el * s; + struct name_entry * entry; - assert(proc); - assert(name); + assert(__reg_proc_get_name(proc, name) == NULL); - s = malloc(sizeof(*s)); - if (s == NULL) + entry = malloc(sizeof(*entry)); + if (entry == NULL) { + log_err("Failed to malloc name."); goto fail_malloc; + } - s->str = strdup(name); - if (s->str == NULL) + entry->name = strdup(name); + if (entry == NULL) { + log_err("Failed to strdup name."); goto fail_name; + } + + list_add(&entry->next, &proc->names); - list_add(&s->next, &proc->names); + proc->n_names++; return 0; fail_name: - free(s); + free(entry); fail_malloc: - return -ENOMEM; + return -1; } void reg_proc_del_name(struct reg_proc * proc, const char * name) { - struct list_head * p = NULL; - struct list_head * h = NULL; - - assert(proc); - assert(name); - - list_for_each_safe(p, h, &proc->names) { - struct str_el * s = list_entry(p, struct str_el, next); - if (!strcmp(name, s->str)) { - list_del(&s->next); - free(s->str); - free(s); - } - } -} - -int reg_proc_sleep(struct reg_proc * proc, - struct timespec * dl) -{ - - int ret = 0; - - assert(proc); + struct name_entry * entry; - pthread_mutex_lock(&proc->lock); - - if (proc->state != PROC_WAKE && proc->state != PROC_DESTROY) - proc->state = PROC_SLEEP; - - pthread_cleanup_push(cancel_reg_proc, proc); - - while (proc->state == PROC_SLEEP && ret != -ETIMEDOUT) - ret = -__timedwait(&proc->cond, &proc->lock, dl); + entry = __reg_proc_get_name(proc, name); + if(entry == NULL) + return; - pthread_cleanup_pop(false); + list_del(&entry->next); - if (proc->state == PROC_DESTROY) { - if (proc->name != NULL) - reg_name_del_pid(proc->name, proc->pid); - ret = -1; - } + __free_name_entry(entry); - proc->state = PROC_INIT; + proc->n_names--; - pthread_cond_broadcast(&proc->cond); - pthread_mutex_unlock(&proc->lock); - - return ret; + assert(__reg_proc_get_name(proc, name) == NULL); } -void reg_proc_wake(struct reg_proc * proc, - struct reg_name * name) +bool reg_proc_has_name(const struct reg_proc * proc, + const char * name) { - assert(proc); - assert(name); - - pthread_mutex_lock(&proc->lock); - - if (proc->state != PROC_SLEEP) { - pthread_mutex_unlock(&proc->lock); - return; - } - - proc->state = PROC_WAKE; - proc->name = name; - - pthread_cond_broadcast(&proc->cond); - - pthread_cleanup_push(cancel_reg_proc, proc); - - while (proc->state == PROC_WAKE) - pthread_cond_wait(&proc->cond, &proc->lock); - - pthread_cleanup_pop(false); - - if (proc->state == PROC_DESTROY) - proc->state = PROC_INIT; - - pthread_mutex_unlock(&proc->lock); -} + return __reg_proc_get_name(proc, name) != NULL; +}
\ No newline at end of file |