On Sunday, 24 January 2021 at 00:24:55 UTC, Ali Çehreli wrote:
One question I have is, does rt_init already do
thread_attachThis? I ask because I have a library that is
loaded by Python and things work even *without* calling
thread_attachThis.
During rt_init in the main thread, thread_attachThis is performed
what I have seen.
Another question: Are TLS ctors executed when I do loadLibrary?
And when they are executed, which modules are involved? The
module that is calling rt_moduleTlsCtor or all modules? What
are "all modules"?
The TLS standard (at least the ELF standard) does not have ctors.
Only simple initialization are allowed meaning the initial data
is stored as .tdata which is copied to the specific memory area
for each thread. There is also a .tbss which is zero memory just
like the .bss section. Actual ctor code that runs for each TLS
thread is language specific and not part of the ELF standard
therefore no such TLS ctor code are being run in the lower level
API. The initialization (only copy and zeroing) of TLS data is
being done when each thread starts. This can even be done in a
lazy manner when the first TLS variable is being accessed.
I have questions regarding thread_attachThis and
thread_detachThis: When should they be called? Should the
library expose a function that the users must call from *each
thread* that they will be using? This may not be easy because a
user may not know what thread they are running on. For example,
the user of our library may be on a framework where threads may
come and go, where the user may not have an opportunity to call
thread_detachThis when a thread goes away. For example, the
user may provide callback functions (which call us) to a
framework that is running on a thread pool.
I call thread_attachThis as soon the thread is supposed to call a
D function. For example a callback from a thread in a thread
pool. This usually happens when there is a function or delegate
involved as any jump to D code would use them. I have to make a
generic API and then a D API on top of that. In practice this
means there is a trampoline function involved where and
thread_attachThis and thread_detachThis is being called. Also
this is where I call TLS ctors/dtors. It is an effect that
delegates is language specific and it falls natural that way.
Avoid extern(C) calls directly into D code.
In practice you can do this for any thread even if there are
several delegates during the thread lifetime. You can simply have
a TLS bool variable telling if the thread_attachThis and
rt_moduleTlsCtor have already been run.
More questions: Can I thread_detachThis the thread that called
rt_init? Can I call rt_moduleTlsCtor more than once? I guess it
depends on each module. It will be troubling if a TLS ctor
reinitializes an module state. :/
I have brought up this question before because like it is right
now I haven't seen any "rt_uninit" or "rt_close" function. This
is bit limiting for me as the main thread can exit while the
process lives on. In general the main thread that goes into main
must also be the last one returning the entire line of functions
that was called during entry of the process. What will happen is
that you possibly do a thread_detachThis twice.
Short answer is just park the main thread while the bulk is being
done by other threads. Unfortunately that's how many libraries
work today.