diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2018-11-15 11:20:14 +0100 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2018-11-15 11:20:14 +0100 |
commit | 09c2339cd63f579b1c8c12db8b0ad8d8246d0626 (patch) | |
tree | b7ed91b466438df2ab7f18fc2b95c4c9a66add31 | |
parent | 1e4f64380a19f6024d54c6bec8553391321e4b99 (diff) | |
download | lanes-09c2339cd63f579b1c8c12db8b0ad8d8246d0626.tar.gz lanes-09c2339cd63f579b1c8c12db8b0ad8d8246d0626.tar.bz2 lanes-09c2339cd63f579b1c8c12db8b0ad8d8246d0626.zip |
Deep userdata must embed DeepPrelude to save an allocation (also changes Deep protocol)
-rw-r--r-- | index.html | 18 |
1 files changed, 9 insertions, 9 deletions
@@ -1607,9 +1607,9 @@ int luaD_new_clonable( lua_State* L) | |||
1607 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> void* idfunc( lua_State* L, DeepOp op_);</pre></td></tr></table> | 1607 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> void* idfunc( lua_State* L, DeepOp op_);</pre></td></tr></table> |
1608 | <tt>op_</tt> can be one of: | 1608 | <tt>op_</tt> can be one of: |
1609 | <ul> | 1609 | <ul> |
1610 | <li><tt>eDO_new</tt>: requests the creation of a new object, whose pointer is returned.</li> | 1610 | <li><tt>eDO_new</tt>: requests the creation of a new object, whose pointer is returned. Starting with version 3.13.0, object should embed <tt>DeepPrelude</tt> structure as header and initialize its <tt>magic</tt> member with the current <tt>DEEP_VERSION</tt>.</li> |
1611 | <li><tt>eDO_delete</tt>: receives this same pointer on the stack as a light userdata, and should cleanup the object.</li> | 1611 | <li><tt>eDO_delete</tt>: receives this same pointer on the stack as a light userdata, and should cleanup the object.</li> |
1612 | <li><tt>eDO_metatable</tt>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it (<tt>eDO_metatable</tt> should only be invoked once per state). Push the metatable on the stack, then call <tt>luaG_pushdeepversion()</tt> before returning (new in version 3.9.5).</li> | 1612 | <li><tt>eDO_metatable</tt>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it (<tt>eDO_metatable</tt> should only be invoked once per state). Just push the metatable on the stack.</li> |
1613 | <li><tt>eDO_module</tt>: requests the name of the module that exports the idfunc, to be returned. It is necessary so that Lanes can require it in any lane state that receives a userdata. This is to prevent crashes in situations where the module could be unloaded while the idfunc pointer is still held.</li> | 1613 | <li><tt>eDO_module</tt>: requests the name of the module that exports the idfunc, to be returned. It is necessary so that Lanes can require it in any lane state that receives a userdata. This is to prevent crashes in situations where the module could be unloaded while the idfunc pointer is still held.</li> |
1614 | </ul> | 1614 | </ul> |
1615 | Take a look at <tt>linda_id</tt> in <tt>lanes.c</tt> or <tt>deep_test_id</tt> in <tt>deep_test.c</tt>. | 1615 | Take a look at <tt>linda_id</tt> in <tt>lanes.c</tt> or <tt>deep_test_id</tt> in <tt>deep_test.c</tt>. |
@@ -1624,13 +1624,13 @@ int luaD_new_clonable( lua_State* L) | |||
1624 | </p> | 1624 | </p> |
1625 | 1625 | ||
1626 | <p> | 1626 | <p> |
1627 | Deep userdata in transit inside keeper states (sent in a linda but not yet consumed) don't call <tt>idfunc(eDO_delete)</tt> and aren't considered by reference counting. The rationale is the following: | 1627 | Deep userdata in transit inside keeper states (sent in a linda but not yet consumed) don't call <tt>idfunc(eDO_delete)</tt> and aren't considered by reference counting. The rationale is the following: |
1628 | <br/> | 1628 | <br /> |
1629 | If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0. | 1629 | If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0. |
1630 | <br/> | 1630 | <br /> |
1631 | OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. But as it happens, deep userdata are only copied to and from keeper states. Most notably, the object's <tt>idfunc()</tt> is never called from a keeper state. | 1631 | OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. Deep userdata's <tt>idfunc()</tt> is never called from a keeper state. |
1632 | <br/> | 1632 | <br /> |
1633 | Therefore, Lanes can just call <tt>idfunc(eDO_delete)</tt> when the last non-keeper-held deep userdata is collected, as long as it doens't do the same in a keeper state after that, since any remaining deep userdata in keeper states now hold stale pointers. | 1633 | Therefore, Lanes can just call <tt>idfunc(eDO_delete)</tt> when the last non-keeper-held deep userdata is collected, as long as it doesn't do the same in a keeper state after that, since any remaining deep userdata in keeper states now hold stale pointers. |
1634 | </p> | 1634 | </p> |
1635 | 1635 | ||
1636 | <p> | 1636 | <p> |