diff options
author | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-02-17 11:05:19 +0100 |
---|---|---|
committer | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-02-17 11:05:19 +0100 |
commit | 437efd443b81de7dcb373913d59634aed525bf82 (patch) | |
tree | c5edb8434b4b3a5379dcf47c8533b94995a94301 | |
parent | 3786716e6ddab0c0a01b58b286bc9573149536a6 (diff) | |
download | lanes-437efd443b81de7dcb373913d59634aed525bf82.tar.gz lanes-437efd443b81de7dcb373913d59634aed525bf82.tar.bz2 lanes-437efd443b81de7dcb373913d59634aed525bf82.zip |
Deep userdata support improvements
* bumped version to 3.9.0
* keepers now require "package", receive package.path & package.cpath,
and call on_state_create() if it is a C function
* changed the deep public API (improved deep idfunc signature, renamed
luaG_deep_userdata to luaG_newdeepuserdata)
* if an error occurs while copying a deep userdata, don't raise inside
the keeper state
* fixed situations where raised errors could lead to memory leaks (deep
gc)
-rw-r--r-- | index.html | 32 |
1 files changed, 22 insertions, 10 deletions
@@ -70,7 +70,7 @@ | |||
70 | </p> | 70 | </p> |
71 | 71 | ||
72 | <p> | 72 | <p> |
73 | This document was revised on 13-Feb-14, and applies to version <tt>3.8.5</tt>. | 73 | This document was revised on 17-Feb-14, and applies to version <tt>3.9.0</tt>. |
74 | </p> | 74 | </p> |
75 | </font> | 75 | </font> |
76 | </center> | 76 | </center> |
@@ -355,7 +355,9 @@ | |||
355 | function/<tt>nil</tt> | 355 | function/<tt>nil</tt> |
356 | </td> | 356 | </td> |
357 | <td> | 357 | <td> |
358 | If provided, will be called in every created Lua state (keepers and lanes) right after initializing the base libraries. | 358 | If provided, will be called in every created Lua state right after initializing the base libraries. |
359 | <br/> | ||
360 | Keeper states will call it as well, but only if it is a C function (keeper states are not able to execute any user Lua code). | ||
359 | <br/> | 361 | <br/> |
360 | Typical usage is twofold: | 362 | Typical usage is twofold: |
361 | <ul> | 363 | <ul> |
@@ -1493,18 +1495,18 @@ events to a common Linda, but... :).</font> | |||
1493 | <ol> | 1495 | <ol> |
1494 | <li> | 1496 | <li> |
1495 | 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 | 1497 | 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 |
1496 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> void idfunc( lua_State *L, char const * const which);</pre></td></tr></table> | 1498 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> void* idfunc( lua_State* L, enum eDeepOp op_);</pre></td></tr></table> |
1497 | <tt>which</tt> can be one of: | 1499 | <tt>op_</tt> can be one of: |
1498 | <ul> | 1500 | <ul> |
1499 | <li><tt>"new"</tt>: requests the creation of a new object, whose pointer is pushed on the stack as a light userdata.</li> | 1501 | <li><tt>eDO_new</tt>: requests the creation of a new object, whose pointer is returned.</li> |
1500 | <li><tt>"delete"</tt>: receives this same pointer on the stack, and should cleanup the object.</li> | 1502 | <li><tt>eDO_delete</tt>: receives this same pointer on the stack as a light userdata, and should cleanup the object.</li> |
1501 | <li><tt>"metatable"</tt>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it ("metatable" should only be invoked once).</li> | 1503 | <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).</li> |
1502 | <li><tt>"module"</tt>: is the name of the module that exports the idfunc, to be pushed on the stack as a string. It is necessary so that Lanes can require it in any Lane and keeper 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> | 1504 | <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> |
1503 | </ul> | 1505 | </ul> |
1504 | Take a look at <tt>linda_id</tt> in <tt>lanes.c</tt>. | 1506 | Take a look at <tt>linda_id</tt> in <tt>lanes.c</tt>. |
1505 | </li> | 1507 | </li> |
1506 | <li>Include <tt>"deep.h"</tt> and link against Lanes. | 1508 | <li>Include <tt>"deep.h"</tt> and link against Lanes. |
1507 | <li>Instanciate your userdata using <tt>luaG_deep_userdata()</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> | 1509 | <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> |
1508 | <li>Accessing the deep userdata from your C code, use <tt>luaG_todeep()</tt> instead of the regular <tt>lua_touserdata()</tt>.</li> | 1510 | <li>Accessing the deep userdata from your C code, use <tt>luaG_todeep()</tt> instead of the regular <tt>lua_touserdata()</tt>.</li> |
1509 | </ol> | 1511 | </ol> |
1510 | 1512 | ||
@@ -1513,7 +1515,17 @@ events to a common Linda, but... :).</font> | |||
1513 | </p> | 1515 | </p> |
1514 | 1516 | ||
1515 | <p> | 1517 | <p> |
1516 | <b>NOTE</b>: The lifespan of deep userdata may exceed that of the Lua state that created it. The allocation of the data storage should not be tied to the Lua state used. In other words, use <tt>malloc</tt>/<tt>free</tt> or similar memory handling mechanism. | 1518 | 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: |
1519 | <br/> | ||
1520 | 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. | ||
1521 | <br/> | ||
1522 | 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. | ||
1523 | <br/> | ||
1524 | 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. | ||
1525 | </p> | ||
1526 | |||
1527 | <p> | ||
1528 | <b>NOTE</b>: The lifespan of deep userdata may exceed that of the Lua state that created it. The allocation of the data storage should not be tied to the Lua state used. In other words, use <tt>malloc()</tt>/<tt>free()</tt> or similar memory handling mechanism. | ||
1517 | </p> | 1529 | </p> |
1518 | 1530 | ||
1519 | 1531 | ||