Airlock Depressurisation Bug (Cause found in code!)

Jordan Senft shared this bug 22 hours ago
Submitted

Hi there,


There has been a long standing Depressurization bug in Space Engineers that seemingly causes air vents to be impossible to depressurize.


After quite a bit of work, the cause has been found (both in game and in code) by myself.


As seen in the attached image, the room with room id 91 is in the right most room... the flood of room ids seen in the lower middle of the screen are also room 91...


The bug is caused by the blocks that count as part of a room id being spread outside the room. This also explains why other rooms can have the depressurization bug behavior "spread", as when you open doors, the bugged room essentially takes over the space (For example, if I opened rooms in the image shown, they too became room 91 if part of the same grid).


The cause for this, I believe, is a race condition / issue with the asynchronous programming in `MyGridGasSystem`.


Specifically, within the `Update` method, a call to `this.StartGenerateAirtightData()` is called, and within it is a parallel task :


this.m_backgroundTask = Parallel.Start(new Action(this.GenerateAirtightData), new Action(this.OnBackgroundTaskFinished));

The issue is this parallel task is called with no checks to see if any other parallel tasks are running. I.e. the parallel task within `this.StartGenerateAirtightData()` will always run.


The issue is that `this.StartGenerateAirtightData()` is relatively quick, so its `BackgroundTaskFinished` method call will happen quite quickly also. Within that `BackgroundTaskFinished` task is a call to do the following:

this.m_isProcessingData = false;


So, if the previous tick / update's other parallel tasks such as:

this.StartShrinkData();

or


this.StartRefreshRoomData();

Are still running (due to being parallel tasks, they can carry through to the next call of `Update()` then, as `this.StartGenerateAirtightData()` will always run, there is a chance that:


this.m_isProcessingData = false;
is called before the other parallel tasks are completed.

This can then lead to 2 threads executing either of the parallel tasks in

this.StartShrinkData();

or


this.StartRefreshRoomData();


Methods, as the check that should prevent this will pass due to the previously mentioned:

this.m_isProcessingData = false;
caused by `this.StartGenerateAirtightData()` .


Whilst I cannot tell you exactly why the behavior seen in the attached image is caused by this concurrency / race condition, hopefully it is enough context for you wonderful folks at Keen to finally nip this age old issue in the bud.


Kind Regards,


Jordan Senft (An Aerospace Engineering Programme Lead who loves this Aerospace Engineering game so much he spent his Friday de-compiling code to bug hunt, and his Saturday morning writing up a bug report for one of his favorite game studios!

Leave a Comment
 
Attach a file
Access denied