Hi Will and the other yoshimi-developers,
as indicated, currently I am involved in an attempt to rework
some of Yoshimi's main application and instance handling logic.
To place this into context, we agree that we have some deeper rooted
architecture problems in the Yoshimi application; especially these
are highlighted by the difficulties haunting the Yoshimi LV2 plug-in;
as it stands, we seem unable to comply to the structures and requirements
of the plug-in standard, and must rely on a non-standard extension and
assume that in fact the LV2 plug-in and it's GUI run in a single process;
in addition we rely on circumstances that just seem to hold for all known
LV2 hosts, without being covered by the standard.
Since some time, we try to address those problems in small manageable
steps, attempting not to break anything relevant for the musical performance.
- there is an ongoing effort to streamline and modernise the memory handling
- another effort is to disentangle the Synth engine from the GUI and to offload
all internal communication to some clearly defined connection systems.
The latter turns out as a quite daunting task, since the GUI regularly just
grabs into the SynthEngine's innards, disregarding anything known about
thread safety on modern machines. Basically, it shows through that the
original code base can be traced back to roots in the 90ies, where you
could be under the impression that concurrency is just (non)preemptive
switching of active functions and data is just sitting in "the memory".
Over the years, Will was quite effective with gradually changing all
command-and-control to be exchanged via some ringbuffer channels.
Last winter, we've developed a new connection scheme, which additionally
allows the core to push bulk data up into the GUI; as a first prototypical
use, we currently attempt to use this new "GuiDataExchange" to handle
effect data and most notably the EQ graphs. This is currently merged
in master, and -- overall -- works quite well. However, we run into
some difficulties when using and especially restoring multiple
Synth engine instances.
On Fri, 31 May 2024 15:06:34 +0200 ichthyo <p...@ichthyostega.de> wrote:
....I have investigated problems when restoring multiple Instances on
start-up. Doing so causes a time-out on the initial "bootstrap" message
sent up into UI, and thus a complete failure of UI startup; the message
would be processed about 600ms later in this case (which is above an
implicit tiemout level of 500ms, which I've built into the new connection
scheme to weed out stale messages).
I tend to resist the temptation just to weaken the timeout level. Rather,
I am looking into what causes that delay. Starting those instances was
somehow hooked into the existing logic of main, and I am under the
impression that the second instance start-up is triggered at the begin of
the event loop and blocks the completion of the initial instance's
start-up.
On 31.05.24 16:12, Will Godfrey wrote:
This was all built up over several years
...
The problems stem from the need for the first stand-alone instance to know
which other instances are currently active when it shuts down so that it can
restart them on the next run - hence that integer handled bit-wise. Each
instance has it's own config and instance files, so if you want to start the
identical setup you need to know which ones to fetch. I did try to find a way
for the first instance start to complete before it loaded the others, but
hadn't been able to do so. A further complication is the feature to force a
new startup from the desktop to open a new slave instance instead.
On 31.05.24 16:42, ichthyo wrote:
Maybe a solution could be to make the current> state of each instance in the
instance map even more explicit; and also the request to start an instance
could be some kind of command, or it could be explicitly marked in the
instance map. (...) we could store a descriptor record as "value" and this
would allow us to store state information explicitly alongside.
Meanwhile, I've completed a draft for a reworked structure at application main()
level, which indeed seems to resolve the structural problems. While there is
still a lot of details to sort out (and it is not actually working code yet!),
I'd like to share the basic approach taken for these proposed changes.
The idea is to turn the main() code inside-out -- or better outside-in....
- define a new component, which I call InstanceManager
- this is a singleton and accessible through the static part of Config
- inside, as internal detail, there is a helper component which maintains
a table of all running instances, and this will be the only part in the
system expected to create SynthEngine and MusicClient objects
- in this table, we store a new entity, which can be seen as an instance
of "the engine". It comprises a SynthEngine, a MusicClient (IO) and,
most important, some lifecycle state flags.
- the body of the main(loop)thread is turned into a »duty cycle«
which is completely governed internally by the InstanceManager
- as part of this duty cycle, all registered instances will be visited
in turn, and each one will be treated according to its lifecycle state
- with this scheme, a new instance can be created as an empty shell,
associated with an instanceID. This represents a request to boot
a new instance for this ID
- such requests are treated with low priority (after the normal event
processing); the new instance will be initialised, connected and started...
- in the next lifecycle phase, the started instance will possibly create
and populate its UI and do further start-up work (loading history, banks)
- then it enters running state, which entails invoking a callback, to
perform the actual FLTK event processing and handle the "returns"- updates
sent back from the core up into the GUI. As part of these "returns", also
the push-updates via the new GuiDataExchange will take place
- there is room for also adding an unwinding stage, after which the
engine instance is taken out of duty and disposed of.
As said, the above can be considered a draft and work in progress still;
hopefully my explanations do make sense and allow to see the direction
this effort is headed, as its yet a lot of complicated stuff to
understand and resolve indeed...
-- Hermann
_______________________________________________
Yoshimi-devel mailing list
Yoshimi-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/yoshimi-devel