summaryrefslogtreecommitdiffstats
path: root/lib/mqueue.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mqueue.h')
-rw-r--r--lib/mqueue.h282
1 files changed, 282 insertions, 0 deletions
diff --git a/lib/mqueue.h b/lib/mqueue.h
new file mode 100644
index 00000000..6fb519d4
--- /dev/null
+++ b/lib/mqueue.h
@@ -0,0 +1,282 @@
+/* Message Queue data structure -- header
+ * Copyright (C) 2009 Chris Hall (GMCH), Highwayman
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ZEBRA_MQUEUE_H
+#define _ZEBRA_MQUEUE_H
+
+#include "qpthreads.h"
+#include "qtime.h"
+
+#ifndef Inline
+#define Inline static inline
+#endif
+
+/*==============================================================================
+ */
+
+typedef struct mqueue_block* mqueue_block ;
+
+typedef uint32_t mqb_flags_t ;
+typedef uint32_t mqb_context_t ;
+
+typedef void* mqb_ptr_t ;
+typedef intptr_t mqb_int_t ;
+typedef uintptr_t mqb_uint_t ;
+
+typedef union
+{
+ mqb_ptr_t p ;
+ mqb_int_t i ;
+ mqb_uint_t u ;
+} mqb_arg_t ;
+
+typedef void mqueue_action(mqueue_block mqb) ;
+
+struct mqueue_block
+{
+ mqueue_block next ; /* single linked list */
+
+ mqueue_action* action ; /* for message dispatch */
+
+ mqb_flags_t flags ; /* for message handler */
+
+ mqb_context_t context ; /* for message revoke */
+
+ mqb_arg_t arg0 ; /* may be pointer or integer */
+ mqb_arg_t arg1 ; /* may be pointer or integer */
+} ;
+
+typedef struct mqueue_thread_signal* mqueue_thread_signal ;
+
+struct mqueue_thread_signal {
+ mqueue_thread_signal next ; /* NULL => last on list */
+ mqueue_thread_signal prev ; /* NULL => NOT on list -- vital ! */
+
+ qpt_thread_t qpthread ; /* qpthread to kick */
+ int signum ; /* signal to kick with */
+} ;
+
+enum mqueue_queue_type {
+ mqt_cond_unicast, /* use qpt_cond_signal to kick the queue */
+ mqt_cond_broadcast, /* use qpt_cond_broadcast to kick the queue */
+ mqt_signal_unicast, /* use single qpt_signal to kick the queue */
+ mqt_signal_broadcast, /* use multiple qpt_signal to kick the queue */
+};
+
+#ifndef MQUEUE_DEFAULT_INTERVAL
+# define MQUEUE_DEFAULT_INTERVAL QTIME(5)
+#endif
+
+struct mqueue_queue_cond {
+ qpt_cond_t wait_here ;
+ qtime_mono_t timeout ;
+ qtime_t interval ;
+} ;
+
+struct mqueue_queue_signal {
+ mqueue_thread_signal head ; /* NULL => list is empty */
+ mqueue_thread_signal tail ;
+};
+
+typedef struct mqueue_queue* mqueue_queue ;
+
+struct mqueue_queue
+{
+ qpt_mutex_t mutex ;
+
+ mqueue_block head ; /* NULL => list is empty */
+ mqueue_block tail_priority ; /* last priority message (if any & not empty) */
+ mqueue_block tail ; /* last message (if not empty) */
+
+ enum mqueue_queue_type type ;
+
+ unsigned waiters ;
+
+ union {
+ struct mqueue_queue_cond cond ;
+ struct mqueue_queue_signal signal ;
+ } kick ;
+} ;
+
+/*==============================================================================
+ * Functions
+ */
+
+void
+mqueue_initialise(void) ;
+
+mqueue_queue
+mqueue_init_new(mqueue_queue mq, enum mqueue_queue_type type) ;
+
+void
+mqueue_set_timeout_interval(mqueue_queue mq, qtime_t interval) ;
+
+mqueue_thread_signal
+mqueue_thread_signal_init(mqueue_thread_signal mqt, qpt_thread_t thread,
+ int signum) ;
+mqueue_block
+mqb_init_new(mqueue_block mqb, mqueue_action action, mqb_context_t context) ;
+
+#define mqb_new(action, context) mqb_init_new(NULL, action, context)
+
+void
+mqb_free(mqueue_block mqb) ;
+
+void
+mqueue_enqueue(mqueue_queue mq, mqueue_block mqb, int priority) ;
+
+mqueue_block
+mqueue_dequeue(mqueue_queue mq, int wait, void* arg) ;
+
+int
+mqueue_done_waiting(mqueue_queue mq, mqueue_thread_signal mtsig) ;
+
+/*==============================================================================
+ * Access functions for mqueue_block fields -- mqb_set_xxx/mqb_get_xxx
+ *
+ * Users should not poke around inside the mqueue_block structure.
+ */
+
+Inline void mqb_set_action(mqueue_block mqb, mqueue_action action) ;
+Inline void mqb_set_context(mqueue_block mqb, mqb_context_t context) ;
+
+Inline void mqb_set_arg0_p(mqueue_block mqb, mqb_ptr_t p) ;
+Inline void mqb_set_arg0_i(mqueue_block mqb, mqb_int_t i) ;
+Inline void mqb_set_arg0_u(mqueue_block mqb, mqb_uint_t u) ;
+Inline void mqb_set_arg1_p(mqueue_block mqb, mqb_ptr_t p) ;
+Inline void mqb_set_arg1_i(mqueue_block mqb, mqb_int_t i) ;
+Inline void mqb_set_arg1_u(mqueue_block mqb, mqb_uint_t u) ;
+
+Inline void mqb_dispatch(mqueue_block mqb) ;
+Inline mqb_context_t mqb_qet_context(mqueue_block mqb) ;
+
+Inline mqb_ptr_t mqb_get_arg0_p(mqueue_block mqb) ;
+Inline mqb_int_t mqb_get_arg0_i(mqueue_block mqb) ;
+Inline mqb_uint_t mqb_get_arg0_u(mqueue_block mqb) ;
+Inline mqb_ptr_t mqb_get_arg1_p(mqueue_block mqb) ;
+Inline mqb_int_t mqb_get_arg1_i(mqueue_block mqb) ;
+Inline mqb_uint_t mqb_get_arg1_u(mqueue_block mqb) ;
+
+/*==============================================================================
+ * The Inline functions.
+ */
+
+/* Set operations. */
+
+Inline void
+mqb_set_action(mqueue_block mqb, mqueue_action action)
+{
+ mqb->action = action ;
+} ;
+
+Inline void
+mqb_set_context(mqueue_block mqb, mqb_context_t context)
+{
+ mqb->context = context ;
+} ;
+
+Inline void
+mqb_set_arg0_p(mqueue_block mqb, mqb_ptr_t p)
+{
+ mqb->arg0.p = p ;
+} ;
+
+Inline void
+mqb_set_arg0_i(mqueue_block mqb, mqb_int_t i)
+{
+ mqb->arg0.i = i ;
+} ;
+
+Inline void
+mqb_set_arg0_u(mqueue_block mqb, mqb_uint_t u)
+{
+ mqb->arg0.u = u ;
+} ;
+
+Inline void
+mqb_set_arg1_p(mqueue_block mqb, mqb_ptr_t p)
+{
+ mqb->arg1.p = p ;
+} ;
+
+Inline void
+mqb_set_arg1_i(mqueue_block mqb, mqb_int_t i)
+{
+ mqb->arg1.i = i ;
+} ;
+
+Inline void
+mqb_set_arg1_u(mqueue_block mqb, mqb_uint_t u)
+{
+ mqb->arg1.u = u ;
+} ;
+
+/* Get operations */
+
+Inline void
+mqb_dispatch(mqueue_block mqb)
+{
+ mqb->action(mqb) ;
+} ;
+
+Inline mqb_context_t
+mqb_qet_context(mqueue_block mqb)
+{
+ return mqb->context ;
+} ;
+
+Inline mqb_ptr_t
+mqb_get_arg0_p(mqueue_block mqb)
+{
+ return mqb->arg0.p ;
+} ;
+
+Inline mqb_int_t
+mqb_get_arg0_i(mqueue_block mqb)
+{
+ return mqb->arg0.i ;
+} ;
+
+Inline mqb_uint_t
+mqb_get_arg0_u(mqueue_block mqb)
+{
+ return mqb->arg0.u ;
+} ;
+
+Inline mqb_ptr_t
+mqb_get_arg1_p(mqueue_block mqb)
+{
+ return mqb->arg1.p ;
+} ;
+
+Inline mqb_int_t
+mqb_get_arg1_i(mqueue_block mqb)
+{
+ return mqb->arg1.i ;
+} ;
+
+Inline mqb_uint_t
+mqb_get_arg1_u(mqueue_block mqb)
+{
+ return mqb->arg1.u ;
+} ;
+
+#endif /* _ZEBRA_MQUEUE_H */