Allow bay callbacks to be enabled and disabled

This commit is contained in:
Rodrigo Arias 2023-02-17 17:21:26 +01:00 committed by Rodrigo Arias Mallo
parent fe6db823a7
commit 5961c4fa96
2 changed files with 56 additions and 15 deletions

View File

@ -25,7 +25,7 @@ cb_chan_is_dirty(struct chan *chan, void *arg)
return -1; return -1;
} }
dbg("adding dirty chan %s", chan->name) dbg("adding dirty chan %s", chan->name);
DL_APPEND(bay->dirty, bchan); DL_APPEND(bay->dirty, bchan);
return 0; return 0;
@ -103,34 +103,68 @@ bay_remove(struct bay *bay, struct chan *chan)
return 0; return 0;
} }
int struct bay_cb *
bay_add_cb(struct bay *bay, enum bay_cb_type type, bay_add_cb(struct bay *bay, enum bay_cb_type type,
struct chan *chan, bay_cb_func_t func, void *arg) struct chan *chan, bay_cb_func_t func, void *arg, int enabled)
{ {
if (func == NULL) { if (func == NULL) {
err("bay_add_cb: func is NULL\n"); err("func is NULL");
return -1; return NULL;
} }
struct bay_chan *bchan = find_bay_chan(bay, chan->name); struct bay_chan *bchan = find_bay_chan(bay, chan->name);
if (bchan == NULL) { if (bchan == NULL) {
err("bay_add_cb: cannot find channel %s in bay\n", chan->name); err("cannot find channel %s in bay", chan->name);
return -1; return NULL;
} }
struct bay_cb *cb = calloc(1, sizeof(struct bay_cb)); struct bay_cb *cb = calloc(1, sizeof(struct bay_cb));
if (cb == NULL) { if (cb == NULL) {
err("bay_add_cb: calloc failed\n"); err("calloc failed");
return -1; return NULL;
} }
cb->func = func; cb->func = func;
cb->arg = arg; cb->arg = arg;
cb->bchan = bchan;
cb->type = type;
cb->enabled = 0;
DL_APPEND(bchan->cb[type], cb); if (enabled)
bchan->ncallbacks[type]++; bay_enable_cb(cb);
return 0;
return cb;
}
void
bay_enable_cb(struct bay_cb *cb)
{
if (cb->enabled)
return;
cb->enabled = 1;
struct bay_chan *bchan = cb->bchan;
if (bchan->is_dirty)
die("cannot change callbacks of dirty bay channel");
DL_APPEND(bchan->cb[cb->type], cb);
bchan->ncallbacks[cb->type]++;
}
void
bay_disable_cb(struct bay_cb *cb)
{
if (cb->enabled == 0)
return;
cb->enabled = 0;
struct bay_chan *bchan = cb->bchan;
if (bchan->is_dirty)
die("cannot change callbacks of dirty bay channel");
DL_DELETE(bchan->cb[cb->type], cb);
bchan->ncallbacks[cb->type]++;
} }
void void
@ -154,7 +188,9 @@ propagate_chan(struct bay_chan *bchan, enum bay_cb_type type)
bchan->chan->name, propname[type]); bchan->chan->name, propname[type]);
struct bay_cb *cur = NULL; struct bay_cb *cur = NULL;
/* New callbacks cannot be added while propagating a bay_chan */
DL_FOREACH(bchan->cb[type], cur) { DL_FOREACH(bchan->cb[type], cur) {
dbg("calling cb %p", cur->func);
if (cur->func(bchan->chan, cur->arg) != 0) { if (cur->func(bchan->chan, cur->arg) != 0) {
err("propagate_chan: callback failed\n"); err("propagate_chan: callback failed\n");
return -1; return -1;

View File

@ -21,6 +21,9 @@ typedef int (*bay_cb_func_t)(struct chan *chan, void *ptr);
struct bay_cb { struct bay_cb {
bay_cb_func_t func; bay_cb_func_t func;
void *arg; void *arg;
struct bay_chan *bchan;
int enabled;
int type;
/* List of callbacks in one channel */ /* List of callbacks in one channel */
struct bay_cb *next; struct bay_cb *next;
@ -61,9 +64,11 @@ struct bay {
void bay_init(struct bay *bay); void bay_init(struct bay *bay);
USE_RET int bay_register(struct bay *bay, struct chan *chan); USE_RET int bay_register(struct bay *bay, struct chan *chan);
USE_RET int bay_remove(struct bay *bay, struct chan *chan); USE_RET int bay_remove(struct bay *bay, struct chan *chan);
USE_RET struct chan *bay_find(struct bay *bay, const char *name);
USE_RET int bay_add_cb(struct bay *bay, enum bay_cb_type type,
struct chan *chan, bay_cb_func_t func, void *arg);
USE_RET int bay_propagate(struct bay *bay); USE_RET int bay_propagate(struct bay *bay);
USE_RET struct chan *bay_find(struct bay *bay, const char *name);
USE_RET struct bay_cb *bay_add_cb(struct bay *bay, enum bay_cb_type type,
struct chan *chan, bay_cb_func_t func, void *arg, int enabled);
void bay_enable_cb(struct bay_cb *cb);
void bay_disable_cb(struct bay_cb *cb);
#endif /* BAY_H */ #endif /* BAY_H */