[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: thread state and dynamically loadable library
- From: Doug Currie <doug.currie@...>
- Date: Mon, 4 Sep 2006 23:04:41 -0400
There are times when a dynamically loadable library needs to maintain
a per thread state. For example, I am working on a port of decNumber
to Lua as a loadable library; it needs a numeric context (rounding,
precision, etc.) that should be "global" to the thread, but not shared
between threads. [There is the option of requiring all operations on
decNumbers to take a context argument. This is the approach the C
library uses, but seems contrary to a Lua user's expectation of, e.g.,
infix operators working on decNumbers.]
Cursory reading of the Lua 5.1 manual leads one to believe that there
is a "thread environment" accessible using LUA_GLOBALSINDEX. But
looking at the source code leads me to conclude that all threads share
the same global table by default. If so, this is useless as a
per-thread storage mechanism for the library. Although it may be
possible to construct tables for each thread that defer to the global
global table using a metatable, this approach would depend on
mechanisms outside the library's control, e.g., at thread creation time.
If the library was statically linked with Lua, there is the
LUAI_EXTRASPACE mechanism to allocate some per-thread storage. This
would suit the purpose perfectly, except that it doesn't work for
dynamically loaded libraries and stock Lua.
What's needed is dynamically allocated per thread storage. Can any one
identify mechanisms to do this that I haven't considered above?
An approach that might work is to create a per-thread table for thread
local storage and put it in the registry keyed on the thread's
identity (i.e., L). This would work until some other library tried to
put something else in the registry keyed on L. I could construct a
"more unique key" such as L concatenated with the address of some
object in my library, but this either runs the risk of running out of
bits in LUA_NUMBER, or taking lots of time in re-constructing the key
every time the context is needed.
It would be really nice to have a LUA_THREADREGISTRYINDEX that
provided access to a gc'd slot in the thread state (initially nil or
an empty table). Then dynamically loadable libraries could store per
thread context in that table.