From Gnash Project Wiki
Threads are hard to debug and maintain. In practice they give lots of problems. So this is an idea to drop their use completely.
See task Task #6960.
The main loop of the gui should not only handle user events and FPS timeout, as it does now. Instead should be augmented to also give a filedescriptor manager a chance to execute (beside also interval expiration calls, see MovieAdvancement for this one).
The filedescriptor manager would maintain a set of filedescriptor and call select on them, with an appropriate timeout computed looking at the VirtualClock. An appropriate timeout is one that doesn't cross next time-constrainted event (like FPS, for instance).
If the select call reveals data being ready on any of the maintained filedescriptor, the manager would invoke callbacks associated to the ready-to-use ones.
The callbacks would need to perform non-blocking reads on the filedescriptors, so to only cache the available data, with least delay possible. Some of them might also parse the data instead of just buffering it locally.
When it's FPS advancement time, the playback would or not enter next frame depending on whether next frame had a chance to be parsed.
The gui in this plan should only take care of setting up a frequent callback into the core lib. The core lib would know what to do depending on time elapsed (looking at the virtual clock). It may be executing expired intervals, advancing playhead or just let the Filedescriptor manager perform its selects. This should avoid duplicating complex code in all GUIs.
Possibly, we'll want the GUI to provide some time constraint for the callback, to avoid long time spent in callbacks making user events delay (plus FPS rate delays).
The Filedescriptor manager (FDKeeper?) would be the core lib object keeping the set of fd of interest and performing the actual select call. Now some of the filedescriptors might not get ready by themselves but would rather need calls to filler (I'm thinking libcurl atm). If this is confirmed there's an additional step to be taken from it, which is stimulating the filler, again with a timeout.
Data callback interface
The callbacks registered with the Filedescriptor manager might either just know everything by themselves (stateful functor) or receive a memory pointer and a size argument being the available data, to avoid duplication of code for fetching system-buffered bytes.
One thing to inspect is how to signal end of stream, would the callbacks still be called in that case, with which arguments in the latter case ?
Callback registration interface
Any subsystem in need for data should take care of setting up the filedescriptor and registering it with the Filedescriptor manager togheter with a callback (functor or something else, read previous section).
In case selecting the fd is not enough, but rather it takes some 'stimulation' to change fd state (think libcurl) we'd also need to register a callback to stimulate it. Again thinking about libcurl, the stimulation function (curl_perform) is able to change state of multiple filedescriptors, so I wonder if we should have a single Fildescriptor manager at all or rather a set of callbacks to be just called at regular intervals (in this case the entry point in the core lib would not be a "filedescriptors manager" but rather an Idle time callbacks manager).