lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Mon, Apr 02, 2007 at 04:10:38PM -0400, Jerome Vuarand wrote:
> Sam Roberts wrote:
> > On Mon, Apr 02, 2007 at 09:49:56PM +0300, Asko Kauppi wrote:
> >> Lua uses NSLINKMODULE_OPTION_PRIVATE flag on OS X for its "require",
> >> but this causes globals in a module required in two separate Lua
> >> states NOT to have common globals. I faced this today, and the only
> >> solution found was removing that flag from loadlib.c.
> > 
> > As a quick fix, have you tried using dlopen() instead? It is
> > recommended on OS X (by Apple, see
> > http://lua-users.org/wiki/BuildingLua).  
> > 
> > Still, I'm a little surprised that the bundle was loaded twice.
> > 
> > Could this be a bug? Isn't package supposed to load the bundle/so/dll
> > only the first time the module is required, and the other times to
> > use the previously opened shared library handle, find the luaopen_XX
> > symbol using that handle, and call it again in the new state?   
> > 
> > The package module definitely keeps the load handle around, I don't
> > see why it shouldn't use it! 
> 
> The problem comes from the fact that Asko use separate Lua states. If a
> binary module is required in two independents Lua states, it's
> initialization function must be called twice. Since binary modules may
> not be reentrant and use globals to store "Lua-state"-specific
> information, having it loaded twice with private static data allows to
> avoid collisions in memory between the two instances of the module,
> while the package system still ensure that all require in the same Lua
> state will always return the same module table.

Ok, that explains why you can't call luaopen_XXX twice, that makes
sense, they aren't written to be called multiple times, often.

But, it still does not make sense to me that require() reloads a module,
possibly, depending on the state. This seems like standing on quicksand.
Does this means that the only safe way to use a binary module is to
require it once, before any coroutines are created, because if require()
is called from within a coroutine, it will always create another copy
of the module?

> If you make the static data shared (by removing the aforementioned
> flag), to allow communication between the two instances of the module,
> you have to make sure all binary modules you load don't store
> "Lua-state"-specific information in static variables. For example you
> can't store registry indices in globals and share them between Lua
> states, since each has its own registry.

They do? So if cfunctions from my binary modules are called from a
coroutine(a different lua_State, right?), and they try and check the
type of a userdata by looking up it's metatable in "the" registry, they
will not find it?

Sam