#include <pthread.h>
#include "frratomic.h"
#include "memory.h"
+#include "frrcu.h"
#include "thread.h"
#ifdef __cplusplus
/* pthread id */
pthread_t thread;
+ struct rcu_thread *rcu_thread;
+
/* thread master for this pthread's thread.c event loop */
struct thread_master *master;
char os_name[OS_THREAD_NAMELEN];
};
-extern struct frr_pthread_attr frr_pthread_attr_default;
+extern const struct frr_pthread_attr frr_pthread_attr_default;
/*
* Initializes this module.
* @param os_name - 16 characters (including '\0') thread name to set in os,
* @return the created frr_pthread upon success, or NULL upon failure
*/
-struct frr_pthread *frr_pthread_new(struct frr_pthread_attr *attr,
+struct frr_pthread *frr_pthread_new(const struct frr_pthread_attr *attr,
const char *name, const char *os_name);
/*
#define pthread_condattr_setclock(A, B)
#endif
+/* mutex auto-lock/unlock */
+
+/* variant 1:
+ * (for short blocks, multiple mutexes supported)
+ * break & return can be used for aborting the block
+ *
+ * frr_with_mutex(&mtx, &mtx2) {
+ * if (error)
+ * break;
+ * ...
+ * }
+ */
+#define _frr_with_mutex(mutex) \
+ *NAMECTR(_mtx_) __attribute__(( \
+ unused, cleanup(_frr_mtx_unlock))) = _frr_mtx_lock(mutex), \
+ /* end */
+
+#define frr_with_mutex(...) \
+ for (pthread_mutex_t MACRO_REPEAT(_frr_with_mutex, ##__VA_ARGS__) \
+ *_once = NULL; _once == NULL; _once = (void *)1) \
+ /* end */
+
+/* variant 2:
+ * (more suitable for long blocks, no extra indentation)
+ *
+ * frr_mutex_lock_autounlock(&mtx);
+ * ...
+ */
+#define frr_mutex_lock_autounlock(mutex) \
+ pthread_mutex_t *NAMECTR(_mtx_) \
+ __attribute__((unused, cleanup(_frr_mtx_unlock))) = \
+ _frr_mtx_lock(mutex) \
+ /* end */
+
+static inline pthread_mutex_t *_frr_mtx_lock(pthread_mutex_t *mutex)
+{
+ pthread_mutex_lock(mutex);
+ return mutex;
+}
+
+static inline void _frr_mtx_unlock(pthread_mutex_t **mutex)
+{
+ if (!*mutex)
+ return;
+ pthread_mutex_unlock(*mutex);
+ *mutex = NULL;
+}
+
#ifdef __cplusplus
}
#endif