The _PyPclose fix looks good, Tim!
The sad thing is that if they had implemented their own data structure
to keep track of the mapping between files and processes, none of this
would have been necessary. Look:
_PyPopenProcs is a dictionary whose keys are FILE* pointers wrapped in
Python longs, and whose values are lists of length 2 containing a
process handle and a file count. Pseudocode:
# global:
_PyPopenProcs = None
# in _PyPopen:
global _PyPopenProcs
if _PyPopenProcs is None:
_PyPopenProcs = {}
files = <list of files created>
list = [process_handle, len(files)]
for file in files:
_PyPopenProcs[id(file)] = list
# in _PyPclose(file):
global _PyPopenProcs
list = _PyPopenProcs[id(file)]
nfiles = list[1]
if nfiles > 1:
list[1] = nfiles-1
else:
<wait for the process status>
del _PyPopenProcs[id(file)]
if len(_PyPopenProcs) == 0:
_PyPopenProcs = None
This expands to pages of C code! There's a *lot* of code dealing with
creating the Python objects, error checking, etc. I bet that it all
would become much smaller and more readable if a custom C-based data
structure was used. A linked list associating files with processes
would be all that's needed. We can even aford a linear search of the
list to see if we just closed the last file open for this process.
Sigh. Maybe for another time.
(That linked list would require a lock of its own. Fine.)
--Guido van Rossum (home page: http://www.pythonlabs.com/~guido/)