History

m_config_core: fix forced option notification with m_config_cache

bc28f7693d095758275448410aaa91255482857a originally added this, but the implementation isn't correct and causes excessive notifications when writing to other options which may have bad behavior in some some circumstances. Fix this by reworking the implementation for force options so that the timestamps of the option update compared instead. Whenever an option gets changed, the internal timestamp in the cache is always incremented. For a special force option, we can save this timestamp internally as well. Because cache_check_update is always checked before potentially sending an option notification, we know that if the internal timestamp is equal to the timestamp saved by a force update option, it must have been previously written. Thus, the notification can be sent. This lets options like geometry work repeatedly but without constantly sending notifications. Fixes #13954.

Dudemanguy committed 2 years ago

Commit 76367da1 parent 2e03e031 file · +31 −23Browse files

Unified · Split

options/m_config_core.c+31−23
@@ -99,12 +99,17 @@ struct config_cache { · 98 unmodified lines
99 void *wakeup_cb_ctx;99 void *wakeup_cb_ctx;
100};100};
101 101
102struct force_update {
103 char *name;
104 uint64_t ts;
105};
106
102// Per m_config_data state for each m_config_group.107// Per m_config_data state for each m_config_group.
103struct m_group_data {108struct m_group_data {
104 char *udata; // pointer to group user option struct109 char *udata; // pointer to group user option struct
105 uint64_t ts; // timestamp of the data copy110 uint64_t ts; // timestamp of the data copy
106 char **force_updates; // track if any opt in group was written with force_update111 struct force_update **force_update; // tracks opts that are written with force update
107 int force_updates_len;112 int force_update_len;
108};113};
109 114
110static void add_sub_group(struct m_config_shadow *shadow, const char *name_prefix,115static void add_sub_group(struct m_config_shadow *shadow, const char *name_prefix,
@@ -590,23 +595,30 @@ struct m_config_cache *m_config_cache_alloc(void *ta_parent, · 479 unmodified lines
590 return m_config_cache_from_shadow(ta_parent, global->config, group);595 return m_config_cache_from_shadow(ta_parent, global->config, group);
591}596}
592 597
593static void clear_force_update_list(struct m_group_data *gsrc)598static void append_force_update(struct m_config_cache *cache, struct m_group_data *gdata,
599 const char *opt_name)
594{600{
595 int index = 0;601 for (int i = 0; i < gdata->force_update_len; ++i) {
596 while (index < gsrc->force_updates_len) {602 if (strcmp(opt_name, gdata->force_update[i]->name) == 0) {
597 TA_FREEP(&gsrc->force_updates[index]);603 gdata->force_update[i]->ts = gdata->ts;
598 ++index;604 return;
605 }
599 }606 }
600 gsrc->force_updates_len = 0;607 struct force_update *new_update = talloc_zero(cache, struct force_update);
608 new_update->name = talloc_strdup(cache, opt_name);
609 new_update->ts = gdata->ts;
610 MP_TARRAY_APPEND(cache, gdata->force_update, gdata->force_update_len, new_update);
601}611}
602 612
603static bool check_force_update_list(struct m_group_data *gsrc, const char *opt_name)613static bool check_force_update(struct m_group_data *gdata, const char *opt_name,
614 uint64_t timestamp)
604{615{
605 int index = 0;616 for (int i = 0; i < gdata->force_update_len; ++i) {
606 while (index < gsrc->force_updates_len) {617 if ((strcmp(opt_name, gdata->force_update[i]->name) == 0) &&
607 if (strcmp(opt_name, gsrc->force_updates[index]) == 0)618 gdata->force_update[i]->ts == timestamp)
619 {
608 return true;620 return true;
609 ++index;621 }
610 }622 }
611 return false;623 return false;
612}624}
@@ -637,8 +649,8 @@ static void update_next_option(struct m_config_cache *cache, void **p_opt) · 24 unmodified lines
637 649
638 if (opt->offset >= 0 && opt->type->size) {650 if (opt->offset >= 0 && opt->type->size) {
639 bool opt_equal = m_option_equal(opt, ddst, dsrc);651 bool opt_equal = m_option_equal(opt, ddst, dsrc);
640 bool force_update = opt->force_update && gsrc->force_updates_len &&652 bool force_update = opt->force_update &&
641 check_force_update_list(gsrc, opt->name);653 check_force_update(gsrc, opt->name, in->ts);
642 if (!opt_equal || force_update) {654 if (!opt_equal || force_update) {
643 uint64_t ch = get_opt_change_mask(dst->shadow,655 uint64_t ch = get_opt_change_mask(dst->shadow,
644 in->upd_group, dst->group_index, opt);656 in->upd_group, dst->group_index, opt);
@@ -666,8 +678,6 @@ static void update_next_option(struct m_config_cache *cache, void **p_opt) · 21 unmodified lines
666 }678 }
667 679
668 gdst->ts = gsrc->ts;680 gdst->ts = gsrc->ts;
669 } else {
670 clear_force_update_list(gsrc);
671 }681 }
672 682
673 in->upd_group++;683 in->upd_group++;
@@ -791,10 +801,8 @@ bool m_config_cache_write_opt(struct m_config_cache *cache, void *ptr) · 117 unmodified lines
791 }801 }
792 }802 }
793 803
794 if (opt->force_update) {804 if (opt->force_update)
795 MP_TARRAY_APPEND(shadow, gsrc->force_updates, gsrc->force_updates_len,805 append_force_update(cache, gsrc, opt->name);
796 talloc_strdup(shadow, opt->name));
797 }
798 806
799 mp_mutex_unlock(&shadow->lock);807 mp_mutex_unlock(&shadow->lock);
800 808

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t