One-time Construction API (3.3.2)

Jason Merrill jason at redhat.com
Wed Aug 4 22:24:07 UTC 2004


I'm working on using this stuff in g++, and finding it rather unwieldy,
primarily because if construction of the object throws, we need to call
__cxa_guard_abort, but if destruction of any temporaries throws, we need to
call __cxa_guard_release.  To make this work, we need to do something like

if (__cxa_guard_acquire (&guard))
  {
    bool flag = false;
    try
      {
        /* initialize */, flag = true, __cxa_atexit (dtor);
      }
    finally
      {
        if (flag)
          __cxa_guard_release (&guard);
        else
          __cxa_guard_abort (&guard);
      }
  }

The flag is necessary to avoid non-nested overlapping EH regions.  It would
have been simpler to have one function that takes the flag as an argument.

Also, 2.8 refers to "the first byte", while 3.3.2 refers to "the low-order
byte".  These are the same on little-endian targets, but not big-endian.

I've been thinking about how to implement the actual locking, and the best
I've come up with is to have the guard be an index into an array of mutexes
(or mutex pointers), with magic values for uninitialized and "creating
mutex"; in the latter case another thread that comes to it should just spin
until it takes on another value.

Has anyone actually implemented this?

Jason



More information about the cxx-abi-dev mailing list