Re: [PATCH] Add wait-for signaling to commands that create new panes

2014-08-24 Thread Nathaniel W Filardo
On Mon, Aug 11, 2014 at 11:19:19PM +0100, Nicholas Marriott wrote:
> Hi
> 
> Can't you just run "mycommand; tmux wait -S foo" in the pane?

That's not robust against the shell's process group or tmux itself being
fatally signaled, which would kill both the "mycommand" process and prevent
the shell from executing the "wait -S" command.  The propsed patch is robust
to the first case because the pane will close and to the second because the
server will (implicitly) close the socket and the running "tmux wait" will
exit.

Cheers,
--nwf;
 
> On Thu, Aug 07, 2014 at 04:15:15PM -0400, Nathaniel W Filardo wrote:
> > On Thu, Aug 07, 2014 at 09:05:01PM +0100, Nicholas Marriott wrote:
> > > Hi
> > > 
> > > What is this useful for?
> > 
> > My use case is that I want to run half a dozen or so jobs via runit and I
> > wanted them to share a tmux session for easy administrative access rather
> > than each spawning their own.  But I need some way to wait for the
> > individual task running on a given pane to exit.
> > 
> > > This seems like a job for hooks if they are ever finished.
> > 
> > What are "hooks" in this context?
> > 
> > Thanks,
> > --nwf;
> > 
> > > On Mon, Aug 04, 2014 at 01:59:26PM -0400, Nathaniel W Filardo wrote:
> > > > Greetings list,
> > > > 
> > > > The attached patch adds options to new-window, new-session, and 
> > > > split-window
> > > > (commands which create panes) to signal a wait_channel when that pane is
> > > > destroyed, for example after the contained process exits.  Towards this 
> > > > end,
> > > > it changes the life-cycle management code in cmd-wait-for.c to allow
> > > > external holds on a wait_channel structure; these are only taken, at the
> > > > moment, by the aforementioned commands.
> > > > 
> > > > It's something of an afternoon hack-job, so it might not be ideal.
> > > > Comments and criticisms welcome; rotten tomatoes possibly understood but
> > > > less welcome. ;)
> > > > 
> > > > Cheers!
> > > > --nwf;
> > > 
> > > > diff --git a/cmd-new-session.c b/cmd-new-session.c
> > > > index b36de70..4cf72fc 100644
> > > > --- a/cmd-new-session.c
> > > > +++ b/cmd-new-session.c
> > > > @@ -38,7 +38,7 @@ const struct cmd_entry cmd_new_session_entry = {
> > > > "Ac:dDF:n:Ps:t:x:y:", 0, -1,
> > > > "[-AdDP] [-c start-directory] [-F format] [-n window-name] "
> > > > "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
> > > > -   "[-y height] [command]",
> > > > +   "[-y height] [-W channel] [command]",
> > > > CMD_STARTSERVER|CMD_CANTNEST,
> > > > NULL,
> > > > cmd_new_session_exec
> > > > @@ -61,6 +61,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q 
> > > > *cmdq)
> > > > u_intsx, sy;
> > > > struct format_tree  *ft;
> > > > struct environ_entry*envent;
> > > > +   struct wait_channel *wc = NULL;
> > > >  
> > > > if (args_has(args, 't') && (args->argc != 0 || args_has(args, 
> > > > 'n'))) {
> > > > cmdq_error(cmdq, "command or window name given with 
> > > > target");
> > > > @@ -214,10 +215,13 @@ cmd_new_session_exec(struct cmd *self, struct 
> > > > cmd_q *cmdq)
> > > > if (c != NULL)
> > > > environ_update(update, &c->environ, &env);
> > > >  
> > > > +   if (args_has(args, 'W'))
> > > > +   wc = wait_channel_hold_by_name(args_get(args,'W'));
> > > > +
> > > > /* Create the new session. */
> > > > idx = -1 - options_get_number(&global_s_options, "base-index");
> > > > s = session_create(newname, argc, argv, path, cwd, &env, tiop, 
> > > > idx, sx,
> > > > -   sy, &cause);
> > > > +   sy, wc, &cause);
> > > > if (s == NULL) {
> > > > cmdq_error(cmdq, "create session failed: %s", cause);
> > > > free(cause);
> > > > diff --git a/cmd-new-window.c b/cmd-new-window.c
> > > > index cd0042e..d5987e8 100644
> > > > --- a/cmd-new-window.c
> > > > +++ b/cmd-new-window.c
> > > > @@ -34,8 +34,8 @@ enum cmd_retval   cmd_new_window_exec(struct cmd 
> > > > *, struct cmd_q *);
> > > >  
> > > >  const struct cmd_entry cmd_new_window_entry = {
> > > > "new-window", "neww",
> > > > -   "ac:dF:kn:Pt:", 0, -1,
> > > > -   "[-adkP] [-c start-directory] [-F format] [-n window-name] "
> > > > +   "ac:dF:kn:Pt:W:", 0, -1,
> > > > +   "[-adkP] [-c start-directory] [-F format] [-n window-name] [-W 
> > > > channel]"
> > > > CMD_TARGET_WINDOW_USAGE " [command]",
> > > > 0,
> > > > NULL,
> > > > @@ -54,6 +54,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q 
> > > > *cmdq)
> > > > int  argc, idx, last, detached, cwd, fd = 
> > > > -1;
> > > > struct format_tree  *ft;
> > > > struct environ_entry*envent;
> > > > +   struct wait_channel *wc = NULL;
> > > >  
> > > > if (args_has(args, 'a')) {
> > > > 

Re: [PATCH] Add wait-for signaling to commands that create new panes

2014-08-11 Thread Nicholas Marriott
You could use trap in the shell to protect against the first case, and
I'm not convinced the new flag is useful enough beyond this very
specific case.

The second is a known issue which could and should be fixed as a
separate change regardless of whether not we add any new flags.

There have been plans for a long time to add hooks so that you could run
whatever commands you like when a pane closed, but the original patch
had some design issues and so far we haven't had time to finish it.


On Mon, Aug 11, 2014 at 06:36:14PM -0400, Nathaniel W Filardo wrote:
> On Mon, Aug 11, 2014 at 11:19:19PM +0100, Nicholas Marriott wrote:
> > Hi
> > 
> > Can't you just run "mycommand; tmux wait -S foo" in the pane?
> 
> That's not robust against the shell's process group or tmux itself being
> fatally signaled, which would kill both the "mycommand" process and prevent
> the shell from executing the "wait -S" command.  The propsed patch is robust
> to the first case because the pane will close and to the second because the
> server will (implicitly) close the socket and the running "tmux wait" will
> exit.
> 
> Cheers,
> --nwf;
>  
> > On Thu, Aug 07, 2014 at 04:15:15PM -0400, Nathaniel W Filardo wrote:
> > > On Thu, Aug 07, 2014 at 09:05:01PM +0100, Nicholas Marriott wrote:
> > > > Hi
> > > > 
> > > > What is this useful for?
> > > 
> > > My use case is that I want to run half a dozen or so jobs via runit and I
> > > wanted them to share a tmux session for easy administrative access rather
> > > than each spawning their own.  But I need some way to wait for the
> > > individual task running on a given pane to exit.
> > > 
> > > > This seems like a job for hooks if they are ever finished.
> > > 
> > > What are "hooks" in this context?
> > > 
> > > Thanks,
> > > --nwf;
> > > 
> > > > On Mon, Aug 04, 2014 at 01:59:26PM -0400, Nathaniel W Filardo wrote:
> > > > > Greetings list,
> > > > > 
> > > > > The attached patch adds options to new-window, new-session, and 
> > > > > split-window
> > > > > (commands which create panes) to signal a wait_channel when that pane 
> > > > > is
> > > > > destroyed, for example after the contained process exits.  Towards 
> > > > > this end,
> > > > > it changes the life-cycle management code in cmd-wait-for.c to allow
> > > > > external holds on a wait_channel structure; these are only taken, at 
> > > > > the
> > > > > moment, by the aforementioned commands.
> > > > > 
> > > > > It's something of an afternoon hack-job, so it might not be ideal.
> > > > > Comments and criticisms welcome; rotten tomatoes possibly understood 
> > > > > but
> > > > > less welcome. ;)
> > > > > 
> > > > > Cheers!
> > > > > --nwf;
> > > > 
> > > > > diff --git a/cmd-new-session.c b/cmd-new-session.c
> > > > > index b36de70..4cf72fc 100644
> > > > > --- a/cmd-new-session.c
> > > > > +++ b/cmd-new-session.c
> > > > > @@ -38,7 +38,7 @@ const struct cmd_entry cmd_new_session_entry = {
> > > > >   "Ac:dDF:n:Ps:t:x:y:", 0, -1,
> > > > >   "[-AdDP] [-c start-directory] [-F format] [-n window-name] "
> > > > >   "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
> > > > > - "[-y height] [command]",
> > > > > + "[-y height] [-W channel] [command]",
> > > > >   CMD_STARTSERVER|CMD_CANTNEST,
> > > > >   NULL,
> > > > >   cmd_new_session_exec
> > > > > @@ -61,6 +61,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q 
> > > > > *cmdq)
> > > > >   u_intsx, sy;
> > > > >   struct format_tree  *ft;
> > > > >   struct environ_entry*envent;
> > > > > + struct wait_channel *wc = NULL;
> > > > >  
> > > > >   if (args_has(args, 't') && (args->argc != 0 || args_has(args, 
> > > > > 'n'))) {
> > > > >   cmdq_error(cmdq, "command or window name given with 
> > > > > target");
> > > > > @@ -214,10 +215,13 @@ cmd_new_session_exec(struct cmd *self, struct 
> > > > > cmd_q *cmdq)
> > > > >   if (c != NULL)
> > > > >   environ_update(update, &c->environ, &env);
> > > > >  
> > > > > + if (args_has(args, 'W'))
> > > > > + wc = wait_channel_hold_by_name(args_get(args,'W'));
> > > > > +
> > > > >   /* Create the new session. */
> > > > >   idx = -1 - options_get_number(&global_s_options, "base-index");
> > > > >   s = session_create(newname, argc, argv, path, cwd, &env, tiop, 
> > > > > idx, sx,
> > > > > - sy, &cause);
> > > > > + sy, wc, &cause);
> > > > >   if (s == NULL) {
> > > > >   cmdq_error(cmdq, "create session failed: %s", cause);
> > > > >   free(cause);
> > > > > diff --git a/cmd-new-window.c b/cmd-new-window.c
> > > > > index cd0042e..d5987e8 100644
> > > > > --- a/cmd-new-window.c
> > > > > +++ b/cmd-new-window.c
> > > > > @@ -34,8 +34,8 @@ enum cmd_retval cmd_new_window_exec(struct cmd 
> > > > > *, struct cmd_q *);
> > > > >  
> > > > >  const struct cmd_entry cmd_new_window_entry = {
> > > > >   "new-window", "neww",
> > > > 

Re: [PATCH] Add wait-for signaling to commands that create new panes

2014-08-11 Thread Nicholas Marriott
Hi

Can't you just run "mycommand; tmux wait -S foo" in the pane?



On Thu, Aug 07, 2014 at 04:15:15PM -0400, Nathaniel W Filardo wrote:
> On Thu, Aug 07, 2014 at 09:05:01PM +0100, Nicholas Marriott wrote:
> > Hi
> > 
> > What is this useful for?
> 
> My use case is that I want to run half a dozen or so jobs via runit and I
> wanted them to share a tmux session for easy administrative access rather
> than each spawning their own.  But I need some way to wait for the
> individual task running on a given pane to exit.
> 
> > This seems like a job for hooks if they are ever finished.
> 
> What are "hooks" in this context?
> 
> Thanks,
> --nwf;
> 
> > On Mon, Aug 04, 2014 at 01:59:26PM -0400, Nathaniel W Filardo wrote:
> > > Greetings list,
> > > 
> > > The attached patch adds options to new-window, new-session, and 
> > > split-window
> > > (commands which create panes) to signal a wait_channel when that pane is
> > > destroyed, for example after the contained process exits.  Towards this 
> > > end,
> > > it changes the life-cycle management code in cmd-wait-for.c to allow
> > > external holds on a wait_channel structure; these are only taken, at the
> > > moment, by the aforementioned commands.
> > > 
> > > It's something of an afternoon hack-job, so it might not be ideal.
> > > Comments and criticisms welcome; rotten tomatoes possibly understood but
> > > less welcome. ;)
> > > 
> > > Cheers!
> > > --nwf;
> > 
> > > diff --git a/cmd-new-session.c b/cmd-new-session.c
> > > index b36de70..4cf72fc 100644
> > > --- a/cmd-new-session.c
> > > +++ b/cmd-new-session.c
> > > @@ -38,7 +38,7 @@ const struct cmd_entry cmd_new_session_entry = {
> > >   "Ac:dDF:n:Ps:t:x:y:", 0, -1,
> > >   "[-AdDP] [-c start-directory] [-F format] [-n window-name] "
> > >   "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
> > > - "[-y height] [command]",
> > > + "[-y height] [-W channel] [command]",
> > >   CMD_STARTSERVER|CMD_CANTNEST,
> > >   NULL,
> > >   cmd_new_session_exec
> > > @@ -61,6 +61,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q 
> > > *cmdq)
> > >   u_intsx, sy;
> > >   struct format_tree  *ft;
> > >   struct environ_entry*envent;
> > > + struct wait_channel *wc = NULL;
> > >  
> > >   if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) {
> > >   cmdq_error(cmdq, "command or window name given with target");
> > > @@ -214,10 +215,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q 
> > > *cmdq)
> > >   if (c != NULL)
> > >   environ_update(update, &c->environ, &env);
> > >  
> > > + if (args_has(args, 'W'))
> > > + wc = wait_channel_hold_by_name(args_get(args,'W'));
> > > +
> > >   /* Create the new session. */
> > >   idx = -1 - options_get_number(&global_s_options, "base-index");
> > >   s = session_create(newname, argc, argv, path, cwd, &env, tiop, idx, sx,
> > > - sy, &cause);
> > > + sy, wc, &cause);
> > >   if (s == NULL) {
> > >   cmdq_error(cmdq, "create session failed: %s", cause);
> > >   free(cause);
> > > diff --git a/cmd-new-window.c b/cmd-new-window.c
> > > index cd0042e..d5987e8 100644
> > > --- a/cmd-new-window.c
> > > +++ b/cmd-new-window.c
> > > @@ -34,8 +34,8 @@ enum cmd_retval cmd_new_window_exec(struct cmd *, 
> > > struct cmd_q *);
> > >  
> > >  const struct cmd_entry cmd_new_window_entry = {
> > >   "new-window", "neww",
> > > - "ac:dF:kn:Pt:", 0, -1,
> > > - "[-adkP] [-c start-directory] [-F format] [-n window-name] "
> > > + "ac:dF:kn:Pt:W:", 0, -1,
> > > + "[-adkP] [-c start-directory] [-F format] [-n window-name] [-W channel]"
> > >   CMD_TARGET_WINDOW_USAGE " [command]",
> > >   0,
> > >   NULL,
> > > @@ -54,6 +54,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q 
> > > *cmdq)
> > >   int  argc, idx, last, detached, cwd, fd = -1;
> > >   struct format_tree  *ft;
> > >   struct environ_entry*envent;
> > > + struct wait_channel *wc = NULL;
> > >  
> > >   if (args_has(args, 'a')) {
> > >   wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
> > > @@ -152,10 +153,13 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q 
> > > *cmdq)
> > >   }
> > >   }
> > >  
> > > + if (args_has(args, 'W'))
> > > + wc = wait_channel_hold_by_name(args_get(args, 'W'));
> > > +
> > >   if (idx == -1)
> > >   idx = -1 - options_get_number(&s->options, "base-index");
> > >   wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
> > > - &cause);
> > > + wc, &cause);
> > >   if (wl == NULL) {
> > >   cmdq_error(cmdq, "create window failed: %s", cause);
> > >   free(cause);
> > > diff --git a/cmd-split-window.c b/cmd-split-window.c
> > > index ea047a3..9a4fc15 100644
> > > --- a/cmd-split-window.c
> > > +++ b/cmd-split-window.c
> > > @@ -37,6 +37,7 @@ const struct cmd_entry cmd_split_window_entry = {
> > >   "split-window", "splitw",
> > >   "c:dF:l:hp:Pt:v", 0, -1,
> > >   "[-dhvP] [-c 

Re: [PATCH] Add wait-for signaling to commands that create new panes

2014-08-08 Thread Nathaniel W Filardo
On Mon, Aug 04, 2014 at 10:59:21PM +0100, Thomas Adam wrote:
>[useful feedback]

Here's take 2; it should (unless I goofed) incorporate all your feedback.
Thanks!
--nwf;
diff --git a/cmd-new-session.c b/cmd-new-session.c
index b36de70..d23fea1 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -35,10 +35,10 @@ enum cmd_retval  cmd_new_session_exec(struct cmd *, 
struct cmd_q *);
 
 const struct cmd_entry cmd_new_session_entry = {
"new-session", "new",
-   "Ac:dDF:n:Ps:t:x:y:", 0, -1,
+   "Ac:dDF:n:Ps:t:W:x:y:", 0, -1,
"[-AdDP] [-c start-directory] [-F format] [-n window-name] "
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
-   "[-y height] [command]",
+   "[-y height] [-W channel] [command]",
CMD_STARTSERVER|CMD_CANTNEST,
NULL,
cmd_new_session_exec
@@ -61,6 +61,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
u_intsx, sy;
struct format_tree  *ft;
struct environ_entry*envent;
+   struct wait_channel *wc = NULL;
 
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) {
cmdq_error(cmdq, "command or window name given with target");
@@ -214,10 +215,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (c != NULL)
environ_update(update, &c->environ, &env);
 
+   if (args_has(args, 'W'))
+   wc = wait_channel_hold_by_name(args_get(args,'W'));
+
/* Create the new session. */
idx = -1 - options_get_number(&global_s_options, "base-index");
s = session_create(newname, argc, argv, path, cwd, &env, tiop, idx, sx,
-   sy, &cause);
+   sy, wc, &cause);
if (s == NULL) {
cmdq_error(cmdq, "create session failed: %s", cause);
free(cause);
diff --git a/cmd-new-window.c b/cmd-new-window.c
index cd0042e..d5987e8 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -34,8 +34,8 @@ enum cmd_retval   cmd_new_window_exec(struct cmd *, 
struct cmd_q *);
 
 const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww",
-   "ac:dF:kn:Pt:", 0, -1,
-   "[-adkP] [-c start-directory] [-F format] [-n window-name] "
+   "ac:dF:kn:Pt:W:", 0, -1,
+   "[-adkP] [-c start-directory] [-F format] [-n window-name] [-W channel]"
CMD_TARGET_WINDOW_USAGE " [command]",
0,
NULL,
@@ -54,6 +54,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
int  argc, idx, last, detached, cwd, fd = -1;
struct format_tree  *ft;
struct environ_entry*envent;
+   struct wait_channel *wc = NULL;
 
if (args_has(args, 'a')) {
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
@@ -152,10 +153,13 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
}
 
+   if (args_has(args, 'W'))
+   wc = wait_channel_hold_by_name(args_get(args, 'W'));
+
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
-   &cause);
+   wc, &cause);
if (wl == NULL) {
cmdq_error(cmdq, "create window failed: %s", cause);
free(cause);
diff --git a/cmd-split-window.c b/cmd-split-window.c
index ea047a3..ec7ddc7 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -35,8 +35,9 @@ enum cmd_retvalcmd_split_window_exec(struct cmd *, 
struct cmd_q *);
 
 const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw",
-   "c:dF:l:hp:Pt:v", 0, -1,
+   "c:dF:l:hp:Pt:vW:", 0, -1,
"[-dhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
+   "[-W channel] "
CMD_TARGET_PANE_USAGE " [command]",
0,
cmd_split_window_key_binding,
@@ -158,6 +159,10 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
new_wp = window_add_pane(w, hlimit);
 
+   if (args_has(args, 'W'))
+   new_wp->signal_on_destroy =
+   wait_channel_hold_by_name(args_get(args, 'W'));
+
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
diff --git a/cmd-wait-for.c b/cmd-wait-for.c
index e251863..01c6208 100644
--- a/cmd-wait-for.c
+++ b/cmd-wait-for.c
@@ -43,6 +43,7 @@ struct wait_channel {
const char *name;
int locked;
 
+   u_int   holds;
TAILQ_HEAD(, cmd_q) waiters;
TAILQ_HEAD(, cmd_q) lockers;
 
@@ -70,6 +71,69 @@ enum cmd_retval  cmd_wait_for_lock(struct cmd_q *, const 
char *,
 enum cmd_retvalcmd_wait_for_unlock(struct cmd_q *, const char *,
struct wait_channel *);
 

Re: [PATCH] Add wait-for signaling to commands that create new panes

2014-08-08 Thread Nathaniel W Filardo
On Thu, Aug 07, 2014 at 09:05:01PM +0100, Nicholas Marriott wrote:
> Hi
> 
> What is this useful for?

My use case is that I want to run half a dozen or so jobs via runit and I
wanted them to share a tmux session for easy administrative access rather
than each spawning their own.  But I need some way to wait for the
individual task running on a given pane to exit.

> This seems like a job for hooks if they are ever finished.

What are "hooks" in this context?

Thanks,
--nwf;

> On Mon, Aug 04, 2014 at 01:59:26PM -0400, Nathaniel W Filardo wrote:
> > Greetings list,
> > 
> > The attached patch adds options to new-window, new-session, and split-window
> > (commands which create panes) to signal a wait_channel when that pane is
> > destroyed, for example after the contained process exits.  Towards this end,
> > it changes the life-cycle management code in cmd-wait-for.c to allow
> > external holds on a wait_channel structure; these are only taken, at the
> > moment, by the aforementioned commands.
> > 
> > It's something of an afternoon hack-job, so it might not be ideal.
> > Comments and criticisms welcome; rotten tomatoes possibly understood but
> > less welcome. ;)
> > 
> > Cheers!
> > --nwf;
> 
> > diff --git a/cmd-new-session.c b/cmd-new-session.c
> > index b36de70..4cf72fc 100644
> > --- a/cmd-new-session.c
> > +++ b/cmd-new-session.c
> > @@ -38,7 +38,7 @@ const struct cmd_entry cmd_new_session_entry = {
> > "Ac:dDF:n:Ps:t:x:y:", 0, -1,
> > "[-AdDP] [-c start-directory] [-F format] [-n window-name] "
> > "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
> > -   "[-y height] [command]",
> > +   "[-y height] [-W channel] [command]",
> > CMD_STARTSERVER|CMD_CANTNEST,
> > NULL,
> > cmd_new_session_exec
> > @@ -61,6 +61,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
> > u_intsx, sy;
> > struct format_tree  *ft;
> > struct environ_entry*envent;
> > +   struct wait_channel *wc = NULL;
> >  
> > if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) {
> > cmdq_error(cmdq, "command or window name given with target");
> > @@ -214,10 +215,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q 
> > *cmdq)
> > if (c != NULL)
> > environ_update(update, &c->environ, &env);
> >  
> > +   if (args_has(args, 'W'))
> > +   wc = wait_channel_hold_by_name(args_get(args,'W'));
> > +
> > /* Create the new session. */
> > idx = -1 - options_get_number(&global_s_options, "base-index");
> > s = session_create(newname, argc, argv, path, cwd, &env, tiop, idx, sx,
> > -   sy, &cause);
> > +   sy, wc, &cause);
> > if (s == NULL) {
> > cmdq_error(cmdq, "create session failed: %s", cause);
> > free(cause);
> > diff --git a/cmd-new-window.c b/cmd-new-window.c
> > index cd0042e..d5987e8 100644
> > --- a/cmd-new-window.c
> > +++ b/cmd-new-window.c
> > @@ -34,8 +34,8 @@ enum cmd_retval   cmd_new_window_exec(struct cmd *, 
> > struct cmd_q *);
> >  
> >  const struct cmd_entry cmd_new_window_entry = {
> > "new-window", "neww",
> > -   "ac:dF:kn:Pt:", 0, -1,
> > -   "[-adkP] [-c start-directory] [-F format] [-n window-name] "
> > +   "ac:dF:kn:Pt:W:", 0, -1,
> > +   "[-adkP] [-c start-directory] [-F format] [-n window-name] [-W channel]"
> > CMD_TARGET_WINDOW_USAGE " [command]",
> > 0,
> > NULL,
> > @@ -54,6 +54,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
> > int  argc, idx, last, detached, cwd, fd = -1;
> > struct format_tree  *ft;
> > struct environ_entry*envent;
> > +   struct wait_channel *wc = NULL;
> >  
> > if (args_has(args, 'a')) {
> > wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
> > @@ -152,10 +153,13 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q 
> > *cmdq)
> > }
> > }
> >  
> > +   if (args_has(args, 'W'))
> > +   wc = wait_channel_hold_by_name(args_get(args, 'W'));
> > +
> > if (idx == -1)
> > idx = -1 - options_get_number(&s->options, "base-index");
> > wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
> > -   &cause);
> > +   wc, &cause);
> > if (wl == NULL) {
> > cmdq_error(cmdq, "create window failed: %s", cause);
> > free(cause);
> > diff --git a/cmd-split-window.c b/cmd-split-window.c
> > index ea047a3..9a4fc15 100644
> > --- a/cmd-split-window.c
> > +++ b/cmd-split-window.c
> > @@ -37,6 +37,7 @@ const struct cmd_entry cmd_split_window_entry = {
> > "split-window", "splitw",
> > "c:dF:l:hp:Pt:v", 0, -1,
> > "[-dhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
> > +   "[-W channel] "
> > CMD_TARGET_PANE_USAGE " [command]",
> > 0,
> > cmd_split_window_key_binding,
> > @@ -158,6 +159,10 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q 
> > *cmdq)
> > }
> > new_wp = win

