summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_connection.c6
-rw-r--r--bgpd/bgp_engine.c55
-rw-r--r--bgpd/bgp_engine.h20
-rw-r--r--bgpd/bgp_main.c76
-rw-r--r--bgpd/bgp_msg_read.c1
-rw-r--r--bgpd/bgp_network.c2
-rw-r--r--bgpd/bgp_packet.c2
-rw-r--r--bgpd/bgp_peer.c29
-rw-r--r--bgpd/bgp_peer.h3
-rw-r--r--bgpd/bgp_session.c2
-rw-r--r--bgpd/bgpd.c30
-rw-r--r--lib/command.c12
-rw-r--r--lib/qpnexus.c133
-rw-r--r--lib/qpnexus.h19
-rw-r--r--lib/vty.c8
15 files changed, 173 insertions, 225 deletions
diff --git a/bgpd/bgp_connection.c b/bgpd/bgp_connection.c
index ba13c33a..9d937033 100644
--- a/bgpd/bgp_connection.c
+++ b/bgpd/bgp_connection.c
@@ -149,9 +149,9 @@ bgp_connection_init_new(bgp_connection connection, bgp_session session,
qps_file_init_new(&connection->qf, NULL) ;
/* Initialise all the timers */
- qtimer_init_new(&connection->hold_timer, p_bgp_engine->pile,
+ qtimer_init_new(&connection->hold_timer, bgp_nexus->pile,
NULL, connection) ;
- qtimer_init_new(&connection->keepalive_timer, p_bgp_engine->pile,
+ qtimer_init_new(&connection->keepalive_timer, bgp_nexus->pile,
NULL, connection) ;
/* Copy log destination and make host name + (primary)/(secondary) */
@@ -483,7 +483,7 @@ bgp_connection_open(bgp_connection connection, int fd)
bgp_connection_disable_accept(connection) ;
/* Set the file going */
- qps_add_file(p_bgp_engine->selection, &connection->qf, fd, connection) ;
+ qps_add_file(bgp_nexus->selection, &connection->qf, fd, connection) ;
/* Clear sundry state is clear */
connection->post = bgp_fsm_null_event ; /* no post event event */
diff --git a/bgpd/bgp_engine.c b/bgpd/bgp_engine.c
index c47094f6..f963d0d9 100644
--- a/bgpd/bgp_engine.c
+++ b/bgpd/bgp_engine.c
@@ -62,10 +62,7 @@
*
*/
-qpn_nexus p_bgp_engine ;
-
-static struct qpn_nexus bgp_engine ;
-
+extern qpn_nexus bgp_nexus ;
/*==============================================================================
* Start the BGP Engine Thread.
@@ -74,43 +71,22 @@ static struct qpn_nexus bgp_engine ;
*
*/
-static void* bgp_engine_loop(void* arg) ;
-
-/* TODO: BGP Engine side of bgp_engine_start() must call bgp_open_listeners()
- * for which it needs the port and address from command line.
+/* BGP Engine side of bgp_engine_start() must call bgp_open_listeners()
+ * for which it needs the port and address from command line.
+ *
+ * Implemented in bgp_main.c
*/
-extern void
-bgp_engine_start(void)
-{
- p_bgp_engine = qpn_init_new(&bgp_engine) ;
-
- p_bgp_engine->start = bgp_engine_loop ;
-
- p_bgp_engine->thread_id = qpt_thread_self() ;
-
- p_bgp_engine->selection = qps_selection_init_new(NULL) ;
- p_bgp_engine->pile = qtimer_pile_init_new(NULL) ;
- p_bgp_engine->queue = mqueue_init_new(NULL, mqt_signal_broadcast) ;
- p_bgp_engine->mts = mqueue_thread_signal_init(NULL,
- p_bgp_engine->thread_id, SIGMQUEUE) ;
-
- qpn_exec(p_bgp_engine) ;
-} ;
-
/*==============================================================================
* Stop the BGP Engine Thread.
*
*/
-/* TODO: BGP Engine side of bgp_engine_stop() must call bgp_close_listeners()
+/* BGP Engine side of bgp_engine_stop() must call bgp_close_listeners()
+ *
+ * Implemented in bgp_main.c
*/
-extern void
-bgp_engine_stop(void)
-{
-} ;
-
/*==============================================================================
* The BGP Engine Thread main loop
*
@@ -154,24 +130,11 @@ bgp_engine_stop(void)
*
* Which generate FSM events.
*
+ * Implemented in qpnexus.c
*
*/
-
-
-
-
-
-
-/*==============================================================================
- * The qpnexus for the BGP Engine.
- *
- *
- */
-
-
-
/*==============================================================================
* The write queue for the BGP Engine
*
diff --git a/bgpd/bgp_engine.h b/bgpd/bgp_engine.h
index 2ffba5d0..46a82093 100644
--- a/bgpd/bgp_engine.h
+++ b/bgpd/bgp_engine.h
@@ -37,15 +37,9 @@
#endif
-
-
-extern qpn_nexus p_bgp_engine ;
-extern qpn_nexus p_peering_engine ;
-
-extern void
-bgp_engine_start(void) ;
-
-
+extern qpn_nexus cli_nexus;
+extern qpn_nexus bgp_nexus;
+extern qpn_nexus routing_nexus;
/*==============================================================================
*
@@ -56,7 +50,7 @@ bgp_engine_start(void) ;
Inline void
bgp_to_bgp_engine(mqueue_block mqb)
{
- mqueue_enqueue(p_bgp_engine->queue, mqb, 0) ;
+ mqueue_enqueue(bgp_nexus->queue, mqb, 0) ;
} ;
/* Send given message to the BGP Engine -- priority
@@ -64,7 +58,7 @@ bgp_to_bgp_engine(mqueue_block mqb)
Inline void
bgp_to_bgp_engine_priority(mqueue_block mqb)
{
- mqueue_enqueue(p_bgp_engine->queue, mqb, 1) ;
+ mqueue_enqueue(bgp_nexus->queue, mqb, 1) ;
} ;
/*==============================================================================
@@ -76,7 +70,7 @@ bgp_to_bgp_engine_priority(mqueue_block mqb)
Inline void
bgp_to_peering_engine(mqueue_block mqb)
{
- mqueue_enqueue(p_peering_engine->queue, mqb, 0) ;
+ mqueue_enqueue(routing_nexus->queue, mqb, 0) ;
} ;
/* Send given message to the Peering Engine -- priority
@@ -84,7 +78,7 @@ bgp_to_peering_engine(mqueue_block mqb)
Inline void
bgp_to_peering_engine_priority(mqueue_block mqb)
{
- mqueue_enqueue(p_peering_engine->queue, mqb, 1) ;
+ mqueue_enqueue(routing_nexus->queue, mqb, 1) ;
} ;
#endif /* QUAGGA_BGP_ENGINE_H */
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index c7eca751..e6afe1ec 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -49,6 +49,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_clist.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_filter.h"
+#include "bgpd/bgp_network.h"
/* bgpd options, we use GNU getopt library. */
static const struct option longopts[] =
@@ -80,6 +81,7 @@ void sigusr2 (void);
/* prototypes */
static void bgp_exit (int);
static void init_second_stage(int pthreads);
+static void bgp_in_thread_init(void);
static struct quagga_signal_t bgp_signals[] =
{
@@ -221,14 +223,10 @@ sigint (void)
if (bgp_nexus != NULL)
qpn_terminate(bgp_nexus);
-
- if (cli_nexus != NULL)
- qpn_terminate(cli_nexus);
- }
- else
- {
- bgp_exit (0);
}
+
+ if (cli_nexus != NULL)
+ qpn_terminate(cli_nexus);
}
/* SIGUSR1 handler. */
@@ -340,8 +338,11 @@ bgp_exit (int status)
if (CONF_BGP_DEBUG (normal, NORMAL))
log_memstats_stderr ("bgpd");
- routing_nexus = qpn_free(routing_nexus);
- bgp_nexus = qpn_free(bgp_nexus);
+ if (qpthreads_enabled)
+ {
+ routing_nexus = qpn_free(routing_nexus);
+ bgp_nexus = qpn_free(bgp_nexus);
+ }
cli_nexus = qpn_free(cli_nexus);
qexit (status);
@@ -364,6 +365,17 @@ init_second_stage(int pthreads)
{
qlib_init_second_stage(pthreads);
bgp_peer_index_mutex_init(NULL);
+
+ /* if using pthreads create additional mutexes */
+ if (pthreads)
+ {
+ bgp_nexus = qpn_init_new(cli_nexus, 0);
+ routing_nexus = qpn_init_new(cli_nexus, 0);
+ }
+
+ /* legacy threads are executed in routing_nexus */
+ routing_nexus->master = master;
+ vty_init_r(cli_nexus, routing_nexus);
}
/* Main routine of bgpd. Treatment of argument and start bgp finite
state machine is handled at here. */
@@ -375,7 +387,6 @@ main (int argc, char **argv)
int daemon_mode = 0;
int dryrun = 0;
char *progname;
- struct thread thread;
int tmp_port;
/* Set umask before anything for security */
@@ -393,6 +404,11 @@ main (int argc, char **argv)
zlog_default = openzlog (progname, ZLOG_BGP,
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
+ /* Make nexus for main thread, always needed */
+ cli_nexus = qpn_init_new(cli_nexus, 1); /* main thread */
+ bgp_nexus = cli_nexus; /* use main thread for now */
+ routing_nexus = cli_nexus; /* use main thread for now */
+
/* BGP master init. */
bgp_master_init ();
@@ -518,15 +534,6 @@ main (int argc, char **argv)
if (!qpthreads_enabled)
init_second_stage(0);
- if (qpthreads_enabled)
- {
- cli_nexus = qpn_init_main(cli_nexus); /* main thread */
- bgp_nexus = qpn_init_bgp(bgp_nexus);
- routing_nexus = qpn_init_bgp(routing_nexus);
-
- vty_init_r(cli_nexus, bgp_nexus);
- }
-
/* Make bgp vty socket. */
vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
@@ -539,32 +546,39 @@ main (int argc, char **argv)
(bm->address ? bm->address : "<all>"),
(int)bm->port);
+ /* in-thread initialization and finalization.
+ * NB if !qpthreads_enabled then there is only 1 nexus object
+ * with all nexus pointers being alises for it. So if different
+ * logical nexus need their own init or final then will need a single
+ * init or final routine.
+ */
+ bgp_nexus->in_thread_init = bgp_in_thread_init;
+ bgp_nexus->in_thread_final = bgp_close_listeners;
- /* Launch finite state machines */
+ /* Launch finite state machine(s) */
if (qpthreads_enabled)
{
void * thread_result = NULL;
- /* TODO: exec routing_nexus */
- /* qpn_exec(routing_nexus); */
+ qpn_exec(routing_nexus);
qpn_exec(bgp_nexus);
qpn_exec(cli_nexus); /* must be last to start - on main thread */
/* terminating, wait for all threads to finish */
- /* TODO: join with routing_nexus */
- /* thread_result = qpt_thread_join(routing_nexus->thread_id); */
+ thread_result = qpt_thread_join(routing_nexus->thread_id);
thread_result = qpt_thread_join(bgp_nexus->thread_id);
- bgp_exit(0);
}
else
{
- /* Start finite state machine, here we go! */
- while (thread_fetch (master, &thread))
- thread_call (&thread);
+ qpn_exec(cli_nexus); /* only nexus - on main thread */
}
- /* Not reached. */
- return (0);
+ bgp_exit(0);
}
-
+/* bgp_nexus in-thread initialization */
+static void
+bgp_in_thread_init(void)
+{
+ bgp_open_listeners(bm->port, bm->address);
+}
diff --git a/bgpd/bgp_msg_read.c b/bgpd/bgp_msg_read.c
index 4e581f4f..bbe8796d 100644
--- a/bgpd/bgp_msg_read.c
+++ b/bgpd/bgp_msg_read.c
@@ -30,6 +30,7 @@
#include "bgpd/bgp_session.h"
#include "bgpd/bgp_open_state.h"
#include "bgpd/bgp_fsm.h"
+#include "bgpd/bgp_vty.h"
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 0f02ae38..10b3eba8 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -323,7 +323,7 @@ bgp_init_listener(int sock, struct sockaddr *sa, socklen_t salen)
listener = XCALLOC(MTYPE_BGP_LISTENER, sizeof(struct bgp_listener)) ;
qps_file_init_new(&listener->qf, NULL) ;
- qps_add_file(p_bgp_engine->selection, &listener->qf, sock, listener) ;
+ qps_add_file(bgp_nexus->selection, &listener->qf, sock, listener) ;
qps_enable_mode(&listener->qf, qps_read_mnum, bgp_accept_action) ;
memcpy(&listener->su, sa, salen) ;
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index f432f7a7..7814e111 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -613,7 +613,7 @@ bgp_write_proceed (struct peer *peer)
#endif
/*------------------------------------------------------------------------------
-/* Write packets to the peer -- subject to the XON flow control.
+ * Write packets to the peer -- subject to the XON flow control.
*
* Empties the obuf queue first.
*
diff --git a/bgpd/bgp_peer.c b/bgpd/bgp_peer.c
index fa5a0d1c..8f84a0ef 100644
--- a/bgpd/bgp_peer.c
+++ b/bgpd/bgp_peer.c
@@ -897,6 +897,35 @@ peer_free (struct peer *peer)
XFREE (MTYPE_BGP_PEER, peer);
}
+void
+peer_nsf_stop (struct peer *peer)
+{
+ afi_t afi;
+ safi_t safi;
+
+ UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
+ UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
+
+ for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
+ for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)
+ peer->nsf[afi][safi] = 0;
+
+ if (peer->t_gr_restart)
+ {
+ BGP_TIMER_OFF (peer->t_gr_restart);
+ if (BGP_DEBUG (events, EVENTS))
+ zlog_debug ("%s graceful restart timer stopped", peer->host);
+ }
+ if (peer->t_gr_stale)
+ {
+ BGP_TIMER_OFF (peer->t_gr_stale);
+ if (BGP_DEBUG (events, EVENTS))
+ zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
+ }
+ bgp_clear_route_all (peer);
+}
+
+
/* Disable then enable the peer. Sends notification. */
void
bgp_peer_reenable(bgp_peer peer, bgp_notify notification)
diff --git a/bgpd/bgp_peer.h b/bgpd/bgp_peer.h
index c3c8b88d..2a8eb78a 100644
--- a/bgpd/bgp_peer.h
+++ b/bgpd/bgp_peer.h
@@ -493,5 +493,8 @@ peer_delete (struct peer *peer);
extern void
peer_free (struct peer *peer);
+extern void
+peer_nsf_stop (struct peer *peer);
+
#endif /* _QUAGGA_BGP_PEER_H */
diff --git a/bgpd/bgp_session.c b/bgpd/bgp_session.c
index 0aae7168..5ab0f3b8 100644
--- a/bgpd/bgp_session.c
+++ b/bgpd/bgp_session.c
@@ -371,7 +371,7 @@ bgp_session_do_disable(mqueue_block mqb, mqb_flag_t flag)
struct bgp_session_disable_args* args = mqb_get_args(mqb) ;
/* Immediately discard any other messages for this session. */
- mqueue_revoke(p_bgp_engine->queue, session) ;
+ mqueue_revoke(bgp_nexus->queue, session) ;
/* Get the FSM to send any notification and close connections */
bgp_fsm_disable_session(session, args->notification) ;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 442ef607..d7baa608 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -959,36 +959,6 @@ peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
return 0;
}
-static void
-peer_nsf_stop (struct peer *peer)
-{
- afi_t afi;
- safi_t safi;
-
- UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
- UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
-
- for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
- for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)
- peer->nsf[afi][safi] = 0;
-
- if (peer->t_gr_restart)
- {
- BGP_TIMER_OFF (peer->t_gr_restart);
- if (BGP_DEBUG (events, EVENTS))
- zlog_debug ("%s graceful restart timer stopped", peer->host);
- }
- if (peer->t_gr_stale)
- {
- BGP_TIMER_OFF (peer->t_gr_stale);
- if (BGP_DEBUG (events, EVENTS))
- zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
- }
- bgp_clear_route_all (peer);
-}
-
-
-
static int
peer_group_cmp (struct peer_group *g1, struct peer_group *g2)
{
diff --git a/lib/command.c b/lib/command.c
index c3c9145d..574e45bf 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -1992,7 +1992,7 @@ node_parent ( enum node_type node )
/* Execute command by argument vline vector. */
static int
cmd_execute_command_real (vector vline, struct vty *vty,
- struct cmd_element **cmd, qpn_nexus bgp_nexus)
+ struct cmd_element **cmd, qpn_nexus dest_nexus)
{
unsigned int i;
unsigned int index;
@@ -2111,7 +2111,7 @@ cmd_execute_command_real (vector vline, struct vty *vty,
if (qpthreads_enabled && !(matched_element->attr & CMD_ATTR_CALL))
{
/* Don't do it now, but send to bgp qpthread */
- cq_enqueue(matched_element, vty, argc, argv, bgp_nexus);
+ cq_enqueue(matched_element, vty, argc, argv, dest_nexus);
return CMD_QUEUED;
}
else
@@ -2122,7 +2122,7 @@ cmd_execute_command_real (vector vline, struct vty *vty,
int
cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
- qpn_nexus bgp_nexus, int vtysh) {
+ qpn_nexus dest_nexus, int vtysh) {
int ret, saved_ret, tried = 0;
enum node_type onode, try_node;
@@ -2143,7 +2143,7 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
}
- ret = cmd_execute_command_real (shifted_vline, vty, cmd, bgp_nexus);
+ ret = cmd_execute_command_real (shifted_vline, vty, cmd, dest_nexus);
vector_free(shifted_vline);
vty_set_node(vty, onode);
@@ -2151,7 +2151,7 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
}
- saved_ret = ret = cmd_execute_command_real (vline, vty, cmd, bgp_nexus);
+ saved_ret = ret = cmd_execute_command_real (vline, vty, cmd, dest_nexus);
if (vtysh)
return saved_ret;
@@ -2162,7 +2162,7 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
{
try_node = node_parent(try_node);
vty_set_node(vty, try_node);
- ret = cmd_execute_command_real (vline, vty, cmd, bgp_nexus);
+ ret = cmd_execute_command_real (vline, vty, cmd, dest_nexus);
tried = 1;
if (ret == CMD_SUCCESS || ret == CMD_WARNING)
{
diff --git a/lib/qpnexus.c b/lib/qpnexus.c
index 5ecb97cf..98bd767c 100644
--- a/lib/qpnexus.c
+++ b/lib/qpnexus.c
@@ -28,12 +28,8 @@
/* prototypes */
static void* qpn_start(void* arg);
-static void* qpn_start_bgp(void* arg);
static void qpn_in_thread_init(qpn_nexus qpn);
-/* Master of the threads. */
-extern struct thread_master *master;
-
/*==============================================================================
* Quagga Nexus Interface -- qpn_xxxx
*
@@ -50,54 +46,17 @@ extern struct thread_master *master;
* Returns the qpn_nexus.
*/
qpn_nexus
-qpn_init_new(qpn_nexus qpn)
+qpn_init_new(qpn_nexus qpn, int main_thread)
{
if (qpn == NULL)
qpn = XCALLOC(MTYPE_QPN_NEXUS, sizeof(struct qpn_nexus)) ;
else
memset(qpn, 0, sizeof(struct qpn_nexus)) ;
- return qpn;
-}
-
-/* Initialize main qpthread */
-qpn_nexus
-qpn_init_main(qpn_nexus qpn)
-{
- qpn = qpn_init_new(qpn);
- qpn->selection = qps_selection_init_new(qpn->selection);
- qpn->pile = qtimer_pile_init_new(qpn->pile);
- qpn->queue = mqueue_init_new(qpn->queue, mqt_signal_unicast);
- qpn->main_thread = 1;
- qpn->start = qpn_start;
-
- return qpn;
-}
-
-/* Initialize bgp engine's qpthread */
-qpn_nexus
-qpn_init_bgp(qpn_nexus qpn)
-{
- qpn = qpn_init_new(qpn);
- qpn->queue = mqueue_init_new(qpn->queue, mqt_signal_unicast);
- qpn->start = qpn_start_bgp;
-
- return qpn;
-}
-
-/* Initialize Routing engine's qpthread
- *
- * Although not expected to do I/O we still use qps_selection (pselect) as
- * the mechanism to wait for either a timeout or a signal from the message
- * queue.
-*/
-qpn_nexus
-qpn_init_routing(qpn_nexus qpn)
-{
- qpn = qpn_init_new(qpn);
qpn->selection = qps_selection_init_new(qpn->selection);
qpn->pile = qtimer_pile_init_new(qpn->pile);
qpn->queue = mqueue_init_new(qpn->queue, mqt_signal_unicast);
+ qpn->main_thread = main_thread;
qpn->start = qpn_start;
return qpn;
@@ -155,9 +114,30 @@ qpn_exec(qpn_nexus qpn)
}
}
-/* Thread routine, complete init, then run finite state machine
- * using mqueue, qps_selection and qtimer
-*/
+/*==============================================================================
+ * Pthread routine
+ *
+ * Processes:
+ *
+ * 1) Main thread only -- signals.
+ *
+ * 2) Pending work -- local queue.
+ *
+ * 3) messages coming from other pthreads -- mqueue_queue.
+ *
+ * 4) I/O -- qpselect
+ *
+ * This deals with all active sockets for read/write/connect/accept.
+ *
+ * Each time a socket is readable, one message is read and dispatched.
+ * The pselect timeout is set to be when the next timer is due.
+ *
+ * 5) Timers -- qtimers
+ *
+ * 6) Legacy threads. To deal with legacy timer mechanism.
+ *
+ *
+ */
static void*
qpn_start(void* arg)
{
@@ -165,6 +145,7 @@ qpn_start(void* arg)
mqueue_block mqb;
int actions;
qtime_mono_t now;
+ struct thread thread;
/* now in our thread, complete initialisation */
qpn_in_thread_init(qpn);
@@ -176,13 +157,8 @@ qpn_start(void* arg)
if (qpn->main_thread)
quagga_sigevent_process ();
- /* process timers */
- now = qt_get_monotonic();
- while (qtimer_pile_dispatch_next(qpn->pile, now))
- {
- }
-
- /* drain the message queue, will be waiting when it's empty */
+ /* drain the message queue, will be in waiting for signal state
+ * when it's empty */
for (;;)
{
mqb = mqueue_dequeue(qpn->queue, 1, qpn->mts) ;
@@ -193,6 +169,7 @@ qpn_start(void* arg)
}
/* block for some input, output, signal or timeout */
+ now = qt_get_monotonic();
actions = qps_pselect(qpn->selection,
qtimer_pile_top_time(qpn->pile, now + QTIME(MAX_PSELECT_TIMOUT)) );
@@ -201,43 +178,27 @@ qpn_start(void* arg)
actions = qps_dispatch_next(qpn->selection) ;
mqueue_done_waiting(qpn->queue, qpn->mts);
- }
- return NULL;
-}
-
-/* Bgp engine's qpthread, complete init, then run finite state machine
- * using legacy threads
-*/
-static void*
-qpn_start_bgp(void* arg)
-{
- qpn_nexus qpn = arg;
- struct thread thread;
- mqueue_block mqb;
-
- /* now in our thread, complete initialisation */
- qpn_in_thread_init(qpn);
-
- while (!qpn->terminate)
- {
- /* drain the message queue, will be waiting when it's empty */
- for (;;)
+ /* process timers */
+ now = qt_get_monotonic();
+ while (qtimer_pile_dispatch_next(qpn->pile, now))
{
- mqb = mqueue_dequeue(qpn->queue, 1, qpn->mts) ;
- if (mqb == NULL)
- break;
-
- mqb_dispatch(mqb, mqb_action);
}
- /* TODO: use qpselect stuff */
- if (thread_fetch (master, &thread))
- thread_call (&thread);
-
- mqueue_done_waiting(qpn->queue, qpn->mts);
+ /* legacy threads */
+ /* TODO: legacy threads must not pselect. How is the pselect above
+ * to know when to timeout for legacy timers? */
+ if (qpn->master != NULL)
+ {
+ if (thread_fetch (qpn->master, &thread))
+ thread_call (&thread);
+ }
}
+ /* last bit of code to run in this thread */
+ if (qpn->in_thread_final)
+ qpn->in_thread_final();
+
return NULL;
}
@@ -281,6 +242,10 @@ qpn_in_thread_init(qpn_nexus qpn)
qpn->mts = mqueue_thread_signal_init(qpn->mts, qpn->thread_id, SIGMQUEUE);
if (qpn->selection != NULL)
qps_set_signal(qpn->selection, SIGMQUEUE, newmask);
+
+ /* custom in-thread initialization */
+ if (qpn->in_thread_init != NULL)
+ qpn->in_thread_init();
}
/* Ask the thread to terminate itself quickly and cleanly */
diff --git a/lib/qpnexus.h b/lib/qpnexus.h
index 69fe8044..c717ed23 100644
--- a/lib/qpnexus.h
+++ b/lib/qpnexus.h
@@ -80,19 +80,28 @@ struct qpn_nexus
mqueue_queue queue;
mqueue_thread_signal mts;
- /* qpthread routine */
+ /* legacy threads */
+ struct thread_master *master;
+
+ /* qpthread routine, can override */
void* (*start)(void*);
+ /* in-thread initialize, can override. Called within the thread
+ * after all other initializion just before thread loop */
+ void (*in_thread_init)(void);
+
+ /* in-thread finalize, can override. Called within thread
+ * just before thread dies. Nexus components all exist but
+ * thread loop is no longer executed */
+ void (*in_thread_final)(void);
+
};
/*==============================================================================
* Functions
*/
-extern qpn_nexus qpn_init_new(qpn_nexus qtn);
-extern qpn_nexus qpn_init_main(qpn_nexus qtn);
-extern qpn_nexus qpn_init_bgp(qpn_nexus qtn);
-extern qpn_nexus qpn_init_routing(qpn_nexus qtn);
+extern qpn_nexus qpn_init_new(qpn_nexus qtn, int main_thread);
extern void qpn_exec(qpn_nexus qtn);
extern void qpn_terminate(qpn_nexus qpn);
extern qpn_nexus qpn_free(qpn_nexus qpn);
diff --git a/lib/vty.c b/lib/vty.c
index 27bab60a..4797f923 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -141,7 +141,7 @@ char integrate_default[] = SYSCONFDIR INTEGRATE_DEFAULT_CONFIG;
/* Master of the threads. */
static struct thread_master *master = NULL;
static qpn_nexus cli_nexus = NULL;
-static qpn_nexus bgp_nexus = NULL;
+static qpn_nexus routing_nexus = NULL;
/* VTY standard output function. vty == NULL or VTY_SHELL => stdout */
int
@@ -553,7 +553,7 @@ vty_command (struct vty *vty, char *buf)
#endif /* CONSUMED_TIME_CHECK */
UNLOCK
- ret = cmd_execute_command (vline, vty, NULL, bgp_nexus, 0);
+ ret = cmd_execute_command (vline, vty, NULL, routing_nexus, 0);
LOCK
/* Get the name of the protocol if any */
@@ -3644,10 +3644,10 @@ vty_set_lines(struct vty *vty, int lines)
/* qpthreads: Install vty's own commands like `who' command. */
void
-vty_init_r (qpn_nexus cli_n, qpn_nexus bgp_n)
+vty_init_r (qpn_nexus cli_n, qpn_nexus routing_n)
{
cli_nexus = cli_n;
- bgp_nexus = bgp_n;
+ routing_nexus = routing_n;
qpt_mutex_init(&vty_mutex, qpt_mutex_recursive);
}