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')) {
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, 

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 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 =
   + 

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,
 - 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;
   

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

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 @@ struct wait_channel {
   const char *name;
   int locked;
  
 + u_int   holds;
   TAILQ_HEAD(, cmd_q) waiters;
   

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=153845071iu=/4140/ostg.clktrk
___
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users