summaryrefslogtreecommitdiffstats
path: root/lib/command_queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/command_queue.c')
-rw-r--r--lib/command_queue.c100
1 files changed, 44 insertions, 56 deletions
diff --git a/lib/command_queue.c b/lib/command_queue.c
index b6aab580..ea8ac469 100644
--- a/lib/command_queue.c
+++ b/lib/command_queue.c
@@ -25,6 +25,10 @@
#include "qpnexus.h"
#include "memory.h"
#include "command_queue.h"
+#include "vty.h"
+#include "uty.h"
+#include "vector.h"
+#include "qstring.h"
/*------------------------------------------------------------------------------
* Form of message passed with command to be executed
@@ -32,17 +36,7 @@
struct cq_command_args
{
- qpn_nexus ret_nexus ;
-
- struct cmd_element *cmd ;
-
- enum node_type cnode ; /* vty->node before execution */
- enum node_type onode ; /* vty->node before "do" */
-
- short int do_shortcut ; /* true => is "do" command */
-
- short int argc ; /* count of arguments */
- short int ret ; /* return code */
+ enum cmd_return_code ret ; /* return code from command */
} ;
MQB_ARGS_SIZE_OK(cq_command_args) ;
@@ -56,28 +50,16 @@ static void cq_return(mqueue_block mqb, mqb_flag_t flag);
* Enqueue vty and argv[] for execution in given nexus.
*/
void
-cq_enqueue(struct vty *vty, struct cmd_parsed* parsed, qpn_nexus to_nexus,
- qpn_nexus from_nexus)
+cq_enqueue(struct vty *vty, qpn_nexus dst)
{
- int i;
struct cq_command_args* args ;
mqueue_block mqb = mqb_init_new(NULL, cq_action, vty) ;
args = mqb_get_args(mqb) ;
- args->cmd = parsed->cmd ;
- args->cnode = parsed->cnode ;
- args->onode = parsed->onode ;
- args->do_shortcut = parsed->do_shortcut ;
- args->argc = parsed->argc ;
-
- args->ret_nexus = from_nexus ;
- args->ret = CMD_SUCCESS ;
-
- for (i = 0; i < parsed->argc; ++i)
- mqb_push_argv_p(mqb, XSTRDUP(MTYPE_MARSHAL, parsed->argv[i]));
+ args->ret = CMD_QUEUED ;
- mqueue_enqueue(to_nexus->queue, mqb, 0) ;
+ mqueue_enqueue(dst->queue, mqb, 0) ;
}
/*------------------------------------------------------------------------------
@@ -85,6 +67,8 @@ cq_enqueue(struct vty *vty, struct cmd_parsed* parsed, qpn_nexus to_nexus,
*
* When done (or revoked/deleted) return the message, so that the sender knows
* that the command has been dealt with (one way or another).
+ *
+ * Note that if the command is revoked the return is set to CMD_QUEUED.
*/
static void
cq_action(mqueue_block mqb, mqb_flag_t flag)
@@ -97,59 +81,63 @@ cq_action(mqueue_block mqb, mqb_flag_t flag)
if (flag == mqb_action)
{
- const char** argv = mqb_get_argv(mqb) ;
-
- args->ret = (args->cmd->func)(args->cmd, vty, args->argc, argv) ;
+ args->ret = cmd_dispatch_call(vty) ;
+ assert(args->ret != CMD_QUEUED) ; /* avoid confusion ! */
}
else
args->ret = CMD_QUEUED ;
mqb_set_action(mqb, cq_return) ;
- mqueue_enqueue(args->ret_nexus->queue, mqb, 0) ;
+ mqueue_enqueue(vty_cli_nexus->queue, mqb, 0) ;
} ;
/*------------------------------------------------------------------------------
- * Accept return from command executed in another thread.
+ * Accept return from command which has completed.
*
* The command line processing for the vty may be stalled (with read mode
* disabled) waiting for the return from the command.
*
- * If the message is being revoked/deleted the state of the vty is still
- * updated (to show that the command has completed) BUT nothing is kicked.
- * It is up to the revoke/delete function to deal with any possibility of the
- * vty remaining stalled.
+ * Do not care whether the message is being revoked or not... the command
+ * has completed and that must be signalled to the CLI. Any pending output
+ * is released.
+ *
+ * The command itself may have been revoked before it was executed. That
+ * makes no difference either... the output buffers will simply be empty.
+ * However, the return code is CMD_QUEUED, to signal the fact that the command
+ * was never executed.
*/
static void
cq_return(mqueue_block mqb, mqb_flag_t flag)
{
struct vty *vty ;
struct cq_command_args* args ;
- int i ;
- void** argv ;
- struct cmd_parsed parsed ;
vty = mqb_get_arg0(mqb) ;
args = mqb_get_args(mqb) ;
- /* clean up */
- argv = mqb_get_argv(mqb) ;
-
- for (i = 0; i < args->argc; ++i)
- XFREE(MTYPE_MARSHAL, argv[i]);
-
- /* signal end of command -- passing the action state */
- parsed.cmd = args->cmd ;
- parsed.cnode = args->cnode ;
- parsed.onode = args->onode ;
- parsed.do_shortcut = args->do_shortcut ;
- parsed.argc = 0 ;
- cmd_post_command(vty, &parsed, args->ret, (flag == mqb_action)) ;
+ /* signal end of command */
+ cmd_post_command(vty, args->ret) ;
+ vty_queued_result(vty, args->ret) ;
- /* update the state of the vty -- passing the "action" state */
- vty_queued_result(vty, args->ret, (flag == mqb_action));
-
- if (qpthreads_enabled)
- qpt_thread_signal(vty_cli_nexus->thread_id, SIGMQUEUE);
+//if (qpthreads_enabled)
+// qpt_thread_signal(vty_cli_nexus->thread_id, SIGMQUEUE);
mqb_free(mqb);
}
+
+/*------------------------------------------------------------------------------
+ * Revoke any messages related to the given VTY
+ *
+ * Revokes in vty_cmd_nexus -- so before command is started
+ * and in vty_cli_nexus -- so after command has completed
+ *
+ * Can do nothing about any command actually being executed in the
+ * vty_cmd_nexus.
+ */
+void
+cq_revoke(struct vty *vty)
+{
+ mqueue_revoke(vty_cmd_nexus->queue, vty) ;
+ mqueue_revoke(vty_cli_nexus->queue, vty) ;
+}
+