Prevent propagation loops

This commit is contained in:
Rodrigo Arias 2023-01-11 12:42:18 +01:00 committed by Rodrigo Arias Mallo
parent 227a2d91df
commit f40a0a8d12
3 changed files with 22 additions and 5 deletions

View File

@ -14,7 +14,11 @@ cb_chan_is_dirty(struct chan *chan, void *arg)
struct bay_chan *bchan = arg; struct bay_chan *bchan = arg;
struct bay *bay = bchan->bay; struct bay *bay = bchan->bay;
/* TODO: check duplicate? */ if (bchan->is_dirty) {
err("channel %s already on dirty list\n", chan->name);
return -1;
}
DL_APPEND(bay->dirty, bchan); DL_APPEND(bay->dirty, bchan);
return 0; return 0;
} }
@ -94,8 +98,6 @@ bay_add_cb(struct bay *bay, struct chan *chan, bay_cb_func_t func, void *arg)
return 0; return 0;
} }
void void
bay_init(struct bay *bay) bay_init(struct bay *bay)
{ {
@ -142,6 +144,7 @@ bay_propagate(struct bay *bay)
err("bay_propagate: chan_flush failed\n"); err("bay_propagate: chan_flush failed\n");
return -1; return -1;
} }
cur->is_dirty = 0;
} }
bay->dirty = NULL; bay->dirty = NULL;

View File

@ -28,6 +28,7 @@ struct bay_chan {
int ncallbacks; int ncallbacks;
struct bay_cb *cb; struct bay_cb *cb;
struct bay *bay; struct bay *bay;
int is_dirty;
/* Global hash table with all channels in bay */ /* Global hash table with all channels in bay */
UT_hash_handle hh; UT_hash_handle hh;

View File

@ -88,8 +88,6 @@ cb_input(struct chan *in_chan, void *ptr)
{ {
struct mux *mux = ptr; struct mux *mux = ptr;
/* TODO: We may need to cache the last read value from select to avoid
* problems reading the select channel too soon */
struct value sel_value; struct value sel_value;
if (chan_read(mux->select, &sel_value) != 0) { if (chan_read(mux->select, &sel_value) != 0) {
err("cb_input: chan_read(select) failed\n"); err("cb_input: chan_read(select) failed\n");
@ -139,6 +137,11 @@ mux_init(struct mux *mux,
return -1; return -1;
} }
if (select == output) {
err("mux_init: cannot use same channel as select and output\n");
return -1;
}
/* The output channel must accept multiple writes in the same /* The output channel must accept multiple writes in the same
* propagation phase while the channel is dirty, as we may write to the * propagation phase while the channel is dirty, as we may write to the
* input and select channel at the same time. */ * input and select channel at the same time. */
@ -178,6 +181,16 @@ mux_find_input(struct mux *mux, struct value value)
int int
mux_add_input(struct mux *mux, struct value key, struct chan *chan) mux_add_input(struct mux *mux, struct value key, struct chan *chan)
{ {
if (chan == mux->output) {
err("mux_init: cannot use same input channel as output\n");
return -1;
}
if (chan == mux->select) {
err("mux_init: cannot use same input channel as select\n");
return -1;
}
if (mux_find_input(mux, key) != NULL) { if (mux_find_input(mux, key) != NULL) {
char buf[128]; char buf[128];
err("mux_add_input: input key %s already in mux\n", err("mux_add_input: input key %s already in mux\n",