Py_BEGIN_ALLOW_THREADS around readdir()?

Currently, the readdir() call releases the GIL. I believe this is not thread-safe, because readdir() does not need to be re-entrant; we should use readdir_r where available to get a thread-safe version. Comments? Regards, Martin

On 17-apr-2006, at 18:19, Martin v. Löwis wrote:
Currently, the readdir() call releases the GIL. I believe this is not thread-safe, because readdir() does not need to be re-entrant; we should use readdir_r where available to get a thread-safe version.
Comments?
AFAIK readdir is only unsafe when multiple threads use the same DIR* at the same time. The spec[1] seems to agree with me. It seems to me that this means the implementation of listdir in posixmodule.c doesn't need to be changed. Ronald [1] : http://www.opengroup.org/onlinepubs/009695399/functions/ readdir.html
Regards, Martin _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ ronaldoussoren%40mac.com

Ronald Oussoren wrote:
AFAIK readdir is only unsafe when multiple threads use the same DIR* at the same time. The spec[1] seems to agree with me. [1] : http://www.opengroup.org/onlinepubs/009695399/functions/readdir.html
What specific sentence makes you think so? I see "The readdir() interface need not be reentrant." which seems to allow for an implementation that returns a static struct dirent. Of course, the most natural implementation associates the storage for the result with the DIR*, so it's probably not a real problem... Regards, Martin

On 17-apr-2006, at 20:50, Martin v. Löwis wrote:
Ronald Oussoren wrote:
AFAIK readdir is only unsafe when multiple threads use the same DIR* at the same time. The spec[1] seems to agree with me. [1] : http://www.opengroup.org/onlinepubs/009695399/functions/ readdir.html
What specific sentence makes you think so? I see
"The readdir() interface need not be reentrant."
which seems to allow for an implementation that returns a static struct dirent.
A couple of lines down it says: "The pointer returned by readdir() points to data which may be overwritten by another call to readdir() on the same directory stream. This data is not overwritten by another call to readdir() on a different directory stream." This explicitly says that implementations cannot use a static dirent structure.
Of course, the most natural implementation associates the storage for the result with the DIR*, so it's probably not a real problem...
If this were a problem on some platform I'd expect it to be so ancient that it doesn't offer readdir_r either. Ronald

Ronald Oussoren wrote:
A couple of lines down it says: "The pointer returned by readdir() points to data which may be overwritten by another call to readdir() on the same directory stream. This data is not overwritten by another call to readdir() on a different directory stream."
This explicitly says that implementations cannot use a static dirent structure.
Ah, right. I read over this several times, and still managed to miss that point. Thanks.
Of course, the most natural implementation associates the storage for the result with the DIR*, so it's probably not a real problem...
If this were a problem on some platform I'd expect it to be so ancient that it doesn't offer readdir_r either.
Sure - I would have just removed Py_BEGIN_ALLOW_THREADS on systems which don't have readdir_r. But this is now unnecessary. Regards, Martin
participants (2)
-
"Martin v. Löwis"
-
Ronald Oussoren