lua-users home
lua-l archive

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

I understand that C code generally should not store the pointer to a
string returned by lua_tostring beyond the lifetime of the C function
call.(PIL says "The lua_tostring function returns a pointer to an
internal copy of the string. Lua ensures that this pointer is valid as
long as the corresponding value is in the stack. When a C function
returns, Lua clears its stack; therefore, as a rule, you should never
store pointers to Lua strings outside the function that got them.")

However, is this restriction strictly true if I can guarantee - from
my code flow - that the original string in lua will continue to be in
reachable (that is, it is not garbage collected) when my C function
call returns?

Here is my actual scenario: Luaw HTTP server uses Lua coroutines to
handle multiple connections simultaneously. While generating response
a Lua coroutine calls a C function with Lua string that the C function
is eventually supposed to write to socket. But since the socket write
may block, the C function actually uses async write API (libuv to be
specific) to write to the socket. The function then returns
immediately and the Lua coroutine that called the C function yields to
suspend itself. When the socket is ready for the actual write, libuv's
async API invokes a C callback that writes the string on the socket
and then resumes the suspended coroutine.

Now in classical model I should make a copy of the string passed into
the first C function as the function will return before the callback
has a chance to write the string onto the socket. However I want to
avoid the data copy (memcpy) if I can get away with it for performance
reasons. My rationale is even though the original C function has
returned the Lua coroutine that called the C function gets suspended
as soon as C function call returns. So the original string that was
passed in the C call is still reference-able from the Lua coroutine
and hence should not be garbage collected. So I should be able to just
store the pointer to the internal Lua string returned by
lua_tostring() without making a copy of it. When the write callback is
called it first calls a C function - kind of a continuation of first C
call - that writes the string onto the socket and then resumes Lua
coroutine. This way I can guarantee that the original Lua string's
lifetime is more than the two C calls - original call and then the
callback invoked by libuv - involved.

Is it safe to not make a copy of a lua string in C function in this case?


- Susheel