Re: [PATCH] Add wait-for signaling to commands that create new panes

2014-08-07 Thread Nicholas Marriott
Hi

What is this useful for?

This seems like a job for hooks if they are ever finished.


On Mon, Aug 04, 2014 at 01:59:26PM -0400, Nathaniel W Filardo wrote:
> Greetings list,
> 
> The attached patch adds options to new-window, new-session, and split-window
> (commands which create panes) to signal a wait_channel when that pane is
> destroyed, for example after the contained process exits.  Towards this end,
> it changes the life-cycle management code in cmd-wait-for.c to allow
> external holds on a wait_channel structure; these are only taken, at the
> moment, by the aforementioned commands.
> 
> It's something of an afternoon hack-job, so it might not be ideal.
> Comments and criticisms welcome; rotten tomatoes possibly understood but
> less welcome. ;)
> 
> Cheers!
> --nwf;

> diff --git a/cmd-new-session.c b/cmd-new-session.c
> index b36de70..4cf72fc 100644
> --- a/cmd-new-session.c
> +++ b/cmd-new-session.c
> @@ -38,7 +38,7 @@ const struct cmd_entry cmd_new_session_entry = {
>   "Ac:dDF:n:Ps:t:x:y:", 0, -1,
>   "[-AdDP] [-c start-directory] [-F format] [-n window-name] "
>   "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
> - "[-y height] [command]",
> + "[-y height] [-W channel] [command]",
>   CMD_STARTSERVER|CMD_CANTNEST,
>   NULL,
>   cmd_new_session_exec
> @@ -61,6 +61,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
>   u_intsx, sy;
>   struct format_tree  *ft;
>   struct environ_entry*envent;
> + struct wait_channel *wc = NULL;
>  
>   if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) {
>   cmdq_error(cmdq, "command or window name given with target");
> @@ -214,10 +215,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q 
> *cmdq)
>   if (c != NULL)
>   environ_update(update, &c->environ, &env);
>  
> + if (args_has(args, 'W'))
> + wc = wait_channel_hold_by_name(args_get(args,'W'));
> +
>   /* Create the new session. */
>   idx = -1 - options_get_number(&global_s_options, "base-index");
>   s = session_create(newname, argc, argv, path, cwd, &env, tiop, idx, sx,
> - sy, &cause);
> + sy, wc, &cause);
>   if (s == NULL) {
>   cmdq_error(cmdq, "create session failed: %s", cause);
>   free(cause);
> diff --git a/cmd-new-window.c b/cmd-new-window.c
> index cd0042e..d5987e8 100644
> --- a/cmd-new-window.c
> +++ b/cmd-new-window.c
> @@ -34,8 +34,8 @@ enum cmd_retval cmd_new_window_exec(struct cmd *, 
> struct cmd_q *);
>  
>  const struct cmd_entry cmd_new_window_entry = {
>   "new-window", "neww",
> - "ac:dF:kn:Pt:", 0, -1,
> - "[-adkP] [-c start-directory] [-F format] [-n window-name] "
> + "ac:dF:kn:Pt:W:", 0, -1,
> + "[-adkP] [-c start-directory] [-F format] [-n window-name] [-W channel]"
>   CMD_TARGET_WINDOW_USAGE " [command]",
>   0,
>   NULL,
> @@ -54,6 +54,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
>   int  argc, idx, last, detached, cwd, fd = -1;
>   struct format_tree  *ft;
>   struct environ_entry*envent;
> + struct wait_channel *wc = NULL;
>  
>   if (args_has(args, 'a')) {
>   wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
> @@ -152,10 +153,13 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q 
> *cmdq)
>   }
>   }
>  
> + if (args_has(args, 'W'))
> + wc = wait_channel_hold_by_name(args_get(args, 'W'));
> +
>   if (idx == -1)
>   idx = -1 - options_get_number(&s->options, "base-index");
>   wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
> - &cause);
> + wc, &cause);
>   if (wl == NULL) {
>   cmdq_error(cmdq, "create window failed: %s", cause);
>   free(cause);
> diff --git a/cmd-split-window.c b/cmd-split-window.c
> index ea047a3..9a4fc15 100644
> --- a/cmd-split-window.c
> +++ b/cmd-split-window.c
> @@ -37,6 +37,7 @@ const struct cmd_entry cmd_split_window_entry = {
>   "split-window", "splitw",
>   "c:dF:l:hp:Pt:v", 0, -1,
>   "[-dhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
> + "[-W channel] "
>   CMD_TARGET_PANE_USAGE " [command]",
>   0,
>   cmd_split_window_key_binding,
> @@ -158,6 +159,10 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q 
> *cmdq)
>   }
>   new_wp = window_add_pane(w, hlimit);
>  
> + if (args_has(args, 'W'))
> + new_wp->signal_on_destroy =
> + wait_channel_hold_by_name(args_get(args, 'W'));
> +
>   path = NULL;
>   if (cmdq->client != NULL && cmdq->client->session == NULL)
>   envent = environ_find(&cmdq->client->environ, "PATH");
> diff --git a/cmd-wait-for.c b/cmd-wait-for.c
> index e251863..f0dd92b 100644
> --- a/cmd-wait-for.c
> +++ b/cmd-wait-for.c
> @@ -43,6 +43,7 @@ 

Re: [PATCH] Add wait-for signaling to commands that create new panes

2014-08-04 Thread Thomas Adam
On Mon, Aug 04, 2014 at 01:59:26PM -0400, Nathaniel W Filardo wrote:
> Greetings list,
> 
> The attached patch adds options to new-window, new-session, and split-window
> (commands which create panes) to signal a wait_channel when that pane is
> destroyed, for example after the contained process exits.  Towards this end,
> it changes the life-cycle management code in cmd-wait-for.c to allow
> external holds on a wait_channel structure; these are only taken, at the
> moment, by the aforementioned commands.
> 
> It's something of an afternoon hack-job, so it might not be ideal.
> Comments and criticisms welcome; rotten tomatoes possibly understood but
> less welcome. ;)
> 
> Cheers!
> --nwf;

> diff --git a/cmd-new-session.c b/cmd-new-session.c
> index b36de70..4cf72fc 100644
> --- a/cmd-new-session.c
> +++ b/cmd-new-session.c
> @@ -38,7 +38,7 @@ const struct cmd_entry cmd_new_session_entry = {
>   "Ac:dDF:n:Ps:t:x:y:", 0, -1,

No "W" needed here?  This seems wrong.

>   "[-AdDP] [-c start-directory] [-F format] [-n window-name] "
>   "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
> - "[-y height] [command]",
> + "[-y height] [-W channel] [command]",
>   CMD_STARTSERVER|CMD_CANTNEST,
>   NULL,
>   cmd_new_session_exec
> @@ -61,6 +61,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
>   u_intsx, sy;
>   struct format_tree  *ft;
>   struct environ_entry*envent;
> + struct wait_channel *wc = NULL;

Missing tab character between type and variable.

[...]

> +static struct wait_channel *
> +wait_channel_find_by_name(const char *name) {
> + struct wait_channel wc0;
> +
> + wc0.name = name;
> + return RB_FIND(wait_channels, &wait_channels, &wc0);

You need to cast name here to (char *), as RB_FIND doesn't accept const
char * pointers.

> +}
> +
> +static struct wait_channel *
> +wait_channel_alloc(const char *name) {
> + struct wait_channel *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);
> +
> + return wc;

return (wc);

> +
> +static void
> +wait_channel_try_free(struct wait_channel *wc) {
> + if (wc->holds > 0)
> + return;
> +
> + if (!TAILQ_EMPTY(&wc->waiters))
> + return;
> +
> + if (!TAILQ_EMPTY(&wc->lockers)) {
> + /* Should we assert that wc->locked == 1 ? */

Why?

> + return;
> + }
> +
> + /* All references to this wait_channel are gone */
> + RB_REMOVE(wait_channels, &wait_channels, wc);
> + free((void*) wc->name);

No need to cast this.

> + free(wc);
> +}
> +
> +static void
> +wait_channel_hold(struct wait_channel *wc) {
> + wc->holds++;
> +}
> +
> +struct wait_channel *
> +wait_channel_hold_by_name(const char *name) {
> + struct wait_channel *wc = wait_channel_find_by_name(name);
> +
> + if(!wc)

if (wc != NULL)

> + wc = wait_channel_alloc(name);

Suggest you call this wait_channel_new();

> +
> + wait_channel_hold(wc);
> +
> + return wc;

return (wc);

> +.Fl W
> +option specifies a channel name which will be signaled when the created pane
> +is destroyed.  Clients may use the

New sentences begin on a new line, please.

-- Thomas Adam

-- 
"Deep in my heart I wish I was wrong.  But deep in my heart I know I am
not." -- Morrissey ("Girl Least Likely To" -- off of Viva Hate.)

--
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls. 
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk
___
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users


[PATCH] Add wait-for signaling to commands that create new panes

2014-08-04 Thread Nathaniel W Filardo
Greetings list,

The attached patch adds options to new-window, new-session, and split-window
(commands which create panes) to signal a wait_channel when that pane is
destroyed, for example after the contained process exits.  Towards this end,
it changes the life-cycle management code in cmd-wait-for.c to allow
external holds on a wait_channel structure; these are only taken, at the
moment, by the aforementioned commands.

It's something of an afternoon hack-job, so it might not be ideal.
Comments and criticisms welcome; rotten tomatoes possibly understood but
less welcome. ;)

Cheers!
--nwf;
diff --git a/cmd-new-session.c b/cmd-new-session.c
index b36de70..4cf72fc 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -38,7 +38,7 @@ const struct cmd_entry cmd_new_session_entry = {
"Ac:dDF:n:Ps:t:x:y:", 0, -1,
"[-AdDP] [-c start-directory] [-F format] [-n window-name] "
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
-   "[-y height] [command]",
+   "[-y height] [-W channel] [command]",
CMD_STARTSERVER|CMD_CANTNEST,
NULL,
cmd_new_session_exec
@@ -61,6 +61,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
u_intsx, sy;
struct format_tree  *ft;
struct environ_entry*envent;
+   struct wait_channel *wc = NULL;
 
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) {
cmdq_error(cmdq, "command or window name given with target");
@@ -214,10 +215,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (c != NULL)
environ_update(update, &c->environ, &env);
 
+   if (args_has(args, 'W'))
+   wc = wait_channel_hold_by_name(args_get(args,'W'));
+
/* Create the new session. */
idx = -1 - options_get_number(&global_s_options, "base-index");
s = session_create(newname, argc, argv, path, cwd, &env, tiop, idx, sx,
-   sy, &cause);
+   sy, wc, &cause);
if (s == NULL) {
cmdq_error(cmdq, "create session failed: %s", cause);
free(cause);
diff --git a/cmd-new-window.c b/cmd-new-window.c
index cd0042e..d5987e8 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -34,8 +34,8 @@ enum cmd_retval   cmd_new_window_exec(struct cmd *, 
struct cmd_q *);
 
 const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww",
-   "ac:dF:kn:Pt:", 0, -1,
-   "[-adkP] [-c start-directory] [-F format] [-n window-name] "
+   "ac:dF:kn:Pt:W:", 0, -1,
+   "[-adkP] [-c start-directory] [-F format] [-n window-name] [-W channel]"
CMD_TARGET_WINDOW_USAGE " [command]",
0,
NULL,
@@ -54,6 +54,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
int  argc, idx, last, detached, cwd, fd = -1;
struct format_tree  *ft;
struct environ_entry*envent;
+   struct wait_channel *wc = NULL;
 
if (args_has(args, 'a')) {
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
@@ -152,10 +153,13 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
}
 
+   if (args_has(args, 'W'))
+   wc = wait_channel_hold_by_name(args_get(args, 'W'));
+
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
-   &cause);
+   wc, &cause);
if (wl == NULL) {
cmdq_error(cmdq, "create window failed: %s", cause);
free(cause);
diff --git a/cmd-split-window.c b/cmd-split-window.c
index ea047a3..9a4fc15 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -37,6 +37,7 @@ const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw",
"c:dF:l:hp:Pt:v", 0, -1,
"[-dhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
+   "[-W channel] "
CMD_TARGET_PANE_USAGE " [command]",
0,
cmd_split_window_key_binding,
@@ -158,6 +159,10 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
new_wp = window_add_pane(w, hlimit);
 
+   if (args_has(args, 'W'))
+   new_wp->signal_on_destroy =
+   wait_channel_hold_by_name(args_get(args, 'W'));
+
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
diff --git a/cmd-wait-for.c b/cmd-wait-for.c
index e251863..f0dd92b 100644
--- a/cmd-wait-for.c
+++ b/cmd-wait-for.c
@@ -43,6 +43,7 @@ struct wait_channel {
const char *name;
int locked;
 
+   u_int   holds;
TAILQ_HEAD(, cmd_q) waiters;
TAILQ_HEAD(, cmd_q) lockers;
 
@@ -70,6 +71,70 @@ enum cmd_retval  cmd_w