diff options
Diffstat (limited to 'src/ipcpd/ipcp-data.c')
-rw-r--r-- | src/ipcpd/ipcp-data.c | 533 |
1 files changed, 0 insertions, 533 deletions
diff --git a/src/ipcpd/ipcp-data.c b/src/ipcpd/ipcp-data.c deleted file mode 100644 index 47c4c472..00000000 --- a/src/ipcpd/ipcp-data.c +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * IPC process utilities - * - * Dimitri Staessens <[email protected]> - * Sander Vrijders <[email protected]> - * - * This program 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, - * 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 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define OUROBOROS_PREFIX "ipcp-utils" - -#include <ouroboros/config.h> -#include <ouroboros/list.h> -#include <ouroboros/time_utils.h> -#include <ouroboros/logs.h> -#include <ouroboros/errno.h> - -#include "ipcp-data.h" -#include "ipcp.h" - -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -struct reg_entry { - struct list_head list; - char * name; -}; - -struct dir_entry { - struct list_head list; - char * name; - uint64_t addr; -}; - -static struct reg_entry * reg_entry_create(char * name) -{ - struct reg_entry * entry = malloc(sizeof(*entry)); - if (entry == NULL) - return NULL; - - assert(name); - - entry->name = name; - if (entry->name == NULL) - return NULL; - - return entry; -} - -static void reg_entry_destroy(struct reg_entry * entry) -{ - assert(entry); - - if (entry->name != NULL) - free(entry->name); - - free(entry); -} - -static struct dir_entry * dir_entry_create(char * name, - uint64_t addr) -{ - struct dir_entry * entry = malloc(sizeof(*entry)); - if (entry == NULL) - return NULL; - - assert(name); - - entry->addr = addr; - entry->name = name; - if (entry->name == NULL) - return NULL; - - return entry; -} - -static void dir_entry_destroy(struct dir_entry * entry) -{ - assert(entry); - - if (entry->name != NULL) - free(entry->name); - - free(entry); -} - -struct ipcp_data * ipcp_data_create() -{ - struct ipcp_data * data = malloc(sizeof(*data)); - if (data == NULL) - return NULL; - - data->type = 0; - - return data; -} - -struct ipcp_data * ipcp_data_init(struct ipcp_data * dst, - enum ipcp_type ipcp_type) -{ - if (dst == NULL) - return NULL; - - dst->type = ipcp_type; - dst->dif_name = NULL; - - /* init the lists */ - list_head_init(&dst->registry); - list_head_init(&dst->directory); - list_head_init(&dst->dir_queries); - - /* init the locks */ - pthread_rwlock_init(&dst->reg_lock, NULL); - pthread_rwlock_init(&dst->dir_lock, NULL); - pthread_mutex_init(&dst->dir_queries_lock, NULL); - - return dst; -} - -static void clear_registry(struct ipcp_data * data) -{ - struct list_head * h; - struct list_head * t; - - assert(data); - - list_for_each_safe(h, t, &data->registry) { - struct reg_entry * e = list_entry(h, struct reg_entry, list); - list_del(&e->list); - reg_entry_destroy(e); - } -} - -static void clear_directory(struct ipcp_data * data) -{ - struct list_head * h; - struct list_head * t; - - assert(data); - - list_for_each_safe(h, t, &data->directory) { - struct dir_entry * e = list_entry(h, struct dir_entry, list); - list_del(&e->list); - dir_entry_destroy(e); - } -} - -static void clear_dir_queries(struct ipcp_data * data) -{ - struct list_head * h; - struct list_head * t; - - assert(data); - - list_for_each_safe(h, t, &data->dir_queries) { - struct dir_query * e = list_entry(h, struct dir_query, next); - list_del(&e->next); - ipcp_data_dir_query_destroy(e); - } -} - -void ipcp_data_destroy(struct ipcp_data * data) -{ - if (data == NULL) - return; - - /* clear the lists */ - pthread_rwlock_wrlock(&data->reg_lock); - clear_registry(data); - pthread_rwlock_unlock(&data->reg_lock); - - pthread_rwlock_wrlock(&data->dir_lock); - clear_directory(data); - pthread_rwlock_unlock(&data->dir_lock); - - pthread_mutex_lock(&data->dir_queries_lock); - clear_dir_queries(data); - pthread_mutex_unlock(&data->dir_queries_lock); - - if (data->dif_name != NULL) - free(data->dif_name); - - pthread_rwlock_destroy(&data->dir_lock); - pthread_rwlock_destroy(&data->reg_lock); - pthread_mutex_destroy(&data->dir_queries_lock); - - free(data); -} - -static struct reg_entry * find_reg_entry_by_name(struct ipcp_data * data, - const char * name) -{ - struct list_head * h; - - assert(data); - assert(name); - - list_for_each(h, &data->registry) { - struct reg_entry * e = list_entry(h, struct reg_entry, list); - if (!strcmp(e->name, name)) - return e; - } - - return NULL; -} - -static struct dir_entry * find_dir_entry(struct ipcp_data * data, - const char * name, - uint64_t addr) -{ - struct list_head * h; - list_for_each(h, &data->directory) { - struct dir_entry * e = list_entry(h, struct dir_entry, list); - if (e->addr == addr && !strcmp(e->name, name)) - return e; - } - - return NULL; -} - -static struct dir_entry * find_dir_entry_any(struct ipcp_data * data, - const char * name) -{ - struct list_head * h; - list_for_each(h, &data->directory) { - struct dir_entry * e = list_entry(h, struct dir_entry, list); - if (!strcmp(e->name, name)) - return e; - } - - return NULL; -} - -int ipcp_data_reg_add_entry(struct ipcp_data * data, - char * name) -{ - struct reg_entry * entry; - - if (data == NULL || name == NULL) - return -1; - - pthread_rwlock_wrlock(&data->reg_lock); - - if (find_reg_entry_by_name(data, name)) { - pthread_rwlock_unlock(&data->reg_lock); - return -1; - } - - entry = reg_entry_create(name); - if (entry == NULL) { - pthread_rwlock_unlock(&data->reg_lock); - return -1; - } - - list_add(&entry->list, &data->registry); - - pthread_rwlock_unlock(&data->reg_lock); - - return 0; -} - -int ipcp_data_reg_del_entry(struct ipcp_data * data, - const char * name) -{ - struct reg_entry * e; - if (data == NULL) - return -1; - - pthread_rwlock_wrlock(&data->reg_lock); - - e = find_reg_entry_by_name(data, name); - if (e == NULL) { - pthread_rwlock_unlock(&data->reg_lock); - return 0; /* nothing to do */ - } - - list_del(&e->list); - - pthread_rwlock_unlock(&data->reg_lock); - - reg_entry_destroy(e); - - return 0; -} - -bool ipcp_data_reg_has(struct ipcp_data * data, - const char * name) -{ - bool ret = false; - - if (data == NULL || name == NULL) - return false; - - pthread_rwlock_rdlock(&data->reg_lock); - - ret = (find_reg_entry_by_name(data, name) != NULL); - - pthread_rwlock_unlock(&data->reg_lock); - - return ret; -} - -int ipcp_data_dir_add_entry(struct ipcp_data * data, - char * name, - uint64_t addr) -{ - struct dir_entry * entry; - char * entry_name; - - if (data == NULL || name == NULL) - return -1; - - pthread_rwlock_wrlock(&data->dir_lock); - - if (find_dir_entry(data, name, addr) != NULL) { - pthread_rwlock_unlock(&data->dir_lock); - return -1; - } - - entry_name = strdup(name); - if (entry_name == NULL) { - pthread_rwlock_unlock(&data->dir_lock); - return -1; - } - - entry = dir_entry_create(entry_name, addr); - if (entry == NULL) { - pthread_rwlock_unlock(&data->dir_lock); - return -1; - } - - list_add(&entry->list,&data->directory); - - pthread_rwlock_unlock(&data->dir_lock); - - LOG_DBG("Added directory entry for %s.", entry_name); - - return 0; -} - -int ipcp_data_dir_del_entry(struct ipcp_data * data, - const char * name, - uint64_t addr) -{ - struct dir_entry * e; - if (data == NULL) - return -1; - - pthread_rwlock_wrlock(&data->dir_lock); - - e = find_dir_entry(data, name, addr); - if (e == NULL) { - pthread_rwlock_unlock(&data->dir_lock); - return 0; /* nothing to do */ - } - - list_del(&e->list); - - pthread_rwlock_unlock(&data->dir_lock); - - dir_entry_destroy(e); - - return 0; -} - -bool ipcp_data_dir_has(struct ipcp_data * data, - const char * name) -{ - bool ret = false; - - pthread_rwlock_rdlock(&data->dir_lock); - - ret = (find_dir_entry_any(data, name) != NULL); - - pthread_rwlock_unlock(&data->dir_lock); - - return ret; -} - -uint64_t ipcp_data_dir_get_addr(struct ipcp_data * data, - const char * name) -{ - struct dir_entry * entry; - uint64_t addr; - - pthread_rwlock_rdlock(&data->dir_lock); - - entry = find_dir_entry_any(data, name); - - if (entry == NULL) { - pthread_rwlock_unlock(&data->dir_lock); - return 0; /* undefined behaviour, 0 may be a valid address */ - } - - addr = entry->addr; - - pthread_rwlock_unlock(&data->dir_lock); - - return addr; -} - -struct dir_query * ipcp_data_dir_query_create(char * name) -{ - struct dir_query * query; - pthread_condattr_t cattr; - - query = malloc(sizeof(*query)); - if (query == NULL) - return NULL; - - query->name = strdup(name); - if (query->name == NULL) { - free(query); - return NULL; - } - - query->state = QUERY_INIT; - - pthread_condattr_init(&cattr); -#ifndef __APPLE__ - pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK); -#endif - pthread_cond_init(&query->cond, &cattr); - pthread_mutex_init(&query->lock, NULL); - - list_head_init(&query->next); - - return query; -} - -void ipcp_data_dir_query_respond(struct dir_query * query) -{ - assert(query); - - pthread_mutex_lock(&query->lock); - - if (query->state != QUERY_PENDING) { - pthread_mutex_unlock(&query->lock); - return; - } - - query->state = QUERY_RESPONSE; - pthread_cond_broadcast(&query->cond); - - while (query->state == QUERY_RESPONSE) - pthread_cond_wait(&query->cond, &query->lock); - - pthread_mutex_unlock(&query->lock); -} - -void ipcp_data_dir_query_destroy(struct dir_query * query) -{ - assert(query); - - pthread_mutex_lock(&query->lock); - - if (query->state == QUERY_DESTROY) { - pthread_mutex_unlock(&query->lock); - return; - } - - if (query->state == QUERY_INIT) - query->state = QUERY_DONE; - - if (query->state == QUERY_PENDING) { - query->state = QUERY_DESTROY; - pthread_cond_broadcast(&query->cond); - } - - while (query->state != QUERY_DONE) - pthread_cond_wait(&query->cond, &query->lock); - - pthread_mutex_unlock(&query->lock); - - pthread_cond_destroy(&query->cond); - pthread_mutex_destroy(&query->lock); - - free(query->name); - free(query); -} - -int ipcp_data_dir_query_wait(struct dir_query * query, - const struct timespec * timeout) -{ - struct timespec abstime; - int ret = 0; - - assert(query); - assert(timeout); - - clock_gettime(PTHREAD_COND_CLOCK, &abstime); - ts_add(&abstime, timeout, &abstime); - - pthread_mutex_lock(&query->lock); - - if (query->state != QUERY_INIT) { - pthread_mutex_unlock(&query->lock); - return -EINVAL; - } - - query->state = QUERY_PENDING; - - while (query->state == QUERY_PENDING) { - if ((ret = -pthread_cond_timedwait(&query->cond, - &query->lock, - &abstime)) == -ETIMEDOUT) - break; - } - - if (query->state == QUERY_DESTROY) - ret = -1; - - query->state = QUERY_DONE; - pthread_cond_broadcast(&query->cond); - - pthread_mutex_unlock(&query->lock); - - return ret; -} |