diff --git a/src/emu/bay.c b/src/emu/bay.c index c112f29..3a83882 100644 --- a/src/emu/bay.c +++ b/src/emu/bay.c @@ -69,6 +69,30 @@ bay_register(struct bay *bay, struct chan *chan) return 0; } +int +bay_remove(struct bay *bay, struct chan *chan) +{ + struct bay_chan *bchan = find_bay_chan(bay, chan->name); + if (bchan == NULL) { + err("bay_remove: channel %s not registered\n", + chan->name); + return -1; + } + + if (bchan->is_dirty) { + err("bay_remove: cannot remote bay channel %s in dirty state\n", + chan->name); + return -1; + } + + chan_set_dirty_cb(chan, NULL, NULL); + + HASH_DEL(bay->channels, bchan); + free(bchan); + + return 0; +} + int bay_add_cb(struct bay *bay, struct chan *chan, bay_cb_func_t func, void *arg) { diff --git a/src/emu/bay.h b/src/emu/bay.h index 2cada96..fa1289e 100644 --- a/src/emu/bay.h +++ b/src/emu/bay.h @@ -54,6 +54,7 @@ struct bay { }; int bay_register(struct bay *bay, struct chan *chan); +int bay_remove(struct bay *bay, struct chan *chan); struct chan *bay_find(struct bay *bay, const char *name); int bay_add_cb(struct bay *bay, struct chan *chan, bay_cb_func_t func, void *arg); void bay_init(struct bay *bay); diff --git a/test/unit/bay.c b/test/unit/bay.c index 4e4b674..7166418 100644 --- a/test/unit/bay.c +++ b/test/unit/bay.c @@ -1,6 +1,41 @@ #include "emu/bay.h" #include "common.h" +static void +test_remove(struct bay *bay) +{ + struct chan chan; + chan_init(&chan, CHAN_SINGLE, "removeme"); + + if (bay_register(bay, &chan) != 0) + die("bay_register failed\n"); + + if (bay_find(bay, chan.name) == NULL) + die("bay_find failed\n"); + + if (bay_remove(bay, &chan) != 0) + die("bay_remove failed\n"); + + if (bay_find(bay, chan.name) != NULL) + die("bay_find didn't fail\n"); +} + +static void +test_duplicate(struct bay *bay) +{ + struct chan chan; + chan_init(&chan, CHAN_SINGLE, "dup"); + + if (bay_register(bay, &chan) != 0) + die("bay_register failed\n"); + + if (bay_register(bay, &chan) == 0) + die("bay_register didn't fail\n"); + + if (bay_remove(bay, &chan) != 0) + die("bay_remove failed\n"); +} + static int callback(struct chan *chan, void *ptr) { @@ -17,35 +52,47 @@ callback(struct chan *chan, void *ptr) return 0; } -int main(void) +static void +test_callback(struct bay *bay) { - struct bay bay; - bay_init(&bay); - struct chan chan; chan_init(&chan, CHAN_SINGLE, "testchan"); - bay_register(&bay, &chan); + if (bay_register(bay, &chan) != 0) + die("bay_register failed\n"); int64_t data = 0; - bay_add_cb(&bay, &chan, callback, &data); + if (bay_add_cb(bay, &chan, callback, &data) != 0) + die("bay_add_cb failed\n"); if (data != 0) die("data changed after bay_chan_append_cb\n"); - struct value one = value_int64(1); - if (chan_set(&chan, one) != 0) + if (chan_set(&chan, value_int64(1)) != 0) die("chan_set failed\n"); if (data != 0) die("data changed after chan_set\n"); /* Now the callback should modify 'data' */ - if (bay_propagate(&bay) != 0) + if (bay_propagate(bay) != 0) die("bay_propagate failed\n"); if (data != 1) die("data didn't change after bay_propagate\n"); + if (bay_remove(bay, &chan) != 0) + die("bay_remove failed\n"); +} + +int main(void) +{ + struct bay bay; + bay_init(&bay); + + test_remove(&bay); + test_duplicate(&bay); + test_callback(&bay); + return 0; }