diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2019-10-29 16:15:38 -0600 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2019-10-29 16:20:04 -0600 |
commit | c368c26519d05815e9bfadbd02f9de5f5d84321c (patch) | |
tree | 8a5ddd08e2de433332cb1c68a9d8bb864c21e807 /libs/ardour/transport_fsm.cc | |
parent | 78cf0e5235a4138cc1c118dd4c2e202320d74b21 (diff) |
fix handling of deferred events in transportFSM
tfsm events live on intrusive lists, with only 1 hook, which means they
can only be on one list at a time, and cannot be deleted while part of
the list. This wasn't being addressed properly when deferring (and
undeferring) events.
Diffstat (limited to 'libs/ardour/transport_fsm.cc')
-rw-r--r-- | libs/ardour/transport_fsm.cc | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/libs/ardour/transport_fsm.cc b/libs/ardour/transport_fsm.cc index 2fd61a3d00..c8b5c65035 100644 --- a/libs/ardour/transport_fsm.cc +++ b/libs/ardour/transport_fsm.cc @@ -80,7 +80,19 @@ TransportFSM::process_events () MotionState oms = _motion_state; ButlerState obs = _butler_state; - if (process_event (queued_events.front())) { /* event processed successfully */ + Event* ev = &queued_events.front(); + bool deferred; + + /* must remove from the queued_events list now, because + * process_event() may defer the event. This will lead to + * insertion into the deferred_events list, and its not possible + * with intrusive lists to be present in two lists at once + * (without additional hooks). + */ + + queued_events.pop_front (); + + if (process_event (*ev, false, deferred)) { /* event processed successfully */ if (oms != _motion_state || obs != _butler_state) { @@ -93,7 +105,8 @@ TransportFSM::process_events () for (EventList::iterator e = deferred_events.begin(); e != deferred_events.end(); ) { Event* deferred_ev = &(*e); - if (process_event (*e)) { /* event processed, remove from deferred */ + bool deferred2; + if (process_event (*e, true, deferred2)) { /* event processed, remove from deferred */ e = deferred_events.erase (e); delete deferred_ev; } else { @@ -104,9 +117,9 @@ TransportFSM::process_events () } } - Event* ev = &queued_events.front(); - queued_events.pop_front (); - delete ev; + if (!deferred) { + delete ev; + } } processing--; @@ -178,10 +191,12 @@ TransportFSM::bad_transition (Event const & ev) } bool -TransportFSM::process_event (Event& ev) +TransportFSM::process_event (Event& ev, bool already_deferred, bool& deferred) { DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("process %1\n", enum_2_string (ev.type))); + deferred = false; + switch (ev.type) { case StartTransport: @@ -194,10 +209,16 @@ TransportFSM::process_event (Event& ev) break; case DeclickToLocate: case WaitingForLocate: - defer (ev); + if (!already_deferred) { + defer (ev); + deferred = true; + } break; case DeclickToStop: - defer (ev); + if (!already_deferred) { + defer (ev); + deferred = true; + } break; default: bad_transition (ev); return false; @@ -215,7 +236,10 @@ TransportFSM::process_event (Event& ev) break; case DeclickToLocate: case WaitingForLocate: - defer (ev); + if (!already_deferred) { + defer (ev); + deferred = true; + } break; default: bad_transition (ev); return false; @@ -224,6 +248,12 @@ TransportFSM::process_event (Event& ev) break; case Locate: + DEBUG_TRACE (DEBUG::TFSMEvents, string_compose ("locate, with roll = %1 flush = %2 target = %3 loop %4 force %5\n", + ev.with_roll, + ev.with_flush, + ev.target, + ev.with_loop, + ev.force)); switch (_motion_state) { case Stopped: transition (WaitingForLocate); |