aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2012-06-05 21:15:02 +0200
committerBenoit Germain <bnt.germain@gmail.com>2012-06-05 21:15:02 +0200
commitd8e446dfad1195d0ed3a63e8945a2f96c73f84cc (patch)
treed475a5164d55a0633ff4ab64bbcda736ec3bd116
parent1c33960abd867e425bad2633a85504f55a1f261c (diff)
downloadlanes-d8e446dfad1195d0ed3a63e8945a2f96c73f84cc.tar.gz
lanes-d8e446dfad1195d0ed3a63e8945a2f96c73f84cc.tar.bz2
lanes-d8e446dfad1195d0ed3a63e8945a2f96c73f84cc.zip
* fixed thread_cancel() not working when called without argument
* new lane-global function set_error_reporting() to enable more data detailed data provided by lane_error()
-rw-r--r--CHANGES4
-rw-r--r--docs/index.html16
-rw-r--r--src/lanes.c168
3 files changed, 130 insertions, 58 deletions
diff --git a/CHANGES b/CHANGES
index d9f2641..ed8e317 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,9 @@
1 1
2CHANGES: 2CHANGES:
3 3
4CHANGE X: 4CHANGE 37: BGe 4-Jun-2012 (fix and idea courtesy of sonoro1234)
5 * fixed thread_cancel() not working when called without argument
6 * new lane-global function set_error_reporting() to enable more data detailed data provided by lane_error()
5 7
6CHANGE 36 BGe 26-Apr-2012 8CHANGE 36 BGe 26-Apr-2012
7 * improved LuaJIT2 compatibility by handling "*" library set through luaL_openlibs() 9 * improved LuaJIT2 compatibility by handling "*" library set through luaL_openlibs()
diff --git a/docs/index.html b/docs/index.html
index 5fe992d..1aeffe9 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -56,7 +56,7 @@
56 56
57<p><br/><font size="-1"><i>Copyright &copy; 2007-12 Asko Kauppi, Benoit Germain. All rights reserved.</i> 57<p><br/><font size="-1"><i>Copyright &copy; 2007-12 Asko Kauppi, Benoit Germain. All rights reserved.</i>
58 <br>Lua Lanes is published under the same <A HREF="http://en.wikipedia.org/wiki/MIT_License">MIT license</A> as Lua 5.1. 58 <br>Lua Lanes is published under the same <A HREF="http://en.wikipedia.org/wiki/MIT_License">MIT license</A> as Lua 5.1.
59 </p><p>This document was revised on 17-Feb-11, and applies to version 3.1.0 59 </p><p>This document was revised on 17-Feb-11, and applies to version 3.1.2
60</font></p> 60</font></p>
61 61
62</center> 62</center>
@@ -431,9 +431,17 @@ Returns <tt>nil</tt> on timeout, <tt>nil,err,stack_tbl</tt> if the lane hit an e
431or the return values of the lane. Unlike in reading the results in table 431or the return values of the lane. Unlike in reading the results in table
432fashion, errors are not propagated. 432fashion, errors are not propagated.
433</p><p> 433</p><p>
434<tt>stack_tbl</tt> is an array of "&lt;filename&gt;:&lt;line&gt;" strings, 434
435describing where the error was thrown. Use <tt>table.concat()</tt> to format 435<table border=1 bgcolor="#E0E0FF" cellpadding=10><tr><td>
436it to your liking (or just ignore it). 436 <code>set_error_reporting("basic"|"extended")</code>
437</table>
438</p><p>
439 Sets the error reporting mode. "basic" is selected by default.
440</p><p>
441 <tt>stack_tbl</tt> is a table describing where the error was thrown.<br/>
442 In extended mode, <tt>stack_tbl</tt> is an array of tables containing info gathered with <tt>lua_getinfo()</tt> (<tt>"source"</tt>,<tt>"currentline"</tt>,<tt>"name"</tt>,<tt>"namewhat"</tt>,<tt>"what"</tt>).<br/>
443In "basic mode", <tt>stack_tbl</tt> is an array of "&lt;filename&gt;:&lt;line&gt;" strings. Use <tt>table.concat()</tt> to format it to your liking (or just ignore it).
444
437</p><p> 445</p><p>
438If you use <tt>:join</tt>, make sure your lane main function returns 446If you use <tt>:join</tt>, make sure your lane main function returns
439a non-nil value so you can tell timeout and error cases apart from succesful 447a non-nil value so you can tell timeout and error cases apart from succesful
diff --git a/src/lanes.c b/src/lanes.c
index 176009a..d777be1 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -51,7 +51,7 @@
51 * ... 51 * ...
52 */ 52 */
53 53
54char const* VERSION = "3.1.1"; 54char const* VERSION = "3.1.2";
55 55
56/* 56/*
57=============================================================================== 57===============================================================================
@@ -107,10 +107,6 @@ THE SOFTWARE.
107*/ 107*/
108#define ERROR_FULL_STACK 108#define ERROR_FULL_STACK
109 109
110#ifdef ERROR_FULL_STACK
111# define STACK_TRACE_KEY ((void*)lane_error) // used as registry key
112#endif
113
114// NOTE: values to be changed by either thread, during execution, without 110// NOTE: values to be changed by either thread, during execution, without
115// locking, are marked "volatile" 111// locking, are marked "volatile"
116// 112//
@@ -695,10 +691,11 @@ LUAG_FUNC( linda_deep ) {
695LUAG_FUNC( linda_tostring) 691LUAG_FUNC( linda_tostring)
696{ 692{
697 char text[32]; 693 char text[32];
698 struct s_Linda *linda = lua_toLinda( L, 1); 694 int len;
695 struct s_Linda* linda = lua_toLinda( L, 1);
699 luaL_argcheck( L, linda, 1, "expected a linda object!"); 696 luaL_argcheck( L, linda, 1, "expected a linda object!");
700 sprintf( text, "linda: %p", linda); 697 len = sprintf( text, "linda: %p", linda);
701 lua_pushstring( L, text); 698 lua_pushlstring( L, text, len);
702 return 1; 699 return 1;
703} 700}
704 701
@@ -720,15 +717,15 @@ LUAG_FUNC( linda_concat)
720 if ( linda1) 717 if ( linda1)
721 { 718 {
722 char text[32]; 719 char text[32];
723 sprintf( text, "linda: %p", linda1); 720 int len = sprintf( text, "linda: %p", linda1);
724 lua_pushstring( L, text); 721 lua_pushlstring( L, text, len);
725 lua_replace( L, 1); 722 lua_replace( L, 1);
726 } 723 }
727 if ( linda2) 724 if ( linda2)
728 { 725 {
729 char text[32]; 726 char text[32];
730 sprintf( text, "linda: %p", linda2); 727 int len = sprintf( text, "linda: %p", linda2);
731 lua_pushstring( L, text); 728 lua_pushlstring( L, text, len);
732 lua_replace( L, 2); 729 lua_replace( L, 2);
733 } 730 }
734 // concat the result 731 // concat the result
@@ -1281,58 +1278,118 @@ LUAG_FUNC( _single ) {
1281*/ 1278*/
1282#ifdef ERROR_FULL_STACK 1279#ifdef ERROR_FULL_STACK
1283 1280
1284static int lane_error( lua_State *L ) { 1281# define STACK_TRACE_KEY ((void*)lane_error) // used as registry key
1285 lua_Debug ar; 1282# define EXTENDED_STACK_TRACE_KEY ((void*)LG_set_error_reporting) // used as registry key
1286 unsigned lev,n; 1283
1284#ifdef ERROR_FULL_STACK
1285LUAG_FUNC( set_error_reporting)
1286{
1287 bool_t equal;
1288 luaL_checktype( L, 1, LUA_TSTRING);
1289 lua_pushliteral( L, "extended");
1290 equal = lua_rawequal( L, -1, 1);
1291 lua_pop( L, 1);
1292 if( equal)
1293 {
1294 goto done;
1295 }
1296 lua_pushliteral( L, "basic");
1297 equal = !lua_rawequal( L, -1, 1);
1298 lua_pop( L, 1);
1299 if( equal)
1300 {
1301 return luaL_error( L, "unsupported error reporting model");
1302 }
1303done:
1304 lua_pushlightuserdata( L, EXTENDED_STACK_TRACE_KEY);
1305 lua_pushboolean( L, equal);
1306 lua_rawset( L, LUA_REGISTRYINDEX);
1307 return 0;
1308}
1309#endif // ERROR_FULL_STACK
1310
1311static int lane_error( lua_State* L)
1312{
1313 lua_Debug ar;
1314 unsigned lev, n;
1315 bool_t extended;
1287 1316
1288 // [1]: error message (any type) 1317 // [1]: error message (any type)
1289 1318
1290 assert( lua_gettop(L)==1 ); 1319 assert( lua_gettop( L) == 1);
1291 1320
1292 // Don't do stack survey for cancelled lanes. 1321 // Don't do stack survey for cancelled lanes.
1293 // 1322 //
1294#if 1 1323#if 1
1295 if (lua_touserdata(L,1) == CANCEL_ERROR) 1324 if( lua_touserdata( L, 1) == CANCEL_ERROR)
1296 return 1; // just pass on 1325 return 1; // just pass on
1297#endif 1326#endif
1298 1327
1299 // Place stack trace at 'registry[lane_error]' for the 'luc_pcall()' 1328 lua_pushlightuserdata( L, EXTENDED_STACK_TRACE_KEY);
1300 // caller to fetch. This bypasses the Lua 5.1 limitation of only one 1329 lua_gettable( L, LUA_REGISTRYINDEX);
1301 // return value from error handler to 'lua_pcall()' caller. 1330 extended = lua_toboolean( L, -1);
1331 lua_pop( L, 1);
1302 1332
1303 // It's adequate to push stack trace as a table. This gives the receiver 1333 // Place stack trace at 'registry[lane_error]' for the 'lua_pcall()'
1304 // of the stack best means to format it to their liking. Also, it allows 1334 // caller to fetch. This bypasses the Lua 5.1 limitation of only one
1305 // us to add more stack info later, if needed. 1335 // return value from error handler to 'lua_pcall()' caller.
1306 //
1307 // table of { "sourcefile.lua:<line>", ... }
1308 //
1309 STACK_GROW(L,3);
1310 lua_newtable(L);
1311 1336
1312 // Best to start from level 1, but in some cases it might be a C function 1337 // It's adequate to push stack trace as a table. This gives the receiver
1313 // and we don't get '.currentline' for that. It's okay - just keep level 1338 // of the stack best means to format it to their liking. Also, it allows
1314 // and table index growing separate. --AKa 22-Jan-2009 1339 // us to add more stack info later, if needed.
1315 // 1340 //
1316 lev= 0; 1341 // table of { "sourcefile.lua:<line>", ... }
1317 n=1; 1342 //
1318 while( lua_getstack(L, ++lev, &ar ) ) { 1343 STACK_GROW( L, 4);
1319 lua_getinfo(L, "Sl", &ar); 1344 lua_newtable( L);
1320 if (ar.currentline > 0) { 1345
1321 lua_pushinteger( L, n++ ); 1346 // Best to start from level 1, but in some cases it might be a C function
1322 lua_pushfstring( L, "%s:%d", ar.short_src, ar.currentline ); 1347 // and we don't get '.currentline' for that. It's okay - just keep level
1323 lua_settable( L, -3 ); 1348 // and table index growing separate. --AKa 22-Jan-2009
1324 } 1349 //
1325 } 1350 lev = 0;
1351 n = 1;
1352 while( lua_getstack( L, ++ lev, &ar))
1353 {
1354 lua_getinfo( L, extended ? "Sln" : "Sl", &ar);
1355 if( extended)
1356 {
1357 lua_newtable( L);
1358
1359 lua_pushstring( L, ar.source);
1360 lua_setfield( L, -2, "source");
1326 1361
1327 lua_pushlightuserdata( L, STACK_TRACE_KEY ); 1362 lua_pushinteger( L, ar.currentline);
1328 lua_insert(L,-2); 1363 lua_setfield( L, -2, "currentline");
1329 lua_settable( L, LUA_REGISTRYINDEX );
1330 1364
1331 assert( lua_gettop(L)== 1 ); 1365 lua_pushstring( L, ar.name);
1366 lua_setfield( L, -2, "name");
1332 1367
1333 return 1; // the untouched error value 1368 lua_pushstring( L, ar.namewhat);
1369 lua_setfield( L, -2, "namewhat");
1370
1371 lua_pushstring( L, ar.what);
1372 lua_setfield( L, -2, "what");
1373
1374 lua_rawseti(L, -2, n ++);
1375 }
1376 else if (ar.currentline > 0)
1377 {
1378 lua_pushinteger( L, n++ );
1379 lua_pushfstring( L, "%s:%d", ar.short_src, ar.currentline );
1380 lua_settable( L, -3 );
1381 }
1382 }
1383
1384 lua_pushlightuserdata( L, STACK_TRACE_KEY);
1385 lua_insert( L ,-2);
1386 lua_settable( L, LUA_REGISTRYINDEX);
1387
1388 assert( lua_gettop( L) == 1);
1389
1390 return 1; // the untouched error value
1334} 1391}
1335#endif 1392#endif // ERROR_FULL_STACK
1336 1393
1337#if defined PLATFORM_WIN32 && !defined __GNUC__ 1394#if defined PLATFORM_WIN32 && !defined __GNUC__
1338//see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx 1395//see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
@@ -1408,6 +1465,11 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs)
1408 lua_setglobal( L, "cancel_test" ); 1465 lua_setglobal( L, "cancel_test" );
1409 1466
1410#ifdef ERROR_FULL_STACK 1467#ifdef ERROR_FULL_STACK
1468 // Tie "set_error_reporting()" to the state
1469 //
1470 lua_pushcfunction( L, LG_set_error_reporting);
1471 lua_setglobal( L, "set_error_reporting");
1472
1411 STACK_GROW( L, 1 ); 1473 STACK_GROW( L, 1 );
1412 lua_pushcfunction( L, lane_error ); 1474 lua_pushcfunction( L, lane_error );
1413 lua_insert( L, 1 ); 1475 lua_insert( L, 1 );
@@ -1885,7 +1947,7 @@ static bool_t thread_cancel( struct s_lane *s, double secs, bool_t force)
1885 1947
1886LUAG_FUNC( thread_cancel) 1948LUAG_FUNC( thread_cancel)
1887{ 1949{
1888 if( lua_gettop( L) != 1 || lua_type( L, 1) != LUA_TUSERDATA) 1950 if( lua_gettop( L) < 1 || lua_type( L, 1) != LUA_TUSERDATA)
1889 { 1951 {
1890 return luaL_error( L, "invalid argument #1, did you use ':' as you should?"); 1952 return luaL_error( L, "invalid argument #1, did you use ':' as you should?");
1891 } 1953 }