summaryrefslogtreecommitdiffstats
path: root/cmd-wait-for.c
diff options
context:
space:
mode:
Diffstat (limited to 'cmd-wait-for.c')
-rw-r--r--cmd-wait-for.c69
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);