diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/frr_pthread.c | 144 | ||||
| -rw-r--r-- | lib/frr_pthread.h | 24 | ||||
| -rw-r--r-- | lib/if.c | 6 | ||||
| -rw-r--r-- | lib/log.c | 1 | ||||
| -rw-r--r-- | lib/zclient.c | 16 | ||||
| -rw-r--r-- | lib/zclient.h | 3 |
6 files changed, 58 insertions, 136 deletions
diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c index d48b23f38a..c1ce57e24e 100644 --- a/lib/frr_pthread.c +++ b/lib/frr_pthread.c @@ -26,108 +26,77 @@ #include "frr_pthread.h" #include "memory.h" -#include "hash.h" +#include "linklist.h" DEFINE_MTYPE(LIB, FRR_PTHREAD, "FRR POSIX Thread"); DEFINE_MTYPE(LIB, PTHREAD_PRIM, "POSIX synchronization primitives"); -/* id for next created pthread */ -static _Atomic uint32_t next_id = 0; - /* default frr_pthread start/stop routine prototypes */ static void *fpt_run(void *arg); static int fpt_halt(struct frr_pthread *fpt, void **res); /* default frr_pthread attributes */ struct frr_pthread_attr frr_pthread_attr_default = { - .id = 0, .start = fpt_run, .stop = fpt_halt, }; -/* hash table to keep track of all frr_pthreads */ -static struct hash *frr_pthread_hash; -static pthread_mutex_t frr_pthread_hash_mtx = PTHREAD_MUTEX_INITIALIZER; - -/* frr_pthread_hash->hash_cmp */ -static int frr_pthread_hash_cmp(const void *value1, const void *value2) -{ - const struct frr_pthread *tq1 = value1; - const struct frr_pthread *tq2 = value2; - - return (tq1->attr.id == tq2->attr.id); -} - -/* frr_pthread_hash->hash_key */ -static unsigned int frr_pthread_hash_key(void *value) -{ - return ((struct frr_pthread *)value)->attr.id; -} +/* list to keep track of all frr_pthreads */ +static pthread_mutex_t frr_pthread_list_mtx = PTHREAD_MUTEX_INITIALIZER; +static struct list *frr_pthread_list; /* ------------------------------------------------------------------------ */ void frr_pthread_init() { - pthread_mutex_lock(&frr_pthread_hash_mtx); + pthread_mutex_lock(&frr_pthread_list_mtx); { - frr_pthread_hash = hash_create(frr_pthread_hash_key, - frr_pthread_hash_cmp, NULL); + frr_pthread_list = list_new(); + frr_pthread_list->del = (void (*)(void *))&frr_pthread_destroy; } - pthread_mutex_unlock(&frr_pthread_hash_mtx); + pthread_mutex_unlock(&frr_pthread_list_mtx); } void frr_pthread_finish() { - pthread_mutex_lock(&frr_pthread_hash_mtx); + pthread_mutex_lock(&frr_pthread_list_mtx); { - hash_clean(frr_pthread_hash, - (void (*)(void *))frr_pthread_destroy); - hash_free(frr_pthread_hash); + list_delete_and_null(&frr_pthread_list); } - pthread_mutex_unlock(&frr_pthread_hash_mtx); + pthread_mutex_unlock(&frr_pthread_list_mtx); } struct frr_pthread *frr_pthread_new(struct frr_pthread_attr *attr, const char *name, const char *os_name) { - static struct frr_pthread holder = {}; struct frr_pthread *fpt = NULL; attr = attr ? attr : &frr_pthread_attr_default; - pthread_mutex_lock(&frr_pthread_hash_mtx); + fpt = XCALLOC(MTYPE_FRR_PTHREAD, sizeof(struct frr_pthread)); + /* initialize mutex */ + pthread_mutex_init(&fpt->mtx, NULL); + /* create new thread master */ + fpt->master = thread_master_create(name); + /* set attributes */ + fpt->attr = *attr; + name = (name ? name : "Anonymous thread"); + fpt->name = XSTRDUP(MTYPE_FRR_PTHREAD, name); + if (os_name) + snprintf(fpt->os_name, OS_THREAD_NAMELEN, "%s", os_name); + /* initialize startup synchronization primitives */ + fpt->running_cond_mtx = XCALLOC( + MTYPE_PTHREAD_PRIM, sizeof(pthread_mutex_t)); + fpt->running_cond = XCALLOC(MTYPE_PTHREAD_PRIM, + sizeof(pthread_cond_t)); + pthread_mutex_init(fpt->running_cond_mtx, NULL); + pthread_cond_init(fpt->running_cond, NULL); + + pthread_mutex_lock(&frr_pthread_list_mtx); { - holder.attr.id = attr->id; - - if (!hash_lookup(frr_pthread_hash, &holder)) { - fpt = XCALLOC(MTYPE_FRR_PTHREAD, - sizeof(struct frr_pthread)); - /* initialize mutex */ - pthread_mutex_init(&fpt->mtx, NULL); - /* create new thread master */ - fpt->master = thread_master_create(name); - /* set attributes */ - fpt->attr = *attr; - name = (name ? name : "Anonymous thread"); - fpt->name = XSTRDUP(MTYPE_FRR_PTHREAD, name); - if (os_name) - snprintf(fpt->os_name, OS_THREAD_NAMELEN, - "%s", os_name); - if (attr == &frr_pthread_attr_default) - fpt->attr.id = frr_pthread_get_id(); - /* initialize startup synchronization primitives */ - fpt->running_cond_mtx = XCALLOC( - MTYPE_PTHREAD_PRIM, sizeof(pthread_mutex_t)); - fpt->running_cond = XCALLOC(MTYPE_PTHREAD_PRIM, - sizeof(pthread_cond_t)); - pthread_mutex_init(fpt->running_cond_mtx, NULL); - pthread_cond_init(fpt->running_cond, NULL); - - /* insert into global thread hash */ - hash_get(frr_pthread_hash, fpt, hash_alloc_intern); - } + listnode_add(frr_pthread_list, fpt); } - pthread_mutex_unlock(&frr_pthread_hash_mtx); + pthread_mutex_unlock(&frr_pthread_list_mtx); return fpt; } @@ -180,21 +149,6 @@ int frr_pthread_set_name(struct frr_pthread *fpt, const char *name, return ret; } -struct frr_pthread *frr_pthread_get(uint32_t id) -{ - static struct frr_pthread holder = {}; - struct frr_pthread *fpt; - - pthread_mutex_lock(&frr_pthread_hash_mtx); - { - holder.attr.id = id; - fpt = hash_lookup(frr_pthread_hash, &holder); - } - pthread_mutex_unlock(&frr_pthread_hash_mtx); - - return fpt; -} - int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr) { int ret; @@ -239,36 +193,16 @@ int frr_pthread_stop(struct frr_pthread *fpt, void **result) return ret; } -/* - * Callback for hash_iterate to stop all frr_pthread's. - */ -static void frr_pthread_stop_all_iter(struct hash_backet *hb, void *arg) -{ - struct frr_pthread *fpt = hb->data; - frr_pthread_stop(fpt, NULL); -} - void frr_pthread_stop_all() { - pthread_mutex_lock(&frr_pthread_hash_mtx); + pthread_mutex_lock(&frr_pthread_list_mtx); { - hash_iterate(frr_pthread_hash, frr_pthread_stop_all_iter, NULL); + struct listnode *n; + struct frr_pthread *fpt; + for (ALL_LIST_ELEMENTS_RO(frr_pthread_list, n, fpt)) + frr_pthread_stop(fpt, NULL); } - pthread_mutex_unlock(&frr_pthread_hash_mtx); -} - -uint32_t frr_pthread_get_id(void) -{ - _Atomic uint32_t nxid; - nxid = atomic_fetch_add_explicit(&next_id, 1, memory_order_seq_cst); - /* just a sanity check, this should never happen */ - assert(nxid <= (UINT32_MAX - 1)); - return nxid; -} - -void frr_pthread_yield(void) -{ - (void)sched_yield(); + pthread_mutex_unlock(&frr_pthread_list_mtx); } /* diff --git a/lib/frr_pthread.h b/lib/frr_pthread.h index 732e2925fe..b9e60511d5 100644 --- a/lib/frr_pthread.h +++ b/lib/frr_pthread.h @@ -34,7 +34,6 @@ struct frr_pthread; struct frr_pthread_attr; struct frr_pthread_attr { - _Atomic uint32_t id; void *(*start)(void *); int (*stop)(struct frr_pthread *, void **); }; @@ -155,13 +154,6 @@ int frr_pthread_set_name(struct frr_pthread *fpt, const char *name, void frr_pthread_destroy(struct frr_pthread *fpt); /* - * Gets an existing frr_pthread by its id. - * - * @return frr_thread associated with the provided id, or NULL on error - */ -struct frr_pthread *frr_pthread_get(uint32_t id); - -/* * Creates a new pthread and binds it to a frr_pthread. * * This function is a wrapper for pthread_create. The first parameter is the @@ -218,22 +210,6 @@ int frr_pthread_stop(struct frr_pthread *fpt, void **result); /* Stops all frr_pthread's. */ void frr_pthread_stop_all(void); -/* Yields the current thread of execution */ -void frr_pthread_yield(void); - -/* - * Returns a unique identifier for use with frr_pthread_new(). - * - * Internally, this is an integer that increments after each call to this - * function. Because the number of pthreads created should never exceed INT_MAX - * during the life of the program, there is no overflow protection. If by - * chance this function returns an ID which is already in use, - * frr_pthread_new() will fail when it is provided. - * - * @return unique identifier - */ -uint32_t frr_pthread_get_id(void); - #ifndef HAVE_PTHREAD_CONDATTR_SETCLOCK #define pthread_condattr_setclock(A, B) #endif @@ -656,7 +656,8 @@ DEFUN_NOSH (interface, int idx_ifname = 1; int idx_vrf = 3; const char *ifname = argv[idx_ifname]->arg; - const char *vrfname = (argc > 2) ? argv[idx_vrf]->arg : NULL; + const char *vrfname = + (argc > 2) ? argv[idx_vrf]->arg : VRF_DEFAULT_NAME; struct interface *ifp; vrf_id_t vrf_id = VRF_DEFAULT; @@ -681,7 +682,8 @@ DEFUN_NOSH (interface, #endif /* SUNOS_5 */ if (!ifp) { - vty_out(vty, "%% interface %s not in %s\n", ifname, vrfname); + vty_out(vty, "%% interface %s not in %s vrf\n", ifname, + vrfname); return CMD_WARNING_CONFIG_FAILED; } VTY_PUSH_CONTEXT(INTERFACE_NODE, ifp); @@ -945,6 +945,7 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_MPLS_LABELS_DELETE), DESC_ENTRY(ZEBRA_IPMR_ROUTE_STATS), DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT), + DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT_ASYNC), DESC_ENTRY(ZEBRA_GET_LABEL_CHUNK), DESC_ENTRY(ZEBRA_RELEASE_LABEL_CHUNK), DESC_ENTRY(ZEBRA_ADVERTISE_ALL_VNI), diff --git a/lib/zclient.c b/lib/zclient.c index 1cdf4ff22e..e6626a178b 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1839,24 +1839,29 @@ static int zclient_read_sync_response(struct zclient *zclient, * immediately reads the answer from the input buffer. * * @param zclient Zclient used to connect to label manager (zebra) + * @param async Synchronous (0) or asynchronous (1) operation * @result Result of response */ -int lm_label_manager_connect(struct zclient *zclient) +int lm_label_manager_connect(struct zclient *zclient, int async) { int ret; struct stream *s; uint8_t result; + uint16_t cmd = async ? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC : + ZEBRA_LABEL_MANAGER_CONNECT; if (zclient_debug) zlog_debug("Connecting to Label Manager (LM)"); - if (zclient->sock < 0) + if (zclient->sock < 0) { + zlog_debug("%s: invalid zclient socket", __func__); return -1; + } /* send request */ s = zclient->obuf; stream_reset(s); - zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, VRF_DEFAULT); + zclient_create_header(s, cmd, VRF_DEFAULT); /* proto */ stream_putc(s, zclient->redist_default); @@ -1882,8 +1887,11 @@ int lm_label_manager_connect(struct zclient *zclient) if (zclient_debug) zlog_debug("LM connect request sent (%d bytes)", ret); + if (async) + return 0; + /* read response */ - if (zclient_read_sync_response(zclient, ZEBRA_LABEL_MANAGER_CONNECT) + if (zclient_read_sync_response(zclient, cmd) != 0) return -1; diff --git a/lib/zclient.h b/lib/zclient.h index cab734ae5e..54f3635901 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -112,6 +112,7 @@ typedef enum { ZEBRA_MPLS_LABELS_DELETE, ZEBRA_IPMR_ROUTE_STATS, ZEBRA_LABEL_MANAGER_CONNECT, + ZEBRA_LABEL_MANAGER_CONNECT_ASYNC, ZEBRA_GET_LABEL_CHUNK, ZEBRA_RELEASE_LABEL_CHUNK, ZEBRA_FEC_REGISTER, @@ -572,7 +573,7 @@ extern int zclient_send_get_label_chunk( uint8_t keep, uint32_t chunk_size); -extern int lm_label_manager_connect(struct zclient *zclient); +extern int lm_label_manager_connect(struct zclient *zclient, int async); extern int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t chunk_size, uint32_t *start, uint32_t *end); |
