Page MenuHomeFeedback Tracker

BIS_fnc_loop is not reliable because of preemption
Closed, ResolvedPublic

Description

BIS_fnc_loop can be preempted by onEachFrame handler during BIS_fnc_loop initialization.

Here is how it might happen:

  1. BIS_fnc_loop enters "itemAdd" case.
  2. BIS_fnc_loop enters "initialize" and subscribes to onEachFrame event
  3. onEachFrame happens and calls BIS_fnc_loop's "onEachFrame" case that auto-deinitializes queue.
  4. BIS_fnc_loop leaves "initialize" (entered is step 2).
  5. missionNameSpace getVariable "BIS_fnc_loop_queue" is nil (deinitialized at step 3) <<<--- BUG HERE

Please watch this video - http://www.youtube.com/watch?v=lS83RYzNprM#t=55
{F24976}

Details

Legacy ID
902363653
Severity
None
Resolution
Fixed
Reproducibility
Always
Category
Scripting
Steps To Reproduce
  1. Start this infinite loop:

MyFunc =
{
hintSilent str [time, _this];
{ deleteVehicle _x } forEach (allMissionObjects "");
private ["_i"];
for "_i" from 0 to 100 do
{

		private ["_veh_cnt", "_rnd", "_cfg"];
		_veh_cnt = count (configFile >> "CfgVehicles");
		_rnd = floor(random (_veh_cnt - 1));
		_cfg = (configFile >> "CfgVehicles") select _rnd;
		if (isClass(_cfg)) then
		{
			private ["_veh"];
			_veh = (configName _cfg) createVehicle ([random 30000, random 30000, 0]);
			player globalChat str _veh;
		};

};

[format ["MyFunc_%1", time], compile format ["%1 spawn MyFunc", time], 1] call BIS_fnc_runLater;
};

[time] call MyFunc;

  1. make yourself a cup of tea - this loop will stop working in a minute or so.

Event Timeline

sms edited Steps To Reproduce. (Show Details)Oct 16 2014, 10:15 PM
sms edited Additional Information. (Show Details)
sms set Category to Scripting.
sms set Reproducibility to Always.
sms set Severity to None.
sms set Resolution to Fixed.
sms set Legacy ID to 902363653.May 7 2016, 7:37 PM
MaHuJa added a subscriber: MaHuJa.May 7 2016, 7:37 PM

"This video is private."

You probably want to change that to unlisted.

Fixed, expect it on Dev Branch next week.
Your example code is problematic because it tries to spawn core modules, try instead:

MyFunc =
{

hintSilent str [time, _this];
[format ["MyFunc_%1", time], compile format ["%1 call MyFunc", time], 1] call BIS_fnc_runLater;

};
[time] call MyFunc;

And it should run forever.
The problem was automatic termination of BIS_fnc_loop in case there were no more items to execute.
Please confirm whether it is solved.
Thank you.

sms added a subscriber: sms.May 7 2016, 7:37 PM
sms added a comment.Oct 17 2014, 10:06 AM

MaHuJa: Sorry about that. Changed to public.

neokika: Thank you! Yes, my real code spawns harmless vehicles like "Land_CncBarrier_F" etc, not modules. The point was to make something that takes long time, then call BIS_fnc_runLater for onEachFrame to interleave with BIS_fnc_runLater execution.

@sms Is this deemed fixed? Thank you.

sms added a comment.Nov 1 2014, 12:11 AM

neokika: Yes, it is seems to be fixed (I've tested it for several days, no problems), thank you! I think it is safe to close this issue now.

(What would be good (for the future) is to be able to pass additonal user parameters as (for example) BIS_fnc_addStackedEventHandler does and, maybe, use user function return value as a new delay value).

cyckuan added a subscriber: cyckuan.May 7 2016, 7:37 PM

onEachFrame is now broken. Draws only 1 frame and doesnt seem to loop anymore.

@cykuan I am unable to repro. Please, if you are still affected by that issue please create a separate ticket.
Thank you.

The cause of this was one version of CBA. Therefore not related. Happy for this to close.