[Python-bugs-list] [Bug #115076] threads of __del__

noreply@sourceforge.net noreply@sourceforge.net
Fri, 22 Sep 2000 03:27:24 -0700


Bug #115076, was updated on 2000-Sep-22 02:15
Here is a current snapshot of the bug.

Project: Python
Category: Core
Status: Open
Resolution: None
Bug Group: None
Priority: 5
Summary: threads of __del__

Details: I suspect (but have not proved) that the support for destroying deeply recursive structures can allow for an instances __del__ method to get called in a thread other than the one in which it lost its last reference.

This can happen if it switches to a different thread during deletion of a deeply recursive structure (with _PyTrash_delete_later not empty). 

Should Python guarantee that this does not happen? (I say yes - it is important for COM clients)

Follow-Ups:

Date: 2000-Sep-22 02:52
By: gvanrossum

Comment:
Agreed that this would be a problem if it could cause an inconsistent state of the trashcan (at the end of object.c) structure. However, since the "trash" code is all executed with the global interpreter lock held, I don't see that there can be a problem. Here's why:

The code in _PyTrash_deposit_object() doesn't make any calls that could invoke __del__, so it's safe. The code in _PyTrash_destroy_chain() makes exactly one call to Py_DECREF(), but it takes care that its global data structures are consistent at this point. For a second I thought that _PyTrash_delete_later would have to be declared volatile, but on second thought I don't: the Py_DECREF() macro expands to a possible (indirect) function call, signaling the compiler that the global _PyTrash_delete_later may be changed in arbitrary ways.

Assigned to Tim Peters to verify my reasoning, because of his superior mind in reasoning about threads and race conditions.
-------------------------------------------------------

Date: 2000-Sep-22 03:05
By: htrd

Comment:
I agree there is no self-consistency problem with the trashcan, however......

The code in _PyTrash_destroy_chain can call an objects __del__ method, which can release the interpreter lock.

A second thread may then reenter _PyTrash_destroy_chain and continue to clean up the first thread's garbage. (the first thread is safely blocked inside the Py_DECREF)

Yes the garbage gets cleaned up, however it happens in the wrong thread.

I suggest that _PyTrash_delete_later should be part of pyThreadState



-------------------------------------------------------

Date: 2000-Sep-22 03:08
By: gvanrossum

Comment:
And why, exactly, would it be a problem that the trash is deleted in the 'wrong" thread? It's just trash. Any thread can delete it.

Or am I missing something?
-------------------------------------------------------

Date: 2000-Sep-22 03:27
By: htrd

Comment:
There are two cases that I have in mind:

First is that of a COM client.

It depends on the COM threading model in use, but this problem applies in the most common threading model which is also the default threading model using Mark Hammond's pythoncom.

It is only permitted to access a reference to a COM object from the thread in which it is created. This restiction applies to the Release() method that is used by pythoncom to release its reference to the COM server.


Secondly, it is common to use a dictionary keyed by thread.get_ident() to provide thread-local storage. This is used extensively in Zope. Any application that uses this type of thread-local storage in a __del__ is likely to be broken.



-------------------------------------------------------

For detailed info, follow this link:
http://sourceforge.net/bugs/?func=detailbug&bug_id=115076&group_id=5470