Closed LaKraven closed 6 years ago
It may actually be better to make the limits a "per-thread" affair. This would provide maximum flexibility, particularly if you know one or more threads will process their Events much more quickly than others.
This would mean the "global variable" would define only the maximum limit for the Event Engine's internal Threads (Queue/Stack) only as the central dispatch.
Possible downside of this approach would be that the central Event Engine could be stalled out waiting for an Event Thread to complete its work in order to free a slot in its Queue/Stack.
This warrants more thought!
Yeah, I'm going to implement a new member FMaxEventCount
in TLKEventContainer
and this limit will be applied collectively between the Queue
and the Stack
(which means the total potential dispatched Events in a given Thread will be FMaxEventCount
regardless of whether they are in the Queue
or the Stack
)
If set to 0, there will be no limit (but this is to be discouraged for the reasons stated in the OP)
It may be necessary to revoke any ability to set this by the implementing developer, and instead "automagically" balance the limit between all registered TLKEventContainer
descendant instances. This will be determined during further development.
Weirdly, it would also be fairly easy to dictate the Event Limit using the "Events Per Second" calculation, so that the limit is dynamically calculated based on the raw Event Processing Performance of each Event Thread.
This could be made an option reasonably easily, and might even be preferable for most applications!
Okay, through trial and error, as well as some fairly straight-forward deductive reasoning, I've determined that two separate limits are required.
A Per-Thread limit: Default to 0 (Unlimited), but allow the implementing developer to impose a maximum Queue/Stack limit for each Event Thread type.
A Global limit: Provided with a rational default value (which is higher on 64bit than 32bit for obvious reasons), as a global variable in the Event Engine's main unit, defining an absolute, system-wide, limit on the number of Events Queued/Stacked at any given moment.
I have to decide whether I should increment the global counter when a TLKEvent
descendant instance is created, or only when it is dispatched. This is a fairly critical consideration, and at present I'm leaning toward the former.
At present, it is possible for a suitably-fast processor (particularly if using multiple Threads) to dispatch so many Events so quickly that it floods the Event Engine, subsequently crashing the system.
This is particularly true on Win32 binaries, as it is possible to allocate more than 2GB of memory to Events that have yet to be processed.
Simple solution (most logical, even) is to provide a globally-modifiable Variable
LKSL_EVENTENGINE_EVENTLIMIT
(name may change) (with a "rational" default value) to dictate an absolute limit to the Event Engine.When a Thread dispatches an Event to the Event Engine after the Queue/Stack hits the defined limit, the dispatching Thread will be made to wait until there is room for the new Event.
Important: Don't freeze the entire dispatching Thread while waiting for room, because this might create a deadlock with the Event Engine trying to pass the Event along to said Thread. Easily avoided with a little careful implementation.