lua-users home
lua-l archive

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


On Tue, Nov 20, 2012 at 10:54:53AM +0000, Jerome Vuarand wrote:
> If you can do with only 53 bits, you can use plain Lua numbers. For
> file offsets (with byte-size words) for example that covers 8
> petabytes. Otherwise you have to revert to the same techniques as in
> C, pass the number in two parts in a table, or as an opaque value (in
> a string or in a userdata) which limits the manipulation the user can
> apply, but depending on the situation that may be acceptable.

The code currently expects a string to be passed in [I may change this
so it can accept either a string or an int], and returns the int64
converted to a string.

This seems something of a problem with Lua itself.  How would you
express, say, the exact size in a bytes of a disk volume?  2^53 is
8 petabytes, which is easily in range of what is available in high end
storage now.  I have access to a larger disk array at work.  Not to
mention that virtual, sparsely allocated disks can be larger even on
my laptop.

Also we use 64 bit ints as bitmasks in various places.

> It all depends on the threading model of the library you're binding.
> You should ensure that your callbacks are called in order and don't
> overlap, as the Lua interpreter cannot be used simultaneously by
> several threads. For some libraries (FUSE for example) that's an init
> option.

In libguestfs we assume that each handle is only used in a single
thread, and callbacks are always delivered in the same thread that is
running the function that generates them.  So I guess we should be OK?

> > - How do I push a userdata onto the Lua stack?  Instead I'm pushing
> >   a pointer to a userdata using: lua_pushlightuserdata (L, u);
> >   [see event_callback_wrapper]
> 
> If you only have a pointer to the userdata you can't push it back. You
> need an actual Lua reference, either on the stack, in an upvalue or in
> a table. If you only want to keep the pointer around, you can create a
> mapping table in the registry, so that you can get back a reference
> from the pointer. Make that mapping table a weak-valued table, use the
> pointers (pushed as light userdata) as keys and the full userdata as
> values.

That is a bug in my bindings, will see if I can fix it.

> > - How do you print "any" type, from C?
> 
> There's no built-in framework for that, because for non-basic types
> there is no trivial way to do it. There are plenty of libraries
> around, in Lua or in C (keep in mind that if you got a lua_State
> pointer you can call Lua code from C very easily).

Is there a particular library I should be looking at?  My Google-fu
isn't turning up anything at the moment ...

The only thing I want to print is the exception which is thrown by the
callback, which cannot be handled in any other way except printing it
(callbacks aren't supposed to be throwing exceptions).

> > - This works:
> >     luaL_register (L, NULL, handle_methods);
> >   but this fails:
> >     luaL_register (L, "guestfs", handle_methods);
> >   Why?
> 
> That by itself should work. How do you determine it doesn't? Do you
> get an error?

Just making that single change causes the bindings to throw errors
like:

/usr/bin/lua: /home/rjones/d/libguestfs/lua/tests/027-create-multiple.lua:26: attempt to index global 'g1' (a userdata value)
stack traceback:
      /home/rjones/d/libguestfs/lua/tests/027-create-multiple.lua:26: in main chunk
      [C]: ?

[...]
> This is unrelated to your question, but I noticed that that
> get_string_list function uses malloc, which requires the caller to
> call free. Note that you can use lua_newuserdata instead of malloc to
> push temporary memory blocs on the Lua stack. They will automatically
> be collected when you give back control to Lua (return from your
> lua_CFunction). The nice bit is that it lets you call functions that
> could throw Lua errors without worrying about potential leaks (right
> now if a Lua error gets thrown between "get_string_list" and the
> corresponding "free" call, the array of pointers is lost).

Right, good idea.  Although in this case since the code that calls
get_string_list is all generated there's only one place that I need to
"remember" to call free, and then the generator puts it in at all the
right places.

Thanks for your detailed answers.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine.  Supports Linux and Windows.
http://et.redhat.com/~rjones/virt-df/