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