Author rhettinger
Recipients JohanAR, davin, gvanrossum, itamarst, ncoghlan, pitrou, python-dev, rhettinger, sbt, serhiy.storchaka, tim.peters, yselivanov, zzzeek
Date 2017-08-25.05:07:07
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1503637628.61.0.960177042502.issue14976@psf.upfronthosting.co.za>
In-reply-to
Content
[Antoine Pitrou]
> So perhaps we need C code after all.

This matches my experience with functools.lru_cache() where I used an RLock() to handle reentrancy.  That by itself was insufficient.  I also had to make otherwise unnecessary variable assignments to hang onto object references to avoid a decref triggering arbitrary Python code from reentering before the links were all in a consistent state.   Further, I had to create a key wrapper to make sure a potentially reentrant __hash__() call wouldn't be made before the state was fully updated.  Even then, a potentially reentrant __eq__() call couldn't be avoided, so I had to re-order the operations to make sure this was the last call after the other state updates.  This defended against all normal code, but all these measures still could not defend against signals or a GC invocation of __del__, either of which can happen at any time.

On the plus side, we now have a C version of functools.lru_cache() that is protected somewhat by the GIL.  On the minus side, it was hard to get right.  Even with the pure python code as a model, the person who wrote the C code didn't fully think through all sources of reentrancy and wrote buggy code that shipped in 3.5 and 3.6 (resulting in normal code code triggering hard-to-reproduce reentrancy bugs).  The lesson here is that while the C code can be written correctly, it isn't easy to do and it is hard to notice when it is incorrect.

One other thought:  Given that __del__() can be invoked at almost any time and can potentially call any other piece of Python code, we should consider turning every lock into an rlock.  Also, there should be some guidance on __del__() advising considerable restraint on what gets called.  The world is likely full of pure Python code that can't defend itself against arbitrary re-entrancy.
History
Date User Action Args
2017-08-25 05:07:08rhettingersetrecipients: + rhettinger, gvanrossum, tim.peters, ncoghlan, pitrou, zzzeek, python-dev, sbt, serhiy.storchaka, JohanAR, yselivanov, itamarst, davin
2017-08-25 05:07:08rhettingersetmessageid: <1503637628.61.0.960177042502.issue14976@psf.upfronthosting.co.za>
2017-08-25 05:07:08rhettingerlinkissue14976 messages
2017-08-25 05:07:07rhettingercreate