Prevent propagation loops
This commit is contained in:
parent
227a2d91df
commit
f40a0a8d12
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user