Skip to content
Snippets Groups Projects

bl00mbox: less aggressive plugin gc

Merged moon2 requested to merge bl00mbox_less_aggressive_gc into main
3 files
+ 68
7
Compare changes
  • Side-by-side
  • Inline
Files
3
@@ -26,6 +26,8 @@ typedef struct _channel_core_obj_t {
// will be NULLed on original if channel has been manually deleted
bl00mbox_channel_t *chan;
mp_obj_t channel_plugin;
// list of all sources connect to the mixer to avoid gc
mp_obj_t sources_mx;
#ifdef BL00MBOX_CALLBACKS_FUNSAFE
// the channel may be become reachable after having been unreachable.
// if the callback was collected during this phase it results in a
@@ -49,6 +51,8 @@ typedef struct _plugin_core_obj_t {
// that might trigger a gc (like creating objects) you need to check this
// pointer for NULL again.
bl00mbox_plugin_t *plugin;
// list of all source plugins to avoid gc
mp_obj_t sources;
} plugin_core_obj_t;
STATIC const mp_obj_type_t plugin_core_type;
@@ -94,6 +98,38 @@ static void bl00mbox_error_unwrap(bl00mbox_error_t error) {
}
}
void bl00mbox_disconnect_rx_callback(void *rx, uint16_t signal_index) {
plugin_core_obj_t *self = rx;
mp_obj_list_t *list = MP_OBJ_TO_PTR(self->sources);
if (signal_index < list->len) {
list->items[signal_index] = mp_const_none;
} else {
bl00mbox_log_error("plugin signal list too short");
}
}
void bl00mbox_connect_rx_callback(void *rx, void *tx, uint16_t signal_index) {
plugin_core_obj_t *self = rx;
mp_obj_list_t *list = MP_OBJ_TO_PTR(self->sources);
if (signal_index < list->len) {
list->items[signal_index] = MP_OBJ_FROM_PTR(tx);
} else {
bl00mbox_log_error("plugin signal list too short");
}
}
void bl00mbox_disconnect_mx_callback(void *chan, void *tx) {
channel_core_obj_t *self = chan;
// don't have to check for duplicates, bl00mbox_user does that for us
mp_obj_list_remove(self->sources_mx, MP_OBJ_FROM_PTR(tx));
}
void bl00mbox_connect_mx_callback(void *chan, void *tx) {
channel_core_obj_t *self = chan;
// don't have to check for duplicates, bl00mbox_user does that for us
mp_obj_list_append(self->sources_mx, MP_OBJ_FROM_PTR(tx));
}
static char *strdup_raise(char *str) {
char *ret = strdup(str);
if (!ret) bl00mbox_error_unwrap(BL00MBOX_ERROR_OOM);
@@ -207,6 +243,12 @@ static mp_obj_t create_channel_plugin(bl00mbox_channel_t *chan) {
self->plugin = chan->channel_plugin;
self->plugin->parent = self;
self->plugin->parent_self_ref = &self->plugin;
size_t num_signals = self->plugin->rugin->len_signals;
mp_obj_t nones[num_signals];
for (size_t i = 0; i < num_signals; i++) nones[i] = mp_const_none;
self->sources = mp_obj_new_list(num_signals, nones);
return MP_OBJ_FROM_PTR(self);
}
@@ -214,7 +256,9 @@ STATIC mp_obj_t channel_core_make_new(const mp_obj_type_t *type, size_t n_args,
size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, 1, false);
channel_core_obj_t *self = m_new_obj_with_finaliser(channel_core_obj_t);
self->base.type = &channel_core_type;
self->sources_mx = mp_obj_new_list(0, NULL);
const char *name = strdup_raise(mp_obj_str_get_str(args[0]));
bl00mbox_channel_t *chan = bl00mbox_channel_create();
@@ -234,6 +278,7 @@ STATIC mp_obj_t channel_core_make_new(const mp_obj_type_t *type, size_t n_args,
bl00mbox_log_info("created channel %s", chan->name);
return MP_OBJ_FROM_PTR(self);
}
STATIC mp_obj_t mp_channel_core_make_fake(mp_obj_t self_in) {
channel_core_obj_t *fake = m_new_obj_with_finaliser(channel_core_obj_t);
fake->base.type = &channel_core_type;
@@ -241,6 +286,7 @@ STATIC mp_obj_t mp_channel_core_make_fake(mp_obj_t self_in) {
channel_core_obj_t *self = MP_OBJ_TO_PTR(self_in);
channel_core_verify(self);
fake->sources_mx = mp_const_none;
fake->chan = self->chan;
fake->chan_ref = self->chan_ref;
fake->fake = true;
@@ -431,6 +477,7 @@ STATIC mp_obj_t plugin_core_make_new(const mp_obj_type_t *type, size_t n_args,
if (chan_core->base.type != &channel_core_type) {
mp_raise_TypeError(MP_ERROR_TEXT("first argument must be ChannelCore"));
}
channel_core_verify(chan_core);
bl00mbox_channel_t *chan = chan_core->chan;
int plugin_kind = mp_obj_get_int(args[1]);
int init_var = mp_obj_get_int(args[2]);
@@ -443,6 +490,13 @@ STATIC mp_obj_t plugin_core_make_new(const mp_obj_type_t *type, size_t n_args,
self->plugin = plugin;
plugin->parent = self;
plugin->parent_self_ref = &self->plugin;
// create empty source list
size_t num_signals = plugin->rugin->len_signals;
mp_obj_t nones[num_signals];
for (size_t i = 0; i < num_signals; i++) nones[i] = mp_const_none;
self->sources = mp_obj_new_list(num_signals, nones);
bl00mbox_log_info("created plugin %s",
self->plugin->rugin->descriptor->name);
return MP_OBJ_FROM_PTR(self);
Loading