The branch, master has been updated via 293e331d69def60110bdc49b6453af905e0509b3 (commit) from 2a91025581ddaa934ffa471f5b27a33d19e4ea2d (commit)
- Log ----------------------------------------------------------------- commit 293e331d69def60110bdc49b6453af905e0509b3 Author: Nicholas Marriott <nicholas.marri...@gmail.com> Commit: Nicholas Marriott <nicholas.marri...@gmail.com> Add functions to allocate and free command contexts rather than doing it all on the stack. --- cfg.c | 35 +++++++++++++++++++---------------- cmd-command-prompt.c | 19 ++++++++++--------- cmd-confirm-before.c | 19 ++++++++++--------- cmd-if-shell.c | 20 +++++++------------- cmd-list.c | 5 +++-- cmd-run-shell.c | 22 ++++++++-------------- cmd.c | 46 +++++++++++++++++++++++++++++++++------------- control.c | 18 ++++++++++-------- key-bindings.c | 21 +++++++++++---------- server-client.c | 25 ++++++++++++++----------- tmux.h | 11 +++++++---- window-choose.c | 19 ++++++++++--------- 12 files changed, 142 insertions(+), 118 deletions(-) diff --git a/cfg.c b/cfg.c index c5c8c65..5592229 100644 --- a/cfg.c +++ b/cfg.c @@ -80,7 +80,7 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) char *buf, *copy, *line, *cause; size_t len, oldlen; struct cmd_list *cmdlist; - struct cmd_ctx ctx; + struct cmd_ctx *ctx; enum cmd_retval retval; if ((f = fopen(path, "rb")) == NULL) { @@ -90,6 +90,21 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) cfg_references++; + ctx = cmd_get_ctx(); + if (ctxin == NULL) { + ctx->msgdata = NULL; + ctx->curclient = NULL; + ctx->cmdclient = NULL; + } else { + ctx->msgdata = ctxin->msgdata; + ctx->curclient = ctxin->curclient; + ctx->cmdclient = ctxin->cmdclient; + } + + ctx->error = cfg_error; + ctx->print = cfg_print; + ctx->info = cfg_print; + n = 0; line = NULL; retval = CMD_RETURN_NORMAL; @@ -146,22 +161,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) if (cmdlist == NULL) continue; - if (ctxin == NULL) { - ctx.msgdata = NULL; - ctx.curclient = NULL; - ctx.cmdclient = NULL; - } else { - ctx.msgdata = ctxin->msgdata; - ctx.curclient = ctxin->curclient; - ctx.cmdclient = ctxin->cmdclient; - } - - ctx.error = cfg_error; - ctx.print = cfg_print; - ctx.info = cfg_print; - cfg_cause = NULL; - switch (cmd_list_exec(cmdlist, &ctx)) { + switch (cmd_list_exec(cmdlist, ctx)) { case CMD_RETURN_YIELD: if (retval != CMD_RETURN_ATTACH) retval = CMD_RETURN_YIELD; @@ -186,6 +187,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) } fclose(f); + cmd_free_ctx(ctx); + cfg_references--; return (retval); diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index ea38035..2a0e1aa 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -150,7 +150,7 @@ cmd_command_prompt_callback(void *data, const char *s) struct cmd_command_prompt_cdata *cdata = data; struct client *c = cdata->c; struct cmd_list *cmdlist; - struct cmd_ctx ctx; + struct cmd_ctx *ctx; char *cause, *new_template, *prompt, *ptr; char *input = NULL; @@ -184,17 +184,18 @@ cmd_command_prompt_callback(void *data, const char *s) return (0); } - ctx.msgdata = NULL; - ctx.curclient = c; + ctx = cmd_get_ctx(); + ctx->msgdata = NULL; + ctx->curclient = c; + ctx->cmdclient = NULL; - ctx.error = key_bindings_error; - ctx.print = key_bindings_print; - ctx.info = key_bindings_info; + ctx->error = key_bindings_error; + ctx->print = key_bindings_print; + ctx->info = key_bindings_info; - ctx.cmdclient = NULL; - - cmd_list_exec(cmdlist, &ctx); + cmd_list_exec(cmdlist, ctx); cmd_list_free(cmdlist); + cmd_free_ctx(ctx); if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback) return (1); diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c index 329027c..33733c3 100644 --- a/cmd-confirm-before.c +++ b/cmd-confirm-before.c @@ -108,7 +108,7 @@ cmd_confirm_before_callback(void *data, const char *s) struct cmd_confirm_before_data *cdata = data; struct client *c = cdata->c; struct cmd_list *cmdlist; - struct cmd_ctx ctx; + struct cmd_ctx *ctx; char *cause; if (s == NULL || *s == '\0') @@ -125,17 +125,18 @@ cmd_confirm_before_callback(void *data, const char *s) return (0); } - ctx.msgdata = NULL; - ctx.curclient = c; + ctx = cmd_get_ctx(); + ctx->msgdata = NULL; + ctx->curclient = c; + ctx->cmdclient = NULL; - ctx.error = key_bindings_error; - ctx.print = key_bindings_print; - ctx.info = key_bindings_info; + ctx->error = key_bindings_error; + ctx->print = key_bindings_print; + ctx->info = key_bindings_info; - ctx.cmdclient = NULL; - - cmd_list_exec(cmdlist, &ctx); + cmd_list_exec(cmdlist, ctx); cmd_list_free(cmdlist); + cmd_free_ctx(ctx); return (0); } diff --git a/cmd-if-shell.c b/cmd-if-shell.c index 636cf80..6f0b151 100644 --- a/cmd-if-shell.c +++ b/cmd-if-shell.c @@ -47,7 +47,7 @@ const struct cmd_entry cmd_if_shell_entry = { struct cmd_if_shell_data { char *cmd_if; char *cmd_else; - struct cmd_ctx ctx; + struct cmd_ctx *ctx; }; enum cmd_retval @@ -63,12 +63,9 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx) cdata->cmd_else = xstrdup(args->argv[2]); else cdata->cmd_else = NULL; - memcpy(&cdata->ctx, ctx, sizeof cdata->ctx); - if (ctx->cmdclient != NULL) - ctx->cmdclient->references++; - if (ctx->curclient != NULL) - ctx->curclient->references++; + cdata->ctx = ctx; + cmd_ref_ctx(ctx); job_run(shellcmd, cmd_if_shell_callback, cmd_if_shell_free, cdata); @@ -79,7 +76,7 @@ void cmd_if_shell_callback(struct job *job) { struct cmd_if_shell_data *cdata = job->data; - struct cmd_ctx *ctx = &cdata->ctx; + struct cmd_ctx *ctx = cdata->ctx; struct cmd_list *cmdlist; char *cause, *cmd; @@ -105,14 +102,11 @@ void cmd_if_shell_free(void *data) { struct cmd_if_shell_data *cdata = data; - struct cmd_ctx *ctx = &cdata->ctx; + struct cmd_ctx *ctx = cdata->ctx; - if (ctx->cmdclient != NULL) { - ctx->cmdclient->references--; + if (ctx->cmdclient != NULL) ctx->cmdclient->flags |= CLIENT_EXIT; - } - if (ctx->curclient != NULL) - ctx->curclient->references--; + cmd_free_ctx(ctx); free(cdata->cmd_else); free(cdata->cmd_if); diff --git a/cmd-list.c b/cmd-list.c index 1717ec3..6820d00 100644 --- a/cmd-list.c +++ b/cmd-list.c @@ -97,7 +97,7 @@ cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx) TAILQ_FOREACH(cmd, &cmdlist->list, qentry) { if (guards) ctx->print(ctx, "%%begin"); - n = cmd_exec(cmd, ctx); + n = cmd->entry->exec(cmd, ctx); if (guards) ctx->print(ctx, "%%end"); @@ -146,7 +146,8 @@ cmd_list_free(struct cmd_list *cmdlist) while (!TAILQ_EMPTY(&cmdlist->list)) { cmd = TAILQ_FIRST(&cmdlist->list); TAILQ_REMOVE(&cmdlist->list, cmd, qentry); - cmd_free(cmd); + args_free(cmd->args); + free(cmd); } free(cmdlist); } diff --git a/cmd-run-shell.c b/cmd-run-shell.c index 44e796d..03cbc29 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -47,7 +47,7 @@ const struct cmd_entry cmd_run_shell_entry = { struct cmd_run_shell_data { char *cmd; - struct cmd_ctx ctx; + struct cmd_ctx *ctx; u_int wp_id; }; @@ -55,7 +55,7 @@ void cmd_run_shell_print(struct job *job, const char *msg) { struct cmd_run_shell_data *cdata = job->data; - struct cmd_ctx *ctx = &cdata->ctx; + struct cmd_ctx *ctx = cdata->ctx; struct window_pane *wp; wp = window_pane_find_by_id(cdata->wp_id); @@ -84,12 +84,9 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx) cdata = xmalloc(sizeof *cdata); cdata->cmd = xstrdup(args->argv[0]); cdata->wp_id = wp->id; - memcpy(&cdata->ctx, ctx, sizeof cdata->ctx); - if (ctx->cmdclient != NULL) - ctx->cmdclient->references++; - if (ctx->curclient != NULL) - ctx->curclient->references++; + cdata->ctx = ctx; + cmd_ref_ctx(ctx); job_run(shellcmd, cmd_run_shell_callback, cmd_run_shell_free, cdata); @@ -100,7 +97,7 @@ void cmd_run_shell_callback(struct job *job) { struct cmd_run_shell_data *cdata = job->data; - struct cmd_ctx *ctx = &cdata->ctx; + struct cmd_ctx *ctx = cdata->ctx; char *cmd, *msg, *line; size_t size; int retcode; @@ -154,14 +151,11 @@ void cmd_run_shell_free(void *data) { struct cmd_run_shell_data *cdata = data; - struct cmd_ctx *ctx = &cdata->ctx; + struct cmd_ctx *ctx = cdata->ctx; - if (ctx->cmdclient != NULL) { - ctx->cmdclient->references--; + if (ctx->cmdclient != NULL) ctx->cmdclient->flags |= CLIENT_EXIT; - } - if (ctx->curclient != NULL) - ctx->curclient->references--; + cmd_free_ctx(ctx); free(cdata->cmd); free(cdata); diff --git a/cmd.c b/cmd.c index 52c1a30..23e86cf 100644 --- a/cmd.c +++ b/cmd.c @@ -132,6 +132,39 @@ struct winlink *cmd_find_window_offset(const char *, struct session *, int *); int cmd_find_index_offset(const char *, struct session *, int *); struct window_pane *cmd_find_pane_offset(const char *, struct winlink *); +struct cmd_ctx * +cmd_get_ctx(void) +{ + struct cmd_ctx *ctx; + + ctx = xcalloc(1, sizeof *ctx); + ctx->references = 0; + + cmd_ref_ctx(ctx); + return (ctx); +} + +void +cmd_free_ctx(struct cmd_ctx *ctx) +{ + if (ctx->cmdclient != NULL) + ctx->cmdclient->references--; + if (ctx->curclient != NULL) + ctx->curclient->references--; + if (--ctx->references == 0) + free(ctx); +} + +void +cmd_ref_ctx(struct cmd_ctx *ctx) +{ + ctx->references++; + if (ctx->cmdclient != NULL) + ctx->cmdclient->references++; + if (ctx->curclient != NULL) + ctx->curclient->references++; +} + int cmd_pack_argv(int argc, char **argv, char *buf, size_t len) { @@ -281,19 +314,6 @@ usage: return (NULL); } -enum cmd_retval -cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx) -{ - return (cmd->entry->exec(cmd, ctx)); -} - -void -cmd_free(struct cmd *cmd) -{ - args_free(cmd->args); - free(cmd); -} - size_t cmd_print(struct cmd *cmd, char *buf, size_t len) { diff --git a/control.c b/control.c index b5ec6bd..f00f57f 100644 --- a/control.c +++ b/control.c @@ -93,7 +93,7 @@ void control_callback(struct client *c, int closed, unused void *data) { char *line, *cause; - struct cmd_ctx ctx; + struct cmd_ctx *ctx; struct cmd_list *cmdlist; if (closed) @@ -108,22 +108,24 @@ control_callback(struct client *c, int closed, unused void *data) break; } - ctx.msgdata = NULL; - ctx.cmdclient = NULL; - ctx.curclient = c; + ctx = cmd_get_ctx(); + ctx->msgdata = NULL; + ctx->cmdclient = NULL; + ctx->curclient = c; - ctx.error = control_msg_error; - ctx.print = control_msg_print; - ctx.info = control_msg_info; + ctx->error = control_msg_error; + ctx->print = control_msg_print; + ctx->info = control_msg_info; if (cmd_string_parse(line, &cmdlist, &cause) != 0) { control_write(c, "%%error in line \"%s\": %s", line, cause); free(cause); } else { - cmd_list_exec(cmdlist, &ctx); + cmd_list_exec(cmdlist, ctx); cmd_list_free(cmdlist); } + cmd_free_ctx(ctx); free(line); } diff --git a/key-bindings.c b/key-bindings.c index cf5237d..a25d370 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -262,18 +262,18 @@ key_bindings_info(struct cmd_ctx *ctx, const char *fmt, ...) void key_bindings_dispatch(struct key_binding *bd, struct client *c) { - struct cmd_ctx ctx; + struct cmd_ctx *ctx; struct cmd *cmd; int readonly; - ctx.msgdata = NULL; - ctx.curclient = c; + ctx = cmd_get_ctx(); + ctx->msgdata = NULL; + ctx->cmdclient = NULL; + ctx->curclient = c; - ctx.error = key_bindings_error; - ctx.print = key_bindings_print; - ctx.info = key_bindings_info; - - ctx.cmdclient = NULL; + ctx->error = key_bindings_error; + ctx->print = key_bindings_print; + ctx->info = key_bindings_info; readonly = 1; TAILQ_FOREACH(cmd, &bd->cmdlist->list, qentry) { @@ -281,9 +281,10 @@ key_bindings_dispatch(struct key_binding *bd, struct client *c) readonly = 0; } if (!readonly && c->flags & CLIENT_READONLY) { - key_bindings_info(&ctx, "Client is read-only"); + key_bindings_info(ctx, "client is read-only"); return; } - cmd_list_exec(bd->cmdlist, &ctx); + cmd_list_exec(bd->cmdlist, ctx); + cmd_free_ctx(ctx); } diff --git a/server-client.c b/server-client.c index d4449a5..1500419 100644 --- a/server-client.c +++ b/server-client.c @@ -864,24 +864,24 @@ server_client_msg_info(struct cmd_ctx *ctx, const char *fmt, ...) void server_client_msg_command(struct client *c, struct msg_command_data *data) { - struct cmd_ctx ctx; + struct cmd_ctx *ctx; struct cmd_list *cmdlist = NULL; int argc; char **argv, *cause; - ctx.error = server_client_msg_error; - ctx.print = server_client_msg_print; - ctx.info = server_client_msg_info; + ctx = cmd_get_ctx(); + ctx->msgdata = data; + ctx->curclient = NULL; + ctx->cmdclient = c; - ctx.msgdata = data; - ctx.curclient = NULL; - - ctx.cmdclient = c; + ctx->error = server_client_msg_error; + ctx->print = server_client_msg_print; + ctx->info = server_client_msg_info; argc = data->argc; data->argv[(sizeof data->argv) - 1] = '\0'; if (cmd_unpack_argv(data->argv, sizeof data->argv, argc, &argv) != 0) { - server_client_msg_error(&ctx, "command too long"); + server_client_msg_error(ctx, "command too long"); goto error; } @@ -892,13 +892,13 @@ server_client_msg_command(struct client *c, struct msg_command_data *data) } if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) { - server_client_msg_error(&ctx, "%s", cause); + server_client_msg_error(ctx, "%s", cause); cmd_free_argv(argc, argv); goto error; } cmd_free_argv(argc, argv); - switch (cmd_list_exec(cmdlist, &ctx)) + switch (cmd_list_exec(cmdlist, ctx)) { case CMD_RETURN_ERROR: case CMD_RETURN_NORMAL: @@ -909,11 +909,14 @@ server_client_msg_command(struct client *c, struct msg_command_data *data) break; } cmd_list_free(cmdlist); + cmd_free_ctx(ctx); return; error: if (cmdlist != NULL) cmd_list_free(cmdlist); + cmd_free_ctx(ctx); + c->flags |= CLIENT_EXIT; } diff --git a/tmux.h b/tmux.h index d602b14..df47cdb 100644 --- a/tmux.h +++ b/tmux.h @@ -1362,8 +1362,10 @@ struct cmd_ctx { * cmdclient and curclient may both be NULL if the command is in the * configuration file. */ - struct client *curclient; - struct client *cmdclient; + struct client *curclient; + struct client *cmdclient; + + int references; struct msg_command_data *msgdata; @@ -1710,13 +1712,14 @@ long long args_strtonum( struct args *, u_char, long long, long long, char **); /* cmd.c */ +struct cmd_ctx *cmd_get_ctx(void); +void cmd_free_ctx(struct cmd_ctx *); +void cmd_ref_ctx(struct cmd_ctx *); int cmd_pack_argv(int, char **, char *, size_t); int cmd_unpack_argv(char *, size_t, int, char ***); char **cmd_copy_argv(int, char *const *); void cmd_free_argv(int, char **); struct cmd *cmd_parse(int, char **, char **); -enum cmd_retval cmd_exec(struct cmd *, struct cmd_ctx *); -void cmd_free(struct cmd *); size_t cmd_print(struct cmd *, char *, size_t); struct session *cmd_current_session(struct cmd_ctx *, int); struct client *cmd_current_client(struct cmd_ctx *); diff --git a/window-choose.c b/window-choose.c index d37527d..e48db7e 100644 --- a/window-choose.c +++ b/window-choose.c @@ -200,7 +200,7 @@ window_choose_data_free(struct window_choose_data *wcd) void window_choose_data_run(struct window_choose_data *cdata) { - struct cmd_ctx ctx; + struct cmd_ctx *ctx; struct cmd_list *cmdlist; char *cause; @@ -220,17 +220,18 @@ window_choose_data_run(struct window_choose_data *cdata) return; } - ctx.msgdata = NULL; - ctx.curclient = cdata->start_client; + ctx = cmd_get_ctx(); + ctx->msgdata = NULL; + ctx->curclient = cdata->start_client; + ctx->cmdclient = NULL; - ctx.error = key_bindings_error; - ctx.print = key_bindings_print; - ctx.info = key_bindings_info; + ctx->error = key_bindings_error; + ctx->print = key_bindings_print; + ctx->info = key_bindings_info; - ctx.cmdclient = NULL; - - cmd_list_exec(cmdlist, &ctx); + cmd_list_exec(cmdlist, ctx); cmd_list_free(cmdlist); + cmd_free_ctx(ctx); } void ----------------------------------------------------------------------- Summary of changes: cfg.c | 35 +++++++++++++++++++---------------- cmd-command-prompt.c | 19 ++++++++++--------- cmd-confirm-before.c | 19 ++++++++++--------- cmd-if-shell.c | 20 +++++++------------- cmd-list.c | 5 +++-- cmd-run-shell.c | 22 ++++++++-------------- cmd.c | 46 +++++++++++++++++++++++++++++++++------------- control.c | 18 ++++++++++-------- key-bindings.c | 21 +++++++++++---------- server-client.c | 25 ++++++++++++++----------- tmux.h | 11 +++++++---- window-choose.c | 19 ++++++++++--------- 12 files changed, 142 insertions(+), 118 deletions(-) hooks/post-receive -- tmux ------------------------------------------------------------------------------ The Go Parallel Website, sponsored by Intel - in partnership with Geeknet, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials, tech docs, whitepapers, evaluation guides, and opinion stories. Check out the most recent posts - join the conversation now. http://goparallel.sourceforge.net/ _______________________________________________ tmux-cvs mailing list tmux-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-cvs