You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The JNI reference count assertions in
JniRuntime.JniObjectReferenceManager were "off," in that the values
they were asserting didn't actually make sense.
Previous logic for JNI local reference create + destroy:
// Assume localReferenceCount starts at 0, because of course it does
Assert (localReferenceCount >= 0); // True; 0 >= 0
localReferenceCount++; // localReferenceCount == 1
...
Assert (localReferenceCount >= 0); // True; 1 >= 0
localReferenceCount--; // localReferenceCount == 0
The problem with this logic is that it doesn't actually make sense;
when localReferenceCount is incremented to 1, there is one reference
in existence; conceptually, then, the created reference *is* #1.
Meanwhile, at *cleanup*, we first check that localReferenceCount is
valid, *before* we decrement it. We're not validating that e.g.
reference "#1" has been destroyed, or that the number of outstanding
references *after* cleanup is identical to what existed *before* it
was created.
In short, the "dispose" check is in the wrong place. It should be done
*after* decrementing the count, not before:
Assert (localReferenceCount >= 0); // True; 0 >= 0
localReferenceCount++; // localReferenceCount == 1
...
localReferenceCount--; // localReferenceCount == 0
Assert (localReferenceCount >= 0); // True; 0 >= 0
This dovetails nicely with LoggingJniObjectReferenceManagerDecorator
behavior, in that the logging should follow the same pattern as the
count updating: log after create, before delete. If/when reference
lifetimes are entirely nested and not overlapping, this allows for
lrefc value "1" on create to have the same lrefc value "1" on destroy.
0 commit comments