-
Notifications
You must be signed in to change notification settings - Fork 96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deep userdata system does not properly copy id_func #7
Comments
The way I see it, Done (locally, since I don't have github access here; I'll create a branch so that you can have a look at the changes). The changes are pretty straightforward. Now all calls to idfunc are direct (no more |
This sounds like a good solution to the problem. It should help clarify the interface between C modules and lanes. Does this change affect the issue where the id_func is called after the associated shared library has been unloaded? If id_func was a C closure, it could be registered ( with the Register cclosure feature ) which would make sure that the shared library was always loaded as long as the closure existed. But if id_func is now just a normal function pointer, how does Lanes make sure that the shared library associated with the id_func pointer remains loaded until the selfdestruct_atext() function is called ( which is the end of Lanes )? |
Unfortunately, since idfunc becomes a regular C function pointer, we can't force the shared library to remain loaded with the changes I have made so far. My idea to fix this would be for the foo module writer to grab the userdata containing the library handle in the main state registry right inside its Edit: Another idea: state that id_func should answer a new query (say, "module") that pushes the name of the module that exports it on the stack. Inside |
This may be slightly off topic: Is there any way we can restructure the current Lanes to allow a single module to be usable without Lanes and with Lanes? Right now, it appears like C modules using userdata must recompile a special version of the module to make it compatible with Lanes. Ideally, an end user should be able to setup whatever is needed to make a module work with Lanes, but since this doesn't appear possible, the next best thing would be to make it easy for module writers to include Lanes support into their module without having to maintain a separate version or inconvenience themselves too much. So if we are already going to be breaking backwards compatibility with previous versions of the deep UD system ( with this change you suggested ), we may want to consider redesigning the interface for a more flexible approach that will allow modules to selectively enable/disable Lanes support for their userdata at runtime. |
It is even worse than that: in order to be compatible, the module must link against lanes since it must push userdata on the stack with |
What about moving the keeper states shutdown in |
This should solve the problem for all deep userdatas, except for the Linda deep UD, since they use This would also mean that thread cleanup functions ( gc and finalizers ) would not be able to use Linda objects at all. I'm currently using Lindas in the |
I'm not sure exactly why This would allow module makers to provide lanes support at runtime on request ( like with an |
So what you propose is that we expose C closures accessible only from C, stored for example in the main state registry, that perform the operations of My feeling about all this is that we have two types of module authors:
So, I believe that making all necessary functions lua_CFunctions so that they can be obtained as C closures once lanes is required will only complexify the work for the module writer that wants to create a Lanes-compatible module. Directly calling So, to my mind, keeping the API as it is (direct call just like any Lua API function) is the way to go. Unless you can convince me otherwise :-) |
I guess I was getting a little too ambitious thinking that module authors would consider adding Lanes support to their publicly available modules. After reading your description of the two types of module authors, I agree with you on that. Making the Lanes API functions directly callable ( like the Lua API ) is definitely much cleaner/clearer, so for the lack of good reasons to use any other method, this probably is the best way to do it. Thank you for taking the time to discuss the idea. |
After playing around with various options available to solve this issue, having Lanes automatically require the appropriate module in the new state seemed to be the best solution. And getting the module name from the id_func is about as simple as you can make it, so IMO, this idea you came up with is an excellent solution to the deep UD id_func shared library dependency problem. |
I've submitted the necessary changes. Can we consider this closed? |
Yes, looks like it's all fixed now. Thank you making these changes to fix this! |
The id_func for deep userdata objects appears to be a normal lua_CFunction type function, but yet it is not copied or accessed properly if various places of the deep userdata system.
If the id_func depends on upvalues or on Lua's automatic stack cleanup, it would not work with the deep userdata system, since it takes a pointer to the function from L and then pushes a new closure onto L2 without copying upvalues. Also
luaG_deep_userdata
( other places too? ) it just calls the id_func directly through the function pointer, rather than calling through the closure withlua_call
.It's not that hard to write your id_func to not rely on closures, module initialization and automatic stack cleanup, so simply mentioning these limitations in the documentation could be all that is needed to address this issue right now.
The text was updated successfully, but these errors were encountered: