Ben Pfaff <[EMAIL PROTECTED]> writes: > The issue at hand, as I understand it, is not even the general > behavior of signals. It is the behavior of fatal signals. That > is, a the program terminates without ever returning from the > signal handler. This is much simpler than the general problem
Yes, good point; it is simpler. However, my impression is that the new module's cleanup function is intended to be callable even from non-fatal signal handlers, so I don't think we have the simpler case here. But for now let's concentrate on the simpler case. > However, I believe that if the assignment in main were changed to > the following, then the signal handler would be guaranteed to see > 1 in x if the signal arrived in getchar; > *(sig_atomic_t volatile *) &x = 1; OK, so it sounds like your idea is that, if all accesses to an object are via a volatile lvalue, then the object is volatile, even if it was not originally defined to be a volatile object. This idea has an intuitive appeal, though I submit that it does not follow from the standard; the standard does not explicitly specify or even suggest this "all accesses" rule. A problem I see with this idea is 6.7.3.(6), which says "An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects." So a volatile object (I assume this is the same as "an object that has volatile-qualified type" in your model?) can spontaneously change, for reasons unknown to and outside the control of the program; this point is underlined later in the paragraph. But if all accesses to a humdrum "static int x;" object are via volatile lvalues, and if that means "x" is a volatile object, doesn't this also mean "x" might spontaneously change? One way out of this mess would be to say that we are making an extra assumption, not present in the standard, that volatile objects do not spontaneously change and that they have no unknown side effects. To some extent we must make this assumption anyway, or we'll get nowhere. Still, 6.7.3.(6) makes it clear (at least to me) that "volatile" is intended more for describing access to memory-mapped device registers, and wasn't really intended for use in safe signal handling or multithreading. There is also the huge escape clause at the end of 6.7.3.(6): "What constitutes an access to an object that has volatile-qualified type is implementation-defined." Ouch! Talk about getting run over by an express train! Anyway, to get back to the original module, it seems to me that the code actually is assuming something quite a bit different from what 'volatile' provides. The code is attempting to do use loads and stores as barriers to prevent the usual sorts of bugs with signal handling. But 'volatile' is not designed to handle this problem: volatile accesses are not guaranteed to be atomic. There has been quite a bit of effort in the C++ community recently to add support for atomic operations; see the cpp-threads mailing list <http://www.decadentplace.org.uk/pipermail/cpp-threads/>. The latest proposal is H.-J. Boehm's WG21/N2047 J16/06-0117 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2047.html> (2006-06-24). It contains a C API, and indicates the sort of problems that people run into with real hardware (albeit not limiting themselves to signal-handler problems), but this stuff is still very much in a state of flux. > Perhaps all this is moot because Bruno's > module does not actually contain any casts to volatile. But the module contains casts to types like "struct tempdir * volatile *", e.g.: struct tempdir * volatile *new_array = (struct tempdir * volatile *) xmalloc (new_allocated * sizeof (struct tempdir * volatile)); and this raises the issue we've been talking about (what I've been calling "volatile objects" versus "volatile lvalues"). And the point wouldn't be moot even if the module had no casts, because you can convert e.g., "void *" to "int volatile *" in C without a cast. My example in <http://lists.gnu.org/archive/html/bug-gnulib/2006-07/msg00062.html> relies on this sort of thing: it has no casts but does have the problem.