aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.c
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 /src/lanes.c
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()
Diffstat (limited to 'src/lanes.c')
-rw-r--r--src/lanes.c168
1 files changed, 115 insertions, 53 deletions
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 }