This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author neologix
Recipients greg.ath, neologix, pitrou, vstinner
Date 2011-06-25.17:10:03
SpamBayes Score 1.2267964e-13
Marked as misclassified No
Message-id <BANLkTikTDeHUxsKP_UCn13sYFjqm0PMqeg@mail.gmail.com>
In-reply-to <1308654176.69.0.733792484541.issue12352@psf.upfronthosting.co.za>
Content
Patch (with test) attached. It disables the garbage collector inside
critical sections.
Of course, if another thread re-enables the gc while the current
thread is inside a critical section, things can break (the probability
is really low, but who knows).
I can't think of any satisfying solution, since it's tricky, because
we don't want it to be thread-safe but reentrant, which is much more
difficult.
I've got another patch which does the following:
- in free(), perform a trylock of the mutex
- if the trylock fails, then create a new Finalizer to postpone the
freeing of the same block to a later time, when the gc is called
- the only problem is that I have to build a dummy reference cycle to
pass it to Finalize if I want free() to be called by the GC later (and
not when the object's reference count drops to 0, otherwise we would
get an infinite recursion).

Another solution would be to make the Finalizer callback run lockless,
maybe just set add the block number to a list/set, and perform the
freeing of pending blocks synchronously when malloc() is called (or
the heap is finalized). There are two drawbacks to that:
- adding an element to a set is not guaranteed to be thread-safe
(well, it is under cPython because of the GIL)
- freeing blocks synchronously means that the blocks won't be freed
until malloc() is called (which could be never)

Suggestions welcome.
History
Date User Action Args
2011-06-25 17:10:04neologixsetrecipients: + neologix, pitrou, vstinner, greg.ath
2011-06-25 17:10:03neologixlinkissue12352 messages
2011-06-25 17:10:03neologixcreate