From: Rainer Weikusat on
David Given <dg(a)cowlark.com> writes:
> On 19/04/10 20:39, Rainer Weikusat wrote:
> [...]
>> Yes. The actual solution is still (and will remain forever): DO NOT DO
>> THIS. This cannot be that complicated, can it?
>
> So, basically, you're saying, don't use fopen()?

I am hard-pressed to try a reply in simplified kindergarten language
here, but I am not entirely certain if you didn't perhaps honestly
misinterprete my text completely. See, if you desire to change the
default policy, it is necessary that you have sufficient control of
your environment to actually change the policy without 'something' you
don't control causing the yet unchanged default policy to be
applied. The environment we are "discussing" here has been carefully
defined as to offer no opportunity for changing the default policy,
consequently, the default policy cannot be changed.

How do you proprose to deal with a multithreaded library which remaps
the text segment of your application with r/w permission and
overwrites your code with one million copies of "Oft glaubt der
Mensch, wenn er nur Worte hoert, es muesse sich dabei doch auch was
denken lassen" (Goethe, Faust I)?

[...]

> We all know that the default for close-on-exec is wrong;

That's your opinion on this topic. Apparently, the opinion of the
people who designed the interface was different. My opinion on this
topic, being a completely pragmatic person with no desire to
evangelize in favor of the one true someone's way is that "whatever the
default happens to be, it will be inconvenient in some situations".
From: Geoff Clare on
David Given wrote:

> My understanding of the problem is that *any* call to fopen(), in a
> multithreaded application, may result in a leaked file descriptor
> (because even if the caller to fopen() remembers to call
> fcntl(fileno(fp), F_SETFD, FD_CLOEXEC) afterwards, there's still a
> window whereby another thread calling fork() might propagate the file
> descriptor).
>
> Is this correct?
>
> If so, is there any actual solution? Because fopen() is not going to go
> away.

Here are three possible solutions:

1. Instead of using fopen(), use open() with O_CLOEXEC and then
fdopen() to get a stream from the file descriptor. Obviously
this is only portable to systems that provide O_CLOEXEC, but
O_CLOEXEC has been mandated by POSIX since 2008.

2. Fork before creating any threads. Then later on tell the
child what to do (via IPC) instead of forking at that point.
(The child can safely fork another child to do the work if
necessary.) Obviously this requires cooperation from the other
threads that would have called fork(), so it may not be possible
when using 3rd party libraries.

3. Use a mutex to ensure fork() cannot be called concurrently
with fopen(). Again this requires cooperation.

--
Geoff Clare <netnews(a)gclare.org.uk>


From: William Ahern on
Jonathan de Boyne Pollard <J.deBoynePollard-newsgroups(a)ntlworld.com> wrote:
> [-- text/html, encoding 7bit, charset: ISO-8859-1, 67 lines --]

No doubt Windows has myriad techniques and devices for handling thread
issues. In fact, some of them clearly aren't resolvable. Windows Vista seems
to terminate a process which has a thread which tries to access a critical
section left inconsistent by ExitProcess terminating another thread!

If these are arguments for how things should be done in Unix, they strongly
suggest circumscribing the unstructured use of threads in Unix, and heaping
scorn on libraries and their developers that do stupid things.

Unix has a long tradition of implementing solutions through wetware, rather
than software or hardware. This is why there is so much opprobium on this
and similar Unix groups, which Windows developers chafe at. This thread is a
case in point.

It's also not unrelated to the fact that access to source code, even for
proprietary platforms, has always been much easier than on Windows. It's a
reasonable proposition to fix bugs rather than work around them. This tact
isn't acceptable in the "corporate" world. But consider that Unix libraries
aren't as often commercial products--libc a notable exception--unlike in
Windows, and we're of course speaking of libraries. Windows provids the
canonical XML parser, but in Unix you use libxml2 or something similar.

Similarly, system-level "solutions" are more difficult in Unix, because
portability across implementations is more highly valued, and unless a
solution is clearly a winner it will never be widely adopted by vendors or
users. This arguably results in evolutionarily stronger solutions, but in
the short-term leaves more gaps to be handled ad hoc--burdensome but IMO
acceptable as long nothing else precludes you from solving the problem.

This is also related to theories of software composition. Windows developers
often balk at the inefficiency of poll()+read() versus Windows' completion
ports. But poll()+read() are far more composable than completion ports.
They're moderately less efficient and yet almost infinitely more
composable--relative to being forced into a threaded, reentrant model. Unix
culture has always been more conservative and protective of unrestricted
composition of primitives than Windows culture. (The uglier Unix interfaces
are ugly by this measure in particular--and it's why most people in this
thread aren't much bothered by the descriptor "leaking" issue; it's not ugly
by this measure). That's not necessarily a judgment one way or another, just
the way it is.

From: David Given on
On 19/04/10 03:31, Joshua Maurice wrote:
[...]
> It's kind of difficult to do
> what you suggest in the real world for general purpose libraries, both
> users and writers.

My understanding of the problem is that *any* call to fopen(), in a
multithreaded application, may result in a leaked file descriptor
(because even if the caller to fopen() remembers to call
fcntl(fileno(fp), F_SETFD, FD_CLOEXEC) afterwards, there's still a
window whereby another thread calling fork() might propagate the file
descriptor).

Is this correct?

If so, is there any actual solution? Because fopen() is not going to go
away.

--
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────

│ "In the beginning was the word.
│ And the word was: Content-type: text/plain" --- Unknown sage
From: Rainer Weikusat on
David Given <dg(a)cowlark.com> writes:
> On 19/04/10 03:31, Joshua Maurice wrote:
> [...]
>> It's kind of difficult to do
>> what you suggest in the real world for general purpose libraries, both
>> users and writers.
>
> My understanding of the problem is that *any* call to fopen(), in a
> multithreaded application, may result in a leaked file descriptor
> (because even if the caller to fopen() remembers to call
> fcntl(fileno(fp), F_SETFD, FD_CLOEXEC) afterwards, there's still a
> window whereby another thread calling fork() might propagate the file
> descriptor).
>
> Is this correct?
>
> If so, is there any actual solution?

Yes. The actual solution is still (and will remain forever): DO NOT DO
THIS. This cannot be that complicated, can it? Since executing fork
will create a new process running the same program with much of the
environment of the old process inherited, insofar parts of the
environment which would otherwise be inherited must not be transferred
across a fork (possibly followd by an exec), the only way to do so is
to either (temporarily) modify the original environment before
fork or adjust the inherited environment after fork. There is no other
way.

The much more interesting question (as compared to 'is there any
actual solution') would be 'Is there any actual problem', that is, a
real-world situation which does not include the generous assumption
that 'unknown and buggy code which exists only in binary form is going
to be executed as part of the forking process'. Because, as soon as
you assume that "the software doesn't work", you'll obviously get just
that (software doesn't work) by definition (and discussing this is as
obviously useless).

BTW, given that the DRAMs usually used in PCs are known to be
inherently unreliable, is their any way to program a computer at all?

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10
Prev: Kill process tree, again
Next: ANN: Seed7 Release 2010-04-18