||FraOrolo, jeff.allen, zyasoft
|Marked as misclassified
I have been playing with competing threads, guiding them step by step to see if I can make one trip up the other. In the process, I decided to check my understanding of ClassValue. It is as I thought, although I've never watched it work before.
I see a problem in the fact, that there is no control for insertion into the classValue. I'm feeling unsure about the fact that multiple threads will re-create the PyType wrapping, because they are waiting in front of the lock and do not check if the first import and wrapping was successful.
But in principle this should be fine, just more PyJavaType wrappings are created.
Recall I am importing javax.swing.text.Utilities, and so Jython will make a PyJavaType to represent its class.
I let Thread-1 call PyType.fromClass() and stopped it in PyType$Registry.resolveType(). This means it has come through ClassValue.get(), missed in the cache, and called computeValue(). I then let Thread-3 do the same, and observed it blocked in computeValue(). I let Thread-1 return through ClassValue.get(), which means the cache in the ClassValue is filled for Utilities. This is too late for Thread-3, which proceeds to construct a second PyJavaType to represent Utilities. On the return journey through ClassValue, Thread-3 fails to insert its result in the cache, and is forced to repeat. This time, it picks up PyJavaType that Thread-1 inserted, so both refer to the same type object, with same Java object id: marvellous!
Thread-3 did work and it became garbage immediately, but this is the price of the non-blocking mechanism we have in ClassValue. The creation of type objects must, however, be idempotent as far as the rest of the process state is concerned. (I think it is.)
Now, let's see if I can trick them into a different error ...
|2019-12-26 12:24:32||jeff.allen||set||messageid: <email@example.com>|
+ jeff.allen, zyasoft, FraOrolo|
|2019-12-26 12:24:32||jeff.allen||link||issue2834 messages|