diff options
author | Thomas Adam <thomas@xteddy.org> | 2016-10-16 20:01:10 +0100 |
---|---|---|
committer | Thomas Adam <thomas@xteddy.org> | 2016-10-16 20:01:10 +0100 |
commit | c67b7025882ee6bc2b3d5112dbc630c191f1fa2a (patch) | |
tree | 4c36124e376eac0235accd523be6545ccdccf6af /cmd-wait-for.c | |
parent | 3d8efdf310f475a6b9ed83814182c966de2bdab3 (diff) | |
parent | ddc4512d2e0eda6c705e002cb5dbf80719d709e1 (diff) | |
download | rtmux-c67b7025882ee6bc2b3d5112dbc630c191f1fa2a.tar.gz rtmux-c67b7025882ee6bc2b3d5112dbc630c191f1fa2a.tar.bz2 rtmux-c67b7025882ee6bc2b3d5112dbc630c191f1fa2a.zip |
Merge branch 'obsd-master'
Diffstat (limited to 'cmd-wait-for.c')
-rw-r--r-- | cmd-wait-for.c | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/cmd-wait-for.c b/cmd-wait-for.c index fb2fb699..505e4d63 100644 --- a/cmd-wait-for.c +++ b/cmd-wait-for.c @@ -41,13 +41,18 @@ const struct cmd_entry cmd_wait_for_entry = { .exec = cmd_wait_for_exec }; +struct wait_item { + struct cmd_q *cmdq; + TAILQ_ENTRY(wait_item) entry; +}; + struct wait_channel { const char *name; int locked; int woken; - TAILQ_HEAD(, cmd_q) waiters; - TAILQ_HEAD(, cmd_q) lockers; + TAILQ_HEAD(, wait_item) waiters; + TAILQ_HEAD(, wait_item) lockers; RB_ENTRY(wait_channel) entry; }; @@ -135,7 +140,7 @@ static enum cmd_retval cmd_wait_for_signal(__unused struct cmd_q *cmdq, const char *name, struct wait_channel *wc) { - struct cmd_q *wq, *wq1; + struct wait_item *wi, *wi1; if (wc == NULL) wc = cmd_wait_for_add(name); @@ -147,10 +152,11 @@ cmd_wait_for_signal(__unused struct cmd_q *cmdq, const char *name, } log_debug("signal wait channel %s, with waiters", wc->name); - TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) { - TAILQ_REMOVE(&wc->waiters, wq, waitentry); - if (!cmdq_free(wq)) - cmdq_continue(wq); + TAILQ_FOREACH_SAFE(wi, &wc->waiters, entry, wi1) { + wi->cmdq->flags &= ~CMD_Q_WAITING; + + TAILQ_REMOVE(&wc->waiters, wi, entry); + free(wi); } cmd_wait_for_remove(wc); @@ -158,10 +164,10 @@ cmd_wait_for_signal(__unused struct cmd_q *cmdq, const char *name, } static enum cmd_retval -cmd_wait_for_wait(struct cmd_q *cmdq, const char *name, - struct wait_channel *wc) +cmd_wait_for_wait(struct cmd_q *cmdq, const char *name, struct wait_channel *wc) { - struct client *c = cmdq->client; + struct client *c = cmdq->client; + struct wait_item *wi; if (c == NULL || c->session != NULL) { cmdq_error(cmdq, "not able to wait"); @@ -178,16 +184,18 @@ cmd_wait_for_wait(struct cmd_q *cmdq, const char *name, } log_debug("wait channel %s not woken (%p)", wc->name, c); - TAILQ_INSERT_TAIL(&wc->waiters, cmdq, waitentry); - cmdq->references++; + wi = xcalloc(1, sizeof *wi); + wi->cmdq = cmdq; + TAILQ_INSERT_TAIL(&wc->waiters, wi, entry); return (CMD_RETURN_WAIT); } static enum cmd_retval -cmd_wait_for_lock(struct cmd_q *cmdq, const char *name, - struct wait_channel *wc) +cmd_wait_for_lock(struct cmd_q *cmdq, const char *name, struct wait_channel *wc) { + struct wait_item *wi; + if (cmdq->client == NULL || cmdq->client->session != NULL) { cmdq_error(cmdq, "not able to lock"); return (CMD_RETURN_ERROR); @@ -197,8 +205,9 @@ cmd_wait_for_lock(struct cmd_q *cmdq, const char *name, wc = cmd_wait_for_add(name); if (wc->locked) { - TAILQ_INSERT_TAIL(&wc->lockers, cmdq, waitentry); - cmdq->references++; + wi = xcalloc(1, sizeof *wi); + wi->cmdq = cmdq; + TAILQ_INSERT_TAIL(&wc->lockers, wi, entry); return (CMD_RETURN_WAIT); } wc->locked = 1; @@ -210,17 +219,17 @@ static enum cmd_retval cmd_wait_for_unlock(struct cmd_q *cmdq, const char *name, struct wait_channel *wc) { - struct cmd_q *wq; + struct wait_item *wi; 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); + if ((wi = TAILQ_FIRST(&wc->lockers)) != NULL) { + wi->cmdq->flags &= ~CMD_Q_WAITING; + TAILQ_REMOVE(&wc->lockers, wi, entry); + free(wi); } else { wc->locked = 0; cmd_wait_for_remove(wc); @@ -233,19 +242,19 @@ void cmd_wait_for_flush(void) { struct wait_channel *wc, *wc1; - struct cmd_q *wq, *wq1; + struct wait_item *wi, *wi1; RB_FOREACH_SAFE(wc, wait_channels, &wait_channels, wc1) { - TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) { - TAILQ_REMOVE(&wc->waiters, wq, waitentry); - if (!cmdq_free(wq)) - cmdq_continue(wq); + TAILQ_FOREACH_SAFE(wi, &wc->waiters, entry, wi1) { + wi->cmdq->flags &= ~CMD_Q_WAITING; + TAILQ_REMOVE(&wc->waiters, wi, entry); + free(wi); } wc->woken = 1; - TAILQ_FOREACH_SAFE(wq, &wc->lockers, waitentry, wq1) { - TAILQ_REMOVE(&wc->lockers, wq, waitentry); - if (!cmdq_free(wq)) - cmdq_continue(wq); + TAILQ_FOREACH_SAFE(wi, &wc->lockers, entry, wi1) { + wi->cmdq->flags &= ~CMD_Q_WAITING; + TAILQ_REMOVE(&wc->lockers, wi, entry); + free(wi); } wc->locked = 0; cmd_wait_for_remove(wc); |