On Tue, Sep 4, 2012 at 11:57 PM, Roland Mainz <roland.ma...@nrubsig.org> wrote:
> Hi!
> ----
> [Just some follow-up to the recent discussion]
> Question is: Why do we want a per-thread cwd ? Is it useful ?
> AFAIK the arguments are:
> * Pro:
> - Moving the cwd from global to a pre-thead makes it easier to
> implement thread support for existing applications
> <any more arguments ?>
> * Contra:
> - The per-thread cwd is locked on the current thread. Moving objects
> relying on this per-thread cwd to another thread (e.g. job "borrowing"
> or forwarding) is not possible unless we alter that's thread cwd
> (which means we have the same kind+class of problems we tried to solve
> when we tried to get rid of the global cwd)
> - The per-thread cwd is only known to libast... any other API will not
> be aware of this (Glenn: Can this we resolved by compiling existing
> libraries against the libast headers ?)
> Finally: Wouldn't it be a better solution to drop the notion of a
> global or per-thread cwd _COMPLETELY_ and let the applications and
> APIs themselves handle this... with as many dirfd's they want ? The
> idea would be that all APIs which currently rely on global resources
> like { cwd, umask, environ } get this information passed as arguments
> instead of relying on the global versions (we already see this
> movement in POSIX with the introduction of the |*at()|-APIs in XPG7 or
> newer additions like
> |posix_spawnattr_setfchdir()|/|posix_spawnattr_setenviron()|/|fexecve()|
> etc. ...) ?

Roland, your analysis is wrong.

A global cwd or per thread cwd is a resource which has to be shared
between objects. The problem is that they have to *share* it
All problems listed in this list or known to me so far have their root
in the unprotected, implicit sharing, and the results of unintended
changes, i.e. one object does a change which other objects are not
aware of. Multithreading and the concurrency of access is cited very
often, but it's only a specialized symptom of the more general problem
of implicit sharing.

So the question is: Does a per thread cwd solve the problem of
unprotected and implicit sharing of the cwd? The answer is a clear NO,
not even with IMO or IMHO.
It's just an idiotic attempt to bump legacy apis to the age of
threads, but without solving the right problem or even try to ask the
right question.
A per thread cwd does at least not solve the problem that objects
share this cwd implicitly and can still interact in unintended ways.

The right solution is: Stop the implicit sharing, and start explicit
sharing, or do not share at all.

For an api this means: Stop using the global cwd, and start passing a
fd to the base directory you'd like to work in as an argument.  For
example glob() needs to be extended to add a gl_dirfd field to pass
the base dir fd, a void *(*gl_fdopendir) (__const char *); to provide
a pointer to fdopendir() (opendir() will operate on strings and a not
directory fd). After that change glob() can operate completely
independent of the global cwd, and even nested calls of glob() within
glob() no longer pose a problem.

You also have to start thinking about apis as *objects* (and not
threads or processes) and that these objects have to work relative to
a base directory. For example a glob_t is a object, Shell_t is an
object, a relative path is an object, and so on. They all work
relative to a base directory fd, implicitly or explicitly.
Our goal should be to make it always explicitly - the notation of a
global cwd or per thread cwd is just in the way of that (correct)

ast-developers mailing list

Reply via email to