22
33#include < stdexcept>
44#include < thread>
5+ #include < unordered_set>
56#include < vector>
67
78#include < yasmin/logs.hpp>
@@ -27,18 +28,28 @@ yasmin::Outcomes FirstWinsConcurrence::collect_outcomes(
2728FirstWinsConcurrence::FirstWinsConcurrence (
2829 const yasmin::StateMap& states,
2930 const std::string& default_outcome,
30- const FirstWinsOutcomeMap& outcome_map)
31+ const FirstWinsOutcomeMap& outcome_map,
32+ const std::unordered_set<std::string>& winner_states)
3133 : State(collect_outcomes(outcome_map, default_outcome)),
3234 states_ (states),
3335 default_outcome_(default_outcome),
34- outcome_map_(outcome_map) {
36+ outcome_map_(outcome_map),
37+ winner_states_(winner_states) {
3538 for (const auto & [state_name, _] : outcome_map) {
3639 if (states.find (state_name) == states.end ()) {
3740 throw std::invalid_argument (
3841 " FirstWinsConcurrence: outcome_map references unknown state '" +
3942 state_name + " '" );
4043 }
4144 }
45+ for (const auto & name : winner_states_) {
46+ if (states.find (name) == states.end ()) {
47+ throw std::invalid_argument (
48+ " FirstWinsConcurrence: winner_states references unknown "
49+ " state '" +
50+ name + " '" );
51+ }
52+ }
4253}
4354
4455std::string FirstWinsConcurrence::execute (
@@ -54,7 +65,18 @@ std::string FirstWinsConcurrence::execute(
5465 threads.emplace_back ([this , blackboard, name = name, state = state]() {
5566 const std::string outcome = (*state)(blackboard);
5667
57- // Only the first completion wins; subsequent ones are ignored.
68+ // If winner_states is set, only those states can win the race.
69+ if (!winner_states_.empty () &&
70+ winner_states_.find (name) == winner_states_.end ()) {
71+ YASMIN_LOG_INFO (
72+ " FirstWinsConcurrence: '%s' finished with '%s' but is not "
73+ " an eligible winner, ignoring" ,
74+ name.c_str (), outcome.c_str ());
75+ return ;
76+ }
77+
78+ // Only the first eligible completion wins; subsequent ones are
79+ // ignored.
5880 bool expected = false ;
5981 if (first_done_.compare_exchange_strong (expected, true )) {
6082 {
0 commit comments