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
> tmux-users@lists.sourceforge.net
> 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
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to