summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/frr_pthread.c144
-rw-r--r--lib/frr_pthread.h24
-rw-r--r--lib/if.c6
-rw-r--r--lib/log.c1
-rw-r--r--lib/zclient.c16
-rw-r--r--lib/zclient.h3
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
diff --git a/lib/if.c b/lib/if.c
index 6b551a9fa1..67e2d366cd 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -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);
diff --git a/lib/log.c b/lib/log.c
index 52ea8d9003..2d800baae1 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -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);