Looks good, applied, thanks.
On Wed, Mar 06, 2013 at 07:49:14AM -0300, Thiago Padilha wrote:
> Here it is. My first patch contains a example shell script in case you
> want to add.
> ---
> cmd-wait-for.c | 81
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
> tmux.1 | 12 ++++++---
> 2 files changed, 85 insertions(+), 8 deletions(-)
> diff --git a/cmd-wait-for.c b/cmd-wait-for.c
> index 6313358..5ab10f9 100644
> --- a/cmd-wait-for.c
> +++ b/cmd-wait-for.c
> @@ -32,8 +32,8 @@ enum cmd_retval cmd_wait_for_exec(struct cmd *, struct
> cmd_q *);
>
> const struct cmd_entry cmd_wait_for_entry = {
> "wait-for", "wait",
> - "S", 1, 1,
> - "[-S] channel",
> + "LSU", 1, 1,
> + "[-L | -S | -U] channel",
> 0,
> NULL,
> NULL,
> @@ -42,7 +42,9 @@ const struct cmd_entry cmd_wait_for_entry = {
>
> struct wait_channel {
> const char *name;
> + int
> locked;
> TAILQ_HEAD(, cmd_q) waiters;
> + TAILQ_HEAD(, cmd_q) lockers;
>
> RB_ENTRY(wait_channel) entry;
> };
> @@ -63,6 +65,10 @@ enum cmd_retval cmd_wait_for_signal(struct cmd_q *,
> const char *,
> struct wait_channel *);
> enum cmd_retval cmd_wait_for_wait(struct cmd_q *, const char *,
> struct wait_channel *);
> +enum cmd_retval cmd_wait_for_lock(struct cmd_q *, const char *,
> + struct wait_channel *);
> +enum cmd_retval cmd_wait_for_unlock(struct cmd_q *, const char *,
> + struct wait_channel *);
>
> enum cmd_retval
> cmd_wait_for_exec(struct cmd *self, struct cmd_q *cmdq)
> @@ -76,6 +82,10 @@ cmd_wait_for_exec(struct cmd *self, struct cmd_q *cmdq)
>
> if (args_has(args, 'S'))
> return (cmd_wait_for_signal(cmdq, name, wc));
> + if (args_has(args, 'L'))
> + return (cmd_wait_for_lock(cmdq, name, wc));
> + if (args_has(args, 'U'))
> + return (cmd_wait_for_unlock(cmdq, name, wc));
> return (cmd_wait_for_wait(cmdq, name, wc));
> }
>
> @@ -95,9 +105,12 @@ cmd_wait_for_signal(struct cmd_q *cmdq, const char *name,
> if (!cmdq_free(wq))
> cmdq_continue(wq);
> }
> - RB_REMOVE(wait_channels, &wait_channels, wc);
> - free((void*) wc->name);
> - free(wc);
> +
> + if (!wc->locked) {
> + RB_REMOVE(wait_channels, &wait_channels, wc);
> + free((void*) wc->name);
> + free(wc);
> + }
>
> return (CMD_RETURN_NORMAL);
> }
> @@ -114,7 +127,9 @@ cmd_wait_for_wait(struct cmd_q *cmdq, const char *name,
> if (wc == NULL) {
> wc = xmalloc(sizeof *wc);
> wc->name = xstrdup(name);
> + wc->locked = 0;
> TAILQ_INIT(&wc->waiters);
> + TAILQ_INIT(&wc->lockers);
> RB_INSERT(wait_channels, &wait_channels, wc);
> }
> TAILQ_INSERT_TAIL(&wc->waiters, cmdq, waitentry);
> @@ -122,3 +137,59 @@ cmd_wait_for_wait(struct cmd_q *cmdq, const char *name,
>
> return (CMD_RETURN_WAIT);
> }
> +
> +enum cmd_retval
> +cmd_wait_for_lock(struct cmd_q *cmdq, const char *name,
> + struct wait_channel *wc)
> +{
> + if (cmdq->client == NULL || cmdq->client->session != NULL) {
> + cmdq_error(cmdq, "not able to lock");
> + return (CMD_RETURN_ERROR);
> + }
> +
> + if (wc == NULL) {
> + wc = xmalloc(sizeof *wc);
> + wc->name = xstrdup(name);
> + wc->locked = 0;
> + TAILQ_INIT(&wc->waiters);
> + TAILQ_INIT(&wc->lockers);
> + RB_INSERT(wait_channels, &wait_channels, wc);
> + }
> +
> + if (wc->locked) {
> + TAILQ_INSERT_TAIL(&wc->lockers, cmdq, waitentry);
> + cmdq->references++;
> + return (CMD_RETURN_WAIT);
> + }
> +
> + wc->locked = 1;
> + return (CMD_RETURN_NORMAL);
> +}
> +
> +enum cmd_retval
> +cmd_wait_for_unlock(struct cmd_q *cmdq, const char *name,
> + struct wait_channel *wc)
> +{
> + struct cmd_q *wq;
> +
> + if (wc == NULL || !wc->locked) {
> + cmdq_error(cmdq, "channel %s not locked", name);
> + return (CMD_RETURN_ERROR);
> + }
> +
> + if ((wq = TAILQ_FIRST(&wc->lockers)) != NULL) {
> + TAILQ_REMOVE(&wc->lockers, wq, waitentry);
> + if (!cmdq_free(wq))
> + cmdq_continue(wq);
> + } else {
> + wc->locked = 0;
> + if (TAILQ_EMPTY(&wc->waiters)) {
> + RB_REMOVE(wait_channels, &wait_channels, wc);
> + free((void*) wc->name);
> + free(wc);
> + }
> + }
> +
> + return (CMD_RETURN_NORMAL);
> +}
> +
> diff --git a/tmux.1 b/tmux.1
> index 8df7975..16eba8e 100644
> --- a/tmux.1
> +++ b/tmux.1
> @@ -3554,16 +3554,22 @@ If the command doesn't return success, the exit
> status is also displayed.
> .D1 (alias: Ic info )
> Show server information and terminal details.
> .It Xo Ic wait-for
> -.Fl S
> +.Fl LSU
> .Ar channel
> .Xc
> .D1 (alias: Ic wait )
> -When used without
> -.Fl S ,
> +When used without options,
> prevents the client from exiting until woken using
> .Ic wait-for
> .Fl S
> with the same channel.
> +When
> +.Ic wait-for
> +.Fl L
> +is used, the channel is locked and any clients that try to lock the same
> +channel will have to wait until the channel is unlocked with
> +.Ic wait-for
> +.Fl U .
> This command only works from outside
> .Nm .
> .El
> ------------------------------------------------------------------------------
> Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
> Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
> endpoint security space. For insight on selecting the right partner to
> tackle endpoint security challenges, access the full report.
> http://p.sf.net/sfu/symantec-dev2dev
> _______________________________________________
> tmux-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/tmux-users
------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
tmux-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-users