apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Florian Weimer ...@deneb.enyo.de>
Subject Re: 1.6 release timetable
Date Sat, 25 Mar 2017 12:34:43 GMT
* Yann Ylavic:

>> readdir is thread-safe.  There used to be this idea that fdopendir
>> could be implemented like this:
>>
>> DIR *
>> fdopendir (int fd)
>> {
>>   return (DIR *) fd;
>> }
>>
>> And readdir would use a static buffer for the directory entry (like
>> gethostbyname) instead of something which is allocated as part of the
>> opaque the DIR * object (similar to a FILE *).  Such systems may
>> indeed have existed at one point, but I doubt that you can compile APR
>> on them.  It's unlikely that these systems will support readdir_r
>> because it is much to recent an interface.
>
> Right, modern readdir()s seem to be thread-safe but with regard to
> different directories only, at least Linux' man page states:
>         "In the current POSIX.1 specification (POSIX.1-2008),
> readdir() is not required to be thread-safe.  However, in modern
> implementations (including the glibc implementation), concurrent calls
> to readdir() that specify different directory streams are thread-safe.
> In cases where multiple threads must read from the same directory
> stream, using readdir() with external synchronization is still
> preferable to the use of the  deprecated readdir_r(3) function.  It is
> expected that a future version of POSIX.1 will require that readdir()
> be thread-safe when concurrently employed on different directory
> streams."

It's been a bit of a struggle to get this right.  People are really
concerned about the case where multiple threads read from the same
directory stream.  But how often does that happen in practice?

>> For systems which use a buffer embedded in the DIR * object (and I'm
>> not aware of any which don't), readdir is as thread-safe as memcpy,
>> although some manual pages claim it is not.  This is very likely an
>> editorial mistake because thread safety guarantees for functions which
>> operate on separate objects are still an evolving concept.
>
> Are you thinking of the above editorial?

I meant this part:

  Preliminary: | MT-Unsafe race:dirstream | AS-Unsafe lock | AC-Unsafe
    lock | See POSIX Safety Concepts.

<https://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html>

“MT-Unsafe race:dirstream” doesn't make much sense because we don't
have this as a category for memcpy because for some reason, it is
“obvious” for memcpy that it's only thread-safe if it is called for
completely separate arguments.

I think the Solaris manual also does not mark readdir as thread-safe,
implicitly suggesting to use readdir_r in multi-threaded programs.
But this suggestion isn't helpful on Solaris, either.

>> Just stop using readdir_r.  I know that many people are invested in
>> that interface for various reasons, but sometimes, you just have to
>> delete pointless code and get on with it.
>
> I'm not sure we can use readdir() blindy though, what if multiple
> threads use it on the same dir?

Then the current implementation is already broken because apr_dir_read
does not perform any locking: The call to readdir_r can write to the
d_name buffer, and the reads of the d_name in apr_dir_read constitute
a data race.

If you mean “the same directory on the file system”: What counts is
the same DIR * object.  If two objects iterate through the same
directory, this does not matter because each DIR * object is required
to keep its own iteration position.

Mime
View raw message