aboutsummaryrefslogtreecommitdiff
path: root/docs/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/index.html')
-rw-r--r--docs/index.html39
1 files changed, 25 insertions, 14 deletions
diff --git a/docs/index.html b/docs/index.html
index 3e535a6..67eccd5 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1683,34 +1683,45 @@ int luaD_new_clonable(lua_State* L)
1683 1683
1684<ol> 1684<ol>
1685 <li> 1685 <li>
1686 Provide an <i>identity function</i> for your userdata, in C. This function is used for creation and deletion of your deep userdata (the shared resource), and for making metatables for the state-specific proxies for accessing it. The prototype is 1686 Provide a <i>factory</i> for your userdata. This object is used for creation and deletion of your deep userdata (the shared resource), and for making metatables for the state-specific proxies for accessing it. The prototype is
1687 <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> void* idfunc(lua_State* L, DeepOp op_);</pre></td></tr></table> 1687<table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre>
1688 <tt>op_</tt> can be one of: 1688class MyDeepFactory : public DeepFactory
1689{
1690 private:
1691
1692 DeepPrelude* newDeepObjectInternal(lua_State* L) const override;
1693 void deleteDeepObjectInternal(lua_State* L, DeepPrelude* o_) const override;
1694 void createMetatable(lua_State* L) const override;
1695 char const* moduleName() const override;
1696};
1697
1698static MyDeepFactory g_MyDeepFactory;
1699</pre></td></tr></table>
1689 <ul> 1700 <ul>
1690 <li><tt>DeepOp::New</tt>: requests the creation of a new object, whose pointer is returned. Said object must derive from <tt>DeepPrelude</tt>.</li> 1701 <li><tt>newDeepObjectInternal</tt>: requests the creation of a new object, whose pointer is returned. Said object must derive from <tt>DeepPrelude</tt>.</li>
1691 <li><tt>DeepOp::Delete</tt>: receives this same pointer on the stack as a light userdata, and should cleanup the object.</li> 1702 <li><tt>deleteDeepObjectInternal</tt>: should cleanup the object.</li>
1692 <li><tt>DeepOp::Metatable</tt>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it (<tt>DeepOp::Metatable</tt> should only be invoked once per state). Just push the metatable on the stack.</li> 1703 <li><tt>createMetatable</tt>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it (<tt>createMetatable</tt> should only be invoked once per state). Just push the metatable on the stack.</li>
1693 <li><tt>DeepOp::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> 1704 <li><tt>moduleName</tt>: requests the name of the module that exports the factory, 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 factory pointer is still held.</li>
1694 </ul> 1705 </ul>
1695 Take a look at <tt>linda_id</tt> in <tt>lanes.cpp</tt> or <tt>deep_test_id</tt> in <tt>deep_test.cpp</tt>. 1706 Take a look at <tt>LindaFactory</tt> in <tt>linda.cpp</tt> or <tt>MyDeepFactory</tt> in <tt>deep_test.cpp</tt>.
1696 </li> 1707 </li>
1697 <li>Include <tt>"deep.h"</tt> and either link against Lanes or statically compile <tt>compat.cpp deep.cpp tools.cpp universe.cpp</tt> into your module if you want to avoid a runtime dependency for users that will use your module without Lanes. 1708 <li>Include <tt>"deep.h"</tt> and either link against Lanes or statically compile <tt>compat.cpp deep.cpp tools.cpp universe.cpp</tt> into your module if you want to avoid a runtime dependency for users that will use your module without Lanes.
1698 <li>Instanciate your userdata using <tt>luaG_newdeepuserdata()</tt>, instead of the regular <tt>lua_newuserdata()</tt>. Given an <tt>idfunc</tt>, it sets up the support structures and returns a state-specific proxy userdata for accessing your data. This proxy can also be copied over to other lanes.</li> 1709 <li>Instanciate your userdata using <tt>yourFactoryObject.pushDeepUserdata()()</tt>, instead of the regular <tt>lua_newuserdata()</tt>. Given a <tt>factory</tt>, it sets up the support structures and returns a state-specific proxy userdata for accessing your data. This proxy can also be copied over to other lanes.</li>
1699 <li>Accessing the deep userdata from your C code, use <tt>luaG_todeep()</tt> instead of the regular <tt>lua_touserdata()</tt>.</li> 1710 <li>Accessing the deep userdata from your C code, use <tt>yourFactoryObject.toDeep()</tt> instead of the regular <tt>lua_touserdata()</tt>.</li>
1700</ol> 1711</ol>
1701 1712
1702<p> 1713<p>
1703 Deep userdata management will take care of tying to <tt>__gc</tt> methods, and doing reference counting to see how many proxies are still there for accessing the data. Once there are none, the data will be freed through a call to the <tt>idfunc</tt> you provided. 1714 Deep userdata management will take care of tying to <tt>__gc</tt> methods, and doing reference counting to see how many proxies are still there for accessing the data. Once there are none, the data will be freed through a call to the factory you provided.
1704</p> 1715</p>
1705 1716
1706<p> 1717<p>
1707 Deep userdata in transit inside keeper states (sent in a linda but not yet consumed) don't call <tt>idfunc(DeepOp::Delete)</tt> and aren't considered by reference counting. The rationale is the following: 1718 Deep userdata in transit inside keeper states (sent in a linda but not yet consumed) don't call <tt>deleteDeepObjectInternal</tt> and aren't considered by reference counting. The rationale is the following:
1708 <br /> 1719 <br />
1709 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. 1720 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.
1710 <br /> 1721 <br />
1711 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. 1722 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>factory()</tt> interface is never accessed from a keeper state.
1712 <br /> 1723 <br />
1713 Therefore, Lanes can just call <tt>idfunc(DeepOp::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. 1724 Therefore, Lanes can just call <tt>deleteDeepObjectInternal</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.
1714</p> 1725</p>
1715 1726
1716<p> 1727<p>