diff options
Diffstat (limited to 'lib/qpnexus.c')
-rw-r--r-- | lib/qpnexus.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/lib/qpnexus.c b/lib/qpnexus.c new file mode 100644 index 00000000..01985d29 --- /dev/null +++ b/lib/qpnexus.c @@ -0,0 +1,120 @@ +/* Quagga Pthreads support -- 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. + */ + +/* This MUST come first... otherwise we don't get __USE_UNIX98, which is */ +/* essential if glibc is to allow pthread_mutexattr_settype() to be used. */ +#include "config.h" + +#include <signal.h> +#include <string.h> + +#include "qpnexus.h" +#include "memory.h" + +/* prototypes */ +static void* qpn_start(void* arg); + +/*============================================================================== + * Quagga Nexus Interface -- qpt_xxxx + * + + */ + +/* Initialise a nexus -- allocating it if required. + * + * Returns the qtn_nexus. + */ +qpn_nexus +qpn_init_new(qpn_nexus qpn) +{ + if (qpn == NULL) + qpn = XCALLOC(MTYPE_QPN_NEXUS, sizeof(struct qpn_nexus)) ; + else + memset(qpn, 0, sizeof(struct qpn_nexus)) ; + + qpn->selection = qps_selection_init_new(qpn->selection); + qpn->pile = qtimer_pile_init_new(qpn->pile); + + /* TODO mqueue initialisation */ + + return qpn; +} + +void +qpn_free(qpn_nexus qpn) +{ + /* timers and the pile */ + qtimer qtr; + while ((qtr = qtimer_pile_ream(qpn->pile, 1))) + { + qtimer_free(qtr); + } + + /* TODO: free qtn->selection */ + + /* TODO: free qtn->queue */ + + XFREE(MTYPE_QPN_NEXUS, qpn) ; +} + +/* Create and execute the qpthread */ +void +qpn_exec(qpn_nexus qpn) +{ + qpn->thread_id = qpt_thread_create(qpn_start, qpn, NULL) ; +} + +static void* +qpn_start(void* arg) +{ + qpn_nexus qpn = arg; + int actions; + + while (!qpn->terminate) + { + qtime_mono_t now = qt_get_monotonic(); + + /* process timers */ + while (qtimer_pile_dispatch_next(qpn->pile, now)) + { + } + + /* block for some input, output or timeout */ + actions = qps_pselect( qpn->selection, + qtimer_pile_top_time(qpn->pile, now + QTIME(MAX_PSELECT_TIMOUT)) ); + + /* process I/O actions */ + while (actions) + { + actions = qps_dispatch_next(qpn->selection) ; + } + + /* TODO process message queue */ + } + + qpn_free(qpn); + + return NULL; +} + + + + |