diff options
Diffstat (limited to 'lib/command_queue.c')
-rw-r--r-- | lib/command_queue.c | 100 |
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) ; +} + |