[BACK]Return to cmd-wait-for.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Diff for /src/usr.bin/tmux/cmd-wait-for.c between version 1.7 and 1.8

version 1.7, 2014/10/20 22:29:25 version 1.8, 2015/09/04 12:02:44
Line 41 
Line 41 
 struct wait_channel {  struct wait_channel {
         const char             *name;          const char             *name;
         int                     locked;          int                     locked;
           int                     woken;
   
         TAILQ_HEAD(, cmd_q)     waiters;          TAILQ_HEAD(, cmd_q)     waiters;
         TAILQ_HEAD(, cmd_q)     lockers;          TAILQ_HEAD(, cmd_q)     lockers;
Line 69 
Line 70 
 enum cmd_retval cmd_wait_for_unlock(struct cmd_q *, const char *,  enum cmd_retval cmd_wait_for_unlock(struct cmd_q *, const char *,
                     struct wait_channel *);                      struct wait_channel *);
   
   struct wait_channel     *cmd_wait_for_add(const char *);
   void                     cmd_wait_for_remove(struct wait_channel *wc);
   
   struct wait_channel *
   cmd_wait_for_add(const char *name)
   {
           struct wait_channel *wc;
   
           wc = xmalloc(sizeof *wc);
           wc->name = xstrdup(name);
   
           wc->locked = 0;
           wc->woken = 0;
   
           TAILQ_INIT(&wc->waiters);
           TAILQ_INIT(&wc->lockers);
   
           RB_INSERT(wait_channels, &wait_channels, wc);
   
           log_debug("add wait channel %s", wc->name);
   
           return (wc);
   }
   
   void
   cmd_wait_for_remove(struct wait_channel *wc)
   {
   
           if (wc->locked)
                   return;
           if (!TAILQ_EMPTY(&wc->waiters) || !wc->woken)
                   return;
   
           log_debug("remove wait channel %s", wc->name);
   
           RB_REMOVE(wait_channels, &wait_channels, wc);
   
           free((void *)wc->name);
           free(wc);
   }
   
 enum cmd_retval  enum cmd_retval
 cmd_wait_for_exec(struct cmd *self, struct cmd_q *cmdq)  cmd_wait_for_exec(struct cmd *self, unused struct cmd_q *cmdq)
 {  {
         struct args             *args = self->args;          struct args             *args = self->args;
         const char              *name = args->argv[0];          const char              *name = args->argv[0];
Line 89 
Line 131 
 }  }
   
 enum cmd_retval  enum cmd_retval
 cmd_wait_for_signal(struct cmd_q *cmdq, const char *name,  cmd_wait_for_signal(unused struct cmd_q *cmdq, const char *name,
     struct wait_channel *wc)      struct wait_channel *wc)
 {  {
         struct cmd_q    *wq, *wq1;          struct cmd_q    *wq, *wq1;
   
         if (wc == NULL || TAILQ_EMPTY(&wc->waiters)) {          if (wc == NULL)
                 cmdq_error(cmdq, "no waiting clients on %s", name);                  wc = cmd_wait_for_add(name);
                 return (CMD_RETURN_ERROR);  
           if (TAILQ_EMPTY(&wc->waiters) && !wc->woken) {
                   log_debug("signal wait channel %s, no waiters", wc->name);
                   wc->woken = 1;
                   return (CMD_RETURN_NORMAL);
         }          }
           log_debug("signal wait channel %s, with waiters", wc->name);
   
         TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) {          TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) {
                 TAILQ_REMOVE(&wc->waiters, wq, waitentry);                  TAILQ_REMOVE(&wc->waiters, wq, waitentry);
Line 105 
Line 152 
                         cmdq_continue(wq);                          cmdq_continue(wq);
         }          }
   
         if (!wc->locked) {          cmd_wait_for_remove(wc);
                 RB_REMOVE(wait_channels, &wait_channels, wc);  
                 free((void *)wc->name);  
                 free(wc);  
         }  
   
         return (CMD_RETURN_NORMAL);          return (CMD_RETURN_NORMAL);
 }  }
   
Line 118 
Line 160 
 cmd_wait_for_wait(struct cmd_q *cmdq, const char *name,  cmd_wait_for_wait(struct cmd_q *cmdq, const char *name,
     struct wait_channel *wc)      struct wait_channel *wc)
 {  {
         if (cmdq->client == NULL || cmdq->client->session != NULL) {          struct client   *c = cmdq->client;
   
           if (c == NULL || c->session != NULL) {
                 cmdq_error(cmdq, "not able to wait");                  cmdq_error(cmdq, "not able to wait");
                 return (CMD_RETURN_ERROR);                  return (CMD_RETURN_ERROR);
         }          }
   
         if (wc == NULL) {          if (wc == NULL)
                 wc = xmalloc(sizeof *wc);                  wc = cmd_wait_for_add(name);
                 wc->name = xstrdup(name);  
                 wc->locked = 0;          if (wc->woken) {
                 TAILQ_INIT(&wc->waiters);                  log_debug("wait channel %s already woken (client %d)", wc->name,
                 TAILQ_INIT(&wc->lockers);                      c->tty.fd);
                 RB_INSERT(wait_channels, &wait_channels, wc);                  cmd_wait_for_remove(wc);
                   return (CMD_RETURN_NORMAL);
         }          }
           log_debug("wait channel %s not woken (client %d)", wc->name, c->tty.fd);
   
         TAILQ_INSERT_TAIL(&wc->waiters, cmdq, waitentry);          TAILQ_INSERT_TAIL(&wc->waiters, cmdq, waitentry);
         cmdq->references++;          cmdq->references++;
Line 147 
Line 193 
                 return (CMD_RETURN_ERROR);                  return (CMD_RETURN_ERROR);
         }          }
   
         if (wc == NULL) {          if (wc == NULL)
                 wc = xmalloc(sizeof *wc);                  wc = cmd_wait_for_add(name);
                 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) {          if (wc->locked) {
                 TAILQ_INSERT_TAIL(&wc->lockers, cmdq, waitentry);                  TAILQ_INSERT_TAIL(&wc->lockers, cmdq, waitentry);
Line 183 
Line 223 
                         cmdq_continue(wq);                          cmdq_continue(wq);
         } else {          } else {
                 wc->locked = 0;                  wc->locked = 0;
                 if (TAILQ_EMPTY(&wc->waiters)) {                  cmd_wait_for_remove(wc);
                         RB_REMOVE(wait_channels, &wait_channels, wc);  
                         free((void *)wc->name);  
                         free(wc);  
                 }  
         }          }
   
         return (CMD_RETURN_NORMAL);          return (CMD_RETURN_NORMAL);
Line 210 
Line 246 
                         if (!cmdq_free(wq))                          if (!cmdq_free(wq))
                                 cmdq_continue(wq);                                  cmdq_continue(wq);
                 }                  }
                 RB_REMOVE(wait_channels, &wait_channels, wc);                  wc->locked = 0;
                 free((void *)wc->name);                  cmd_wait_for_remove(wc);
                 free(wc);  
         }          }
 }  }

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8