if no current valid reference) */
static int reported_no_majority; /* Flag to avoid repeated log message
about no majority */
+static int report_selection_loss; /* Flag to force logging a message if
+ selection is lost in a transient state
+ (SRC_WAITS_STATS, SRC_WAITS_UPDATE) */
/* Score needed to replace the currently selected source */
#define SCORE_LIMIT 10.0
/* Forward prototype */
static void update_sel_options(void);
+static void unselect_selected_source(LOG_Severity severity, const char *format,
+ const char *arg);
static void slew_sources(struct timespec *raw, struct timespec *cooked, double dfreq,
double doffset, LCL_ChangeType change_type, void *anything);
static void add_dispersion(double dispersion, void *anything);
if (last_updated_inst == instance)
last_updated_inst = NULL;
- /* Force reselection if currently selected */
- SRC_ResetInstance(instance);
-
assert(initialised);
if (instance->index < 0 || instance->index >= n_sources ||
- instance->index == selected_source_index ||
instance != sources[instance->index])
assert(0);
if (selected_source_index > dead_index)
--selected_source_index;
+ else if (selected_source_index == dead_index)
+ unselect_selected_source(LOGS_INFO, NULL, NULL);
+
+ SRC_SelectSource(NULL);
}
/* ================================================== */
}
}
+/* ================================================== */
+/* Reset the index of selected source and report the selection loss. If no
+ message is provided, assume it is a transient state and wait for another
+ call providing a message or selection of another source, which resets the
+ report_selection_loss flag. */
+
+static void
+unselect_selected_source(LOG_Severity severity, const char *format, const char *arg)
+{
+ if (selected_source_index != INVALID_SOURCE) {
+ selected_source_index = INVALID_SOURCE;
+ report_selection_loss = 1;
+ }
+
+ if (report_selection_loss && format) {
+ log_selection_message(severity, format, arg);
+ report_selection_loss = 0;
+ }
+}
+
/* ================================================== */
static int
}
if (n_sources == 0) {
- /* Removed sources are unselected before actual removal */
- if (selected_source_index != INVALID_SOURCE)
- assert(0);
+ unselect_selected_source(LOGS_INFO, "Can't synchronise: no sources", NULL);
return;
}
if (n_badstats_sources && n_sel_sources && selected_source_index == INVALID_SOURCE &&
max_sel_reach_size < SOURCE_REACH_BITS && max_sel_reach >> 1 == max_badstat_reach) {
mark_ok_sources(SRC_WAITS_STATS);
+ unselect_selected_source(LOGS_INFO, NULL, NULL);
return;
}
if (n_endpoints == 0) {
/* No sources provided valid endpoints */
- if (selected_source_index != INVALID_SOURCE) {
- log_selection_message(LOGS_INFO, "Can't synchronise: no selectable sources", NULL);
- selected_source_index = INVALID_SOURCE;
- }
+ unselect_selected_source(LOGS_INFO, "Can't synchronise: no selectable sources", NULL);
return;
}
if (!reported_no_majority) {
log_selection_message(LOGS_WARN, "Can't synchronise: no majority", NULL);
reported_no_majority = 1;
+ report_selection_loss = 0;
}
if (selected_source_index != INVALID_SOURCE) {
}
if (!n_sel_sources || sel_req_source || n_sel_sources < CNF_GetMinSources()) {
- if (selected_source_index != INVALID_SOURCE) {
- log_selection_message(LOGS_INFO, "Can't synchronise: %s selectable sources",
- !n_sel_sources ? "no" :
- sel_req_source ? "no required source in" : "not enough");
- selected_source_index = INVALID_SOURCE;
- }
+ unselect_selected_source(LOGS_INFO, "Can't synchronise: %s selectable sources",
+ !n_sel_sources ? "no" :
+ sel_req_source ? "no required source in" : "not enough");
mark_ok_sources(SRC_WAITS_SOURCES);
return;
}
/* Before selecting the new synchronisation source wait until the reference
can be updated */
if (sources[max_score_index]->updates == 0) {
- selected_source_index = INVALID_SOURCE;
+ unselect_selected_source(LOGS_INFO, NULL, NULL);
mark_ok_sources(SRC_WAITS_UPDATE);
return;
}
}
reported_no_majority = 0;
+ report_selection_loss = 0;
}
mark_source(sources[selected_source_index], SRC_SELECTED);