[cxx-abi-dev] Adding __cxa_thread_atexit() to the C++ ABI?
Matthew Dempsky
matthew at dempsky.org
Wed May 7 17:15:33 UTC 2014
On Sun, Apr 27, 2014 at 11:14 PM, John McCall <rjmccall at apple.com> wrote:
> Yes, preparing a proposal would be great. Please send it here,
> though, not as a push request to github.
Okay, here's my first stab at this. Feedback welcome.
diff --git a/abi.html b/abi.html
index bdd8476..b46c398 100644
--- a/abi.html
+++ b/abi.html
@@ -3786,8 +3786,8 @@ All references are via the API described below.
<p>
<li> Object construction:
<p>
-After constructing a global (or local static) object,
-that will require destruction on exit,
+After constructing an object with static storage duration,
+that will require destruction on process exit,
a termination function is <i>registered</i> as follows:
<center><code>
extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d );
@@ -3801,6 +3801,29 @@ It returns zero if registration is successful,
nonzero on failure.
The registration function is not called from within the constructor.
<p>
+<li> Thread-local object construction:
+<p>
+After constructing an object with thread storage duration,
+that will require destruction on process or thread exit,
+a thread-local termination function is <i>registered</i> as follows:
+<center><code>
+extern "C" int __cxa_thread_atexit ( void (*f)(void *), void *p, void *d );
+</code></center>
+This registration, e.g. <code>__cxa_thread_atexit(f,p,d)</code>,
+is intended to cause the call <code>f(p)</code> when the calling
thread terminates
+(e.g. by returning from its initial function or calling
<code>std::exit</code>),
+before all such thread-local termination calls registered before this one.
+It returns zero if registration is successful, nonzero on failure.
+
+<p>
+The registration function is not called from within the constructor.
+Additionally, the registration increments the reference count for DSO
<code>d</code>.
+
+<p>
+The thread-local termination function is called from the same thread
that registered it.
+After <code>f(p)</code> returns, the reference count for DSO
<code>d</code> is decremented.
+
+<p>
<li> User <code>atexit</code> calls:
<p>
When the user registers exit functions with <code>atexit</code>,
@@ -3819,12 +3842,13 @@ with a parameter or a home DSO.
<p>
<li> Termination:
<p>
-When linking any DSO containing a call to <code>__cxa_atexit</code>,
+When linking any DSO containing a call to <code>__cxa_atexit</code>
or <code>__cxa_thread_atexit</code>,
the linker should define a hidden symbol <code>__dso_handle</code>,
with a value which is an address in one of the object's segments.
(It does not matter what address,
as long as they are different in different DSOs.)
-It should also include a call to the following function in the FINI
+Additionally, DSOs that contain a call to <code>__cxa_atexit</code>
+should also include a call to the following function in the FINI
list (to be executed first):
<center><code>
extern "C" void __cxa_finalize ( void *d );
@@ -3851,7 +3875,9 @@ the implementation may either remove entries or
mark them finished.
<p>
When the main program calls <code>exit</code>,
-it must call any remaining <code>__cxa_atexit</code>-registered functions,
+it must first call any <code>__cxa_thread_atexit</code>-registered functions
+for the exiting thread.
+Next, it must call any remaining <code>__cxa_atexit</code>-registered
functions,
either by calling <code>__cxa_finalize(NULL)</code>,
or by walking the registration list itself.
@@ -3863,8 +3889,8 @@ in the opposite of the order in which they were
enqueued by
</ol>
<p>
-Since <code>__cxa_atexit</code> and <code>__cxa_finalize</code>
-must both manipulate the same termination function list,
+Since calls to <code>__cxa_atexit</code>,
<code>__cxa_thread_atexit</code>, and <code>__cxa_finalize</code>
+must manipulate the same termination function lists,
they must be defined in the implementation's runtime library,
rather than in the individual linked objects.
More information about the cxx-abi-dev
mailing list