Re: Suspensions and NewVariableInstance

2021-02-02 Thread Beckerle, Mike
Well, to sanity check ideas, here's my thoughts on how unparsers and variable 
instances and suspensions/expressions ought to interact.

There may be naive assumptions in here. If so let's find them.

So unparsers call each other in a recursive walk, and variable instances go 
in/out of scope as the unparsers are walked. That's on the variable-map 
structure stacks in UStateMain.

This creates the variable instances, and those specific variable instances 
should be the ones that are frozen into a suspension. I.e., the suspension 
shouldn't contain the variable map with things going into/out of scope, but 
just a single association of variable name to variable instance object.

So I think creating a suspension should create a snapshot of the top-of-stack 
for each variable as part of that UStateForSuspension. It's important that 
these variable instances are; however, shared with other expressions/unparser 
actions that are for that same scope. So we can't deep copy the variable 
instances themselves or we'll disconnect them from their producers and 
consumers. We could in principle copy the variable stacks with all their 
pointers to variable instances, but we'll only ever address the top-of-stack 
variable instances from a suspension.

These variable instances are then sort of floating in air, connected to 
expressions that produce/consume them by the suspension/expression system, but 
they're not being stack-maintained any more. They're heap objects at that 
point, disconnected from the stacks that controlled when they were 
scope-visible. They have to eventually be reclaimed by the garbage collector.

The variable going out of scope should only affect the variable map in the 
UStateMain object, not the suspensions, and it should remove a variable from 
scope, but not otherwise frob the variable-instance, which may be referenced by 
suspensions.

Now, all that said, I bet there's a flaw in there.





From: Adams, Joshua 
Sent: Tuesday, February 2, 2021 11:12 AM
To: dev@daffodil.apache.org 
Subject: Suspensions and NewVariableInstance

I've been running into a lot of headaches trying to get newVariableInstance to 
correctly handle suspensions.  Currently when a newVariableInstance statement 
is found, a NewVariableInstanceStart and End unparsers are created. 
NewVariableInstanceStart will immediately create the newVariableInstance with 
no value and, if applicable, will create a SuspendableExpression that will 
calculate the default value. This works as expected but as the NVI's go out of 
scope we start running into some issues.

The NewVariableIsntanceEnd unparser simply removes the variable instance that 
was created in NVIStart.  It is not performing or checking for any sort of 
suspension, so NVIEnd is called while the NVIStart suspension is still active. 
Since the UStateForSuspension object uses the same VariableMap as the main 
UState object, this results in the variable's value not being correct after it 
goes out of scope.

I'm not sure what a good solution for this would be.  I've attempted adding a 
SuspendableOperation to the NVIEnd unparser to wait until the variable has a 
value before removing, but this results in a SuspensionDeadlock.  I've also 
attempted doing a deep copy of all the variables for each UStateForSuspension 
object, but this too results in a SuspensionDeadlock, not to mention that any 
changes made in one suspension wouldn't be visible to other suspensions.  One 
other thought I had, which I'm not even sure would even address the suspension 
issue, is to have whatever sequence is containing the NVI statement handle 
calling the NVIEnd unparser by simply adding it to the end of its sequence 
child unparsers.

Any thoughts on how best to handle this sticky situation of dealing with 
newVariableInstance and unparsing suspensions?


Suspensions and NewVariableInstance

2021-02-02 Thread Adams, Joshua
I've been running into a lot of headaches trying to get newVariableInstance to 
correctly handle suspensions.  Currently when a newVariableInstance statement 
is found, a NewVariableInstanceStart and End unparsers are created. 
NewVariableInstanceStart will immediately create the newVariableInstance with 
no value and, if applicable, will create a SuspendableExpression that will 
calculate the default value. This works as expected but as the NVI's go out of 
scope we start running into some issues.

The NewVariableIsntanceEnd unparser simply removes the variable instance that 
was created in NVIStart.  It is not performing or checking for any sort of 
suspension, so NVIEnd is called while the NVIStart suspension is still active. 
Since the UStateForSuspension object uses the same VariableMap as the main 
UState object, this results in the variable's value not being correct after it 
goes out of scope.

I'm not sure what a good solution for this would be.  I've attempted adding a 
SuspendableOperation to the NVIEnd unparser to wait until the variable has a 
value before removing, but this results in a SuspensionDeadlock.  I've also 
attempted doing a deep copy of all the variables for each UStateForSuspension 
object, but this too results in a SuspensionDeadlock, not to mention that any 
changes made in one suspension wouldn't be visible to other suspensions.  One 
other thought I had, which I'm not even sure would even address the suspension 
issue, is to have whatever sequence is containing the NVI statement handle 
calling the NVIEnd unparser by simply adding it to the end of its sequence 
child unparsers.

Any thoughts on how best to handle this sticky situation of dealing with 
newVariableInstance and unparsing suspensions?