From 79e46938c5d8daf164ab2d934f668fa27b32e4cf Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Tue, 4 Jan 2011 21:31:17 +0100 Subject: Take all code from Asko Kauppi's SVN server, and push it here so that the github repository becomes the official Lanes source codebase. Note that Asko's SVN server holds version 2.0.9, whereas this is version 2.0.10, but I don't see any real need to update SVN if it is to become deprecated. Next steps: - upgrade the rockspec to the latest version - make the html help available online somewhere Signed-off-by: Benoit Germain --- BUGS | 111 +++ CHANGES | 74 +- COPYRIGHT | 2 +- Makefile | 7 + TODO | 17 + docs/comparison.html | 28 +- docs/index.html | 44 +- lanes-2.0-2.rockspec | 95 +++ lanes-2.0.2.tgz | Bin 0 -> 312965 bytes setup-vc.cmd | 8 +- src/keeper.lua | 4 +- src/lanes.c | 732 +++++++++++------ src/lanes.lua | 33 +- src/threading.c | 9 +- src/tools.c | 260 +++--- src/tools.h | 2 + tests/appendud.lua | 58 ++ tests/basic.lua | 52 +- tests/func_is_string.lua | 12 + xcode/xcode.xcodeproj/abisoft.mode1 | 1460 +++++++++++++++++++++++++++++++++ xcode/xcode.xcodeproj/abisoft.pbxuser | 411 ++++++++++ xcode/xcode.xcodeproj/project.pbxproj | 268 ++++++ xcode/xcode.xcodeproj/soumya.pbxuser | 124 +++ 23 files changed, 3319 insertions(+), 492 deletions(-) create mode 100644 lanes-2.0-2.rockspec create mode 100644 lanes-2.0.2.tgz create mode 100644 tests/appendud.lua create mode 100644 tests/func_is_string.lua create mode 100644 xcode/xcode.xcodeproj/abisoft.mode1 create mode 100644 xcode/xcode.xcodeproj/abisoft.pbxuser create mode 100644 xcode/xcode.xcodeproj/project.pbxproj create mode 100644 xcode/xcode.xcodeproj/soumya.pbxuser diff --git a/BUGS b/BUGS index d25cc0e..9ae6db5 100644 --- a/BUGS +++ b/BUGS @@ -1,6 +1,117 @@ BUGS: +- Reported by Pierre LeMoine (Dec-2009: +<< +Hi! +I think i've located an error in Lanes. When a finalizer is called, it +receive two tables. The second one seems to be the table containing +the finalizers. The attached test reproduces the error, and is tested +on binaries built by myself and from the LfW project. +The following line from run_finalizers in lanes.c seems to be wrong to me: + + error_index= (lua_rc!=0) ? tbl_index-1 : 0; // absolute indices + +I think it should be -2 there, since the stack at this point should look like +[-1] finalizer table <- tbl_index +[-2] stack table +[-3] error string + +Also, in some places, checks for valid returns from lua_toLinda are +missing, leading to crashes. (for example, linda.get) + +Sometimes when i use lanes i get a "recursive use of upvalues"-error, +i fail to see how upvalues can be recursive? =) + +/Pierre +<< + + +- Reported by Benoit Germain (Dec-2009): +<< +Doc says : + +The current execution state of a lane can be read via its status member, providing one of these values: + + +"waiting" waiting at a Linda :receive() or :send() + + + +But code and test say otherwise : lane status remains « running » even when waiting on a Linda operation, which is quite understandable since nowhere in the code status is changed to WAITING. This is a problem for me because my lanes are consumers waiting for commands on a linda. « waiting » status is the only means I have to ensure that a command is not currently being processed. Therefore the fix, to make Lanes behave as the documentation states : + +LUAG_FUNC( linda_receive ) { + ... + // BBB HACK: fetch the lane object to update the status + { + struct s_lane *s; + enum e_status prev_status; + STACK_GROW(L,1); + + STACK_CHECK(L) + lua_pushlightuserdata( L, CANCEL_TEST_KEY ); + lua_rawget( L, LUA_REGISTRYINDEX ); + s= lua_touserdata( L, -1 ); // lightuserdata (true 's_lane' pointer) / nil + lua_pop(L,1); + STACK_END(L,0) + if( s) + { + prev_status = s->status; + s->status = WAITING; + } + if (!SIGNAL_WAIT( &linda->write_happened, &K->lock_, timeout )) + { + if( s) s->status = prev_status; + break; + } + if( s) s->status = prev_status; + } + +Of course, the same has to be done in linda_send, and lane structure retrieval could be factorized with the cancel_test. Anyway, what I am concerned about now is whether I missed something or not. Can the lane status change while waiting, so that restoring the previous value could cause problems? +<< + + +- The use of 'static' and "one time" initialization of things is not suitable +to a situation where a Lua state is run, using Lanes, then terminated. If +another Lua state later is launched, the initializations will get cramped. + +Reported by Boris Ouretskey (25-Jun-09) + + +- a 'require "lanes"' and speedy exit from the process causes a segfault + on ArchLinux (reported by kkndrox@gmail.com 1-Jun-2009). + + This issue is not reproducible on Ubuntu (8.04 or 9.04) and has not therefore + been fixed. A patch is welcome. The issue is most likely caused by the + Linda thread not being properly launched when the process itself already + quits. + +<< +With Lanes 2.0.3, the following code *always* gives me a segmentation +fault: + +-- begin +require("lanes") +-- end + +But this: + +-- begin +require("lanes") +garbagecollect('collect') +-- end + +always work. + +Based on this experimentation, if I require lanes and the program end +without any garbage collecting, I receive a segmentation fault. +I'm using Arch Linux (32bits), Lua 5.1.4 and it was compiled with gcc 4.3 +<< + + Also simply waiting a bit ('os.execute("sleep 1")') avoids the crash. + + - tests/irayo_closure.lua fails (trouble with setting globals right for functions carried over to another Lua state) +- "make appendud" causes a segfault on OS X PowerPC. diff --git a/CHANGES b/CHANGES index ae4da3c..c41e36d 100644 --- a/CHANGES +++ b/CHANGES @@ -3,11 +3,51 @@ CHANGES: CHANGE X: +CHANGE 21 (bugfixes) BGe 3-Jan-2011: + Several fixes by Martin Krpan: + - linda_send was waiting on the wrong signal + - buildfix when using i586-mingw32msvc-gcc cross compiler + - lanes_h:cancel() returns a boolean as it should + - timers could get blocked sometimes because they were initialized with negative values + - prepare_timeout could generate an illegal setting + +CHANGE 20 BGe 3-Dec-2010: + Enable to specify a string as lane code instead of a function so that we dont use lua_dump, which + isn't supported by LuaJIT. + +CHANGE 19 BGe 2-Dec-2010: + No longer rely on global function 'tostring' to generate unique identifiers when caching data being transfered through la linda. Should fix a compatilibity issue with LuaJIT2. + +CHANGE 18 BGe 6-Oct-2010: + Fixed 'memory leak' in some situations where a free running lane is collected before application shutdown + A bit of code cleanup + +CHANGE 17 BGe 21-Sept-2010: + Fixed stupid compilation errors. + +CHANGE 16 PLM 24-Aug-2010: + Releasing memory at gc / atexit. + Finalizers actually get error strings. + Fixed missing argument propagation in lane:cancel + Added variable threadName sent trough globals-table. Set in s_lane, and in debuggers on windows. + Added argument checking for linda-objects, where missing them caused crashes. + +CHANGE 15 (minor) BGe 27-Jul-2010: + Version bump for a true upgrade release (2.0.4 package was only a renamed 2.0.3) + +CHANGE 14 (bug fix) BGe 09-Jul-2010: + Fixed lane status to be correctly returned as "waiting" when it should. + +CHANGE 13 (fix for multithreaded host apps) AKa 24-Jun-2009: + mentioned Lanes expects the host application to be singlethreaded, + and there are troubles if Lanes is used from multiple threads, opened by the host + (before requiring Lanes). This is true, and fix should now be in place. + CHANGE 12 (bug fix on Windows, 2.0.3) AKa 25-Jan-2009: Did CHANGE 9 the way it should be done. CHANGE 11 (new feature, 2.0.3) AKa 23-Jan-2009: - Finalizers ('set_finalizer()') for being able to do cleanup of a lane's + Finalizers ('set_finalizer()') for being able to do cleanup of a lane's resources, whether it returned succesfully or via an error. CHANGE 10 (new feature, 2.0.3) AKa 23-Jan-2009: @@ -18,12 +58,12 @@ CHANGE 10 (new feature, 2.0.3) AKa 23-Jan-2009: CHANGE 9 (bug fix on Windows) AKa 10-Dec-2008 (> 2.0.2): Applied patch from Kriss Daniels to avoid issues on 'now_time()' in Win32 (http://luaforge.net/forum/forum.php?thread_id=22704&forum_id=1781). - + CHANGE 8 (bug fix) AKa 26-Oct-2008: Avoids occasional segfault at process exit (on multicore CPUs). Does this by keeping track of "free running" threads (s.a. the time thread) and - cancelling them at process exit. - + cancelling them at process exit. + Tested (2.0.2) on Linux 64,x86, OS X, WinXP. CHANGE 7 (bug fix) AKa 15-Oct-2008: @@ -34,15 +74,15 @@ CHANGE 6 (bug fix) AKa 15-Oct-2008: Added local caches of the following to src/lanes.lua (was otherwise getting errors at least in 'tests/irayo_recursive.lua'). - local assert= assert - local string_gmatch= assert( string.gmatch ) - local select= assert( select ) - local type= assert( type ) - local pairs= assert( pairs ) - local tostring= assert( tostring ) - local error= assert( error ) - local setmetatable= assert( setmetatable ) - local rawget= assert( rawget ) + local assert= assert + local string_gmatch= assert( string.gmatch ) + local select= assert( select ) + local type= assert( type ) + local pairs= assert( pairs ) + local tostring= assert( tostring ) + local error= assert( error ) + local setmetatable= assert( setmetatable ) + local rawget= assert( rawget ) Thanks to Irayo for detecting and reporting this. @@ -55,17 +95,17 @@ CHANGE 4 (new feature): CHANGE 3 (bug fix) AKa 5-Aug-2008: The '__gc' method was not tied to thread userdata, at all. Caused memory lifespan problems at least on OS X when threads were cancelled (EINVAL). - + CHANGE 2 (bug fix) AKa 5-Aug-2008: Better calculation of timeouts, always making them absolute (even in Win32) to allow for events that wake the lane up but don't read/write the Linda key that it was observing. CHANGE 1 (bug fix) AKa 4-Aug-2008: - Signalling woke up only one waiting thread, not all. This caused i.e. - receive to not wake up if there was another thread waiting on the same + Signalling woke up only one waiting thread, not all. This caused i.e. + receive to not wake up if there was another thread waiting on the same Linda object. - + PThread fix: using 'pthread_cond_broadcast()' instead of 'pthread_cond_signal()' Win32 fix: using manual events and 'PulseEvent()' diff --git a/COPYRIGHT b/COPYRIGHT index 2930f19..d6b0008 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -6,7 +6,7 @@ For details and rationale, see http://www.lua.org/license.html =============================================================================== -Copyright (C) 2007-09 Asko Kauppi, +Copyright (C) 2007-11 Asko Kauppi, Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 4c0ff4b..b4a78cc 100644 --- a/Makefile +++ b/Makefile @@ -82,6 +82,7 @@ test: $(MAKE) objects $(MAKE) fibonacci $(MAKE) recursive + $(MAKE) func_is_string basic: tests/basic.lua $(_TARGET_SO) $(_PREFIX) $(LUA) $< @@ -143,6 +144,12 @@ finalizer: tests/finalizer.lua $(_TARGET_SO) error-test: tests/error.lua $(_TARGET_SO) $(_PREFIX) $(LUA) $< +appendud: tests/appendud.lua $(_TARGET_SO) + $(_PREFIX) $(LUA) $< + +func_is_string: tests/func_is_string.lua $(_TARGET_SO) + $(_PREFIX) $(LUA) $< + #--- perftest-plain: tests/perftest.lua $(_TARGET_SO) $(MAKE) _perftest ARGS="$< $(N) -plain" diff --git a/TODO b/TODO index 7c4c3d8..2846384 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,21 @@ TODO: +- Use of 'atexit()' is not good. It's possible to be called at "program (process) + exit", when the so might already be out. Tying to OS specific so cleanup + is way better. + - Testing Lane killing (not cancellation, but actual killing) + +- Like luaproc: Lanes to have M:N relationship to kernel threads + (= give a maximum number of kernel threads to run, then juggle those to run a Lane, + until the lane suspends, blocks, or exits) + (default could be twice the kernel threads of the CPU count, or something.) + +- Like luaproc: +"only the basic standard +library and our own library are automatically loaded into each new Lua process. The re- +maining standard libraries (io, os, table, string, math, and debug) are pre-registered and +can be loaded with a standard call to Lua’s require function. " + +- Lanes so/dll to have a second interface; C code sending data to a linda of given void* diff --git a/docs/comparison.html b/docs/comparison.html index 84ef9ca..bebc68b 100644 --- a/docs/comparison.html +++ b/docs/comparison.html @@ -49,6 +49,7 @@ Pros: Cons: - requires OS threads + - currently 1:1 mapping to OS threads (limits scalability and maybe performance) - not utilizing network parallelism (all threads on one CPU) Sample: @@ -70,6 +71,31 @@ Sample: << +=========== + luaproc (by Skyrme, Rodriguez and Ierusalimschy) +=========== + +http://www.inf.puc-rio.br/~roberto/docs/ry08-05.pdf + +The PDF seems to be an authorative voyage into how Lua could handle multithreading, +in a multicore "separate universes" manner (not like what coroutines already do). + +Pros: + - Tackles both multicore and network parallelism + - M:N relationship to kernel threads (one kernel thread runs multiple luaprocs) + - Simple (so they say) + - Lua author (Roberto) included + - Can be used also without _any_ OS threading support (works like Rings, then) + +Cons: + - Data passing for "strings, number, or booleans" only + "More complex types must be encoded in some form" + (serializing data is slower than the stack-to-stack copies used by i.e. Lanes) + (yet, serializing allows for network parallelism) + - Message passing is synchronous (only). The sender will wait until the + receiver has taken the message. + + ================== Lua coroutines (by Lua authors) ================== @@ -157,7 +183,7 @@ but it won't use more than one CPU core. Other differences include: (Lanes opens the needed ones) - marshalls numbers, strings, booleans, userdata - (Lanes marshalls also non-cyclic tables) + (Lanes also marshalls tables, functions, upvalues, ..) - "remotedostring" allows executing code in the master state (Lanes does _not_ allow subthreads to trouble/modify master automatically, diff --git a/docs/index.html b/docs/index.html index 956e691..45b52bc 100644 --- a/docs/index.html +++ b/docs/index.html @@ -54,9 +54,9 @@ Change log -


Copyright © 2007-08 Asko Kauppi. All rights reserved. +


Copyright © 2007-11 Asko Kauppi. All rights reserved.
Lua Lanes is published under the same MIT license as Lua 5.1. -

This document was revised on 23-Jan-09, and applies to version 2.0.3. +

This document was revised on 3-Jan-11, and applies to version 2.0.10.

@@ -195,6 +195,9 @@ joins the threads, waiting for any results not already there. launching any number of lanes. They will share code, options, initial globals, but the particular arguments may vary. Only calling the generator function actually launches a lane, and provides a handle for controlling it. + Alternatively, lane_func may be a string, in which case it will be compiled + in the lane. This is to be able to launch lanes whith LuaJIT, + which does not support lua_dump, used internally to transfer functions to the lane.
@@ -378,7 +387,7 @@ If the lane is still running and force_kill is true, the OS thread running the lane is forcefully killed. This means no GC, and should generally be the last resort.

-

Cancellation is tested before going to sleep in receive() or send() calls +

Cancellation is tested before going to sleep in receive() or send() calls and after executing cancelstep Lua statements. A currently pending receive or send call is currently not awakened, and may be a reason for a non-detected cancel.

@@ -920,6 +929,30 @@ its actual value.

Change log

+Jan-2011 (2.0.10): +

    +
  • linda_send was waiting on the wrong signal
  • +
  • buildfix when using i586-mingw32msvc-gcc cross compiler
  • +
  • lanes_h:cancel() returns a boolean as it should
  • +
  • timers could get blocked sometimes because they were initialized with negative values
  • +
  • prepare_timeout could generate an illegal setting
  • +
+ +Dec-2010 (2.0.9): +
    +
  • Fixed 'memory leak' in some situations where a free running lane is collected before application shutdown
  • +
  • Fix LuaJIT2 incompatibility (no 'tostring' hijack anymore)
  • +
  • Added support to generate a lane from a string
  • +
+ +Aug-2010 (2.0.6): +
    +
  • Fixed some memory leaks
  • +
  • Fixed error in passing parameters to finalizers
  • +
  • Fixed missing argument propagation in lane:cancel
  • +
  • Added thread name debugging in VS
  • +
+ Jan-2009 (2.0.3):
  • Added 'finalizer' to lane options. (TBD: not implemented yet!) @@ -942,6 +975,7 @@ Jul-2008 (2.0):

    diff --git a/lanes-2.0-2.rockspec b/lanes-2.0-2.rockspec new file mode 100644 index 0000000..407a622 --- /dev/null +++ b/lanes-2.0-2.rockspec @@ -0,0 +1,95 @@ +-- +-- Lanes rockspec +-- +-- Ref: +-- +-- +-- History: +-- AKa 1-Sep-2008: 2.0-2 (NOT sent to list): fixed VC++ not finding DLL issue +-- AKa 20-Aug-2008: 2.0-1 sent to luarocks-developers +-- + +package = "Lanes" + +version = "2.0-2" + +source= { + url= "http://akauppi.googlepages.com/lanes-2.0.tgz", + md5= "27a807828de0bda3787dbcd2d4947019" +} + +description = { + summary= "Multithreading support for Lua", + detailed= [[ + Lua Lanes is a portable, message passing multithreading library + providing the possibility to run multiple Lua states in parallel. + ]], + license= "MIT/X11", + homepage="http://kotisivu.dnainternet.net/askok/lanes/", + maintainer="Asko Kauppi " +} + +-- Q: What is the difference of "windows" and "win32"? Seems there is none; +-- so should we list either one or both? +-- +supported_platforms= { "win32", + "macosx", + "linux", + "freebsd", -- TBD: not tested + "msys", -- TBD: not supported by LuaRocks 1.0 (or is it?) +} + +dependencies= { + "lua >= 5.1, < 5.2", +} + +-- +-- Non-Win32: build using the Makefile +-- Win32: build using 'make-vc.cmd' and "manual" copy of products +-- +-- TBD: How is MSYS treated? We'd like (really) it to use the Makefile. +-- It should be a target like "cygwin", not defining "windows". +-- "windows" should actually guarantee Visual C++ as the compiler. +-- +-- Q: Does "win32" guarantee we have Visual C++ 2005/2008 command line tools? +-- +-- Note: Cannot use the simple "module" build type, because we need to precompile +-- 'src/keeper.lua' -> keeper.lch and bake it into lanes.c. +-- +build = { + + -- Win32 (Visual C++) uses 'make-vc.cmd' for building + -- + platforms= { + windows= { + type= "command", + build_command= "make-vc.cmd", + install= { + lua = { "src/lanes.lua" }, + lib = { "lua51-lanes.dll" } + } + } + }, + + -- Other platforms use the Makefile + -- + -- LuaRocks defines CFLAGS, LIBFLAG and LUA_INCDIR for 'make rock', + -- defines LIBDIR, LUADIR for 'make install' + -- + -- Ref: + -- + type = "make", + + build_target = "rock", + build_variables= { + CFLAGS= "$(CFLAGS) -I$(LUA_INCDIR)", + LIBFLAG= "$(LIBFLAG)", + }, + + install_target = "install", + install_variables= { + LUA_LIBDIR= "$(LIBDIR)", + LUA_SHAREDIR= "$(LUADIR)", + } +} + diff --git a/lanes-2.0.2.tgz b/lanes-2.0.2.tgz new file mode 100644 index 0000000..666de3b Binary files /dev/null and b/lanes-2.0.2.tgz differ diff --git a/setup-vc.cmd b/setup-vc.cmd index e93262e..247459c 100644 --- a/setup-vc.cmd +++ b/setup-vc.cmd @@ -17,19 +17,19 @@ REM Test for VC++2005 FIRST, because it is the norm with Lua 5.1.4 REM LuaBinaries and LfW. All prebuilt modules and lua.exe are built REM with it. REM -set VSINSTALLDIR=C:\Program Files\Microsoft Visual Studio 8 +set VSINSTALLDIR=%ProgramFiles%\Microsoft Visual Studio 8 if not exist "%VSINSTALLDIR%\VC\vcvarsall.bat" goto TRY_VC9 REM Win32 headers must be separately downloaded for VC++2005 REM (VC++2008 SP1 carries an SDK with it) REM -set _SDK=C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\SetEnv.cmd +set _SDK=%ProgramFiles%\Microsoft Platform SDK for Windows Server 2003 R2\SetEnv.cmd if not exist "%_SDK%" goto ERR_NOSDK call "%_SDK%" goto FOUND_VC :TRY_VC9 -set VSINSTALLDIR=C:\Program Files\Microsoft Visual Studio 9.0 +set VSINSTALLDIR=%ProgramFiles%\Microsoft Visual Studio 9.0 if not exist "%VSINSTALLDIR%\VC\vcvarsall.bat" goto ERR_NOVC echo. @@ -54,7 +54,7 @@ call "%VSINSTALLDIR%\VC\vcvarsall.bat" REM 'timeit.exe' is part of the MS Server Res Kit Tools (needed for "make perftest") REM -set _RESKIT=C:\Program Files\Windows Resource Kits\Tools\ +set _RESKIT=%ProgramFiles%\Windows Resource Kits\Tools\ if not exist "%_RESKIT%\timeit.exe" goto WARN_NOTIMEIT PATH=%PATH%;%_RESKIT% goto EXIT diff --git a/src/keeper.lua b/src/keeper.lua index f76173b..9256a4b 100644 --- a/src/keeper.lua +++ b/src/keeper.lua @@ -11,7 +11,7 @@ --[[ =============================================================================== -Copyright (C) 2008 Asko Kauppi +Copyright (C) 2008-10 Asko Kauppi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -135,7 +135,7 @@ function send( ud, key, ... ) local m= limits[key] if m and len+n > m then - return false -- would exceed the limit; try again later + return false -- would exceed the limit; try again later end for i=1,n do diff --git a/src/lanes.c b/src/lanes.c index 9b36e4d..ba9e59a 100644 --- a/src/lanes.c +++ b/src/lanes.c @@ -4,6 +4,13 @@ * Multithreading in Lua. * * History: + * 3-Jan-11 (2.0.10): linda_send bugfix, was waiting on the wrong signal + * 3-Dec-10 (2.0.9): Added support to generate a lane from a string + * 2-Dec-10 (2.0.8): Fix LuaJIT2 incompatibility (no 'tostring' hijack anymore) + * ???????? (2.0.7): Fixed 'memory leak' in some situations where a free running + * lane is collected before application shutdown + * 24-Aug-10 (2.0.6): Mem fixes, argument checking (lua_toLinda result), thread name + * 24-Jun-09 (2.0.4): Made friendly to already multithreaded host apps. * 20-Oct-08 (2.0.2): Added closing of free-running threads, but it does * not seem to eliminate the occasional segfaults at process * exit. @@ -13,10 +20,9 @@ * 18-Sep-06 AKa: Started the module. * * Platforms (tested internally): - * OS X (10.5.4 PowerPC/Intel) + * OS X (10.5.7 PowerPC/Intel) * Linux x86 (Ubuntu 8.04) * Win32 (Windows XP Home SP2, Visual C++ 2005/2008 Express) - * PocketPC (TBD) * * Platforms (tested externally): * Win32 (MSYS) by Ross Berteig. @@ -54,15 +60,16 @@ * * To-do: * + * Make waiting threads cancelable. * ... */ -const char *VERSION= "2.0.3"; +const char *VERSION= "2.0.10"; /* =============================================================================== -Copyright (C) 2007-08 Asko Kauppi +Copyright (C) 2007-10 Asko Kauppi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -84,10 +91,11 @@ THE SOFTWARE. =============================================================================== */ + #include #include -#include #include +#include #include "lua.h" #include "lauxlib.h" @@ -127,7 +135,59 @@ THE SOFTWARE. static char keeper_chunk[]= #include "keeper.lch" -struct s_lane; +// NOTE: values to be changed by either thread, during execution, without +// locking, are marked "volatile" +// +struct s_lane { + THREAD_T thread; + // + // M: sub-thread OS thread + // S: not used + + char threadName[64]; //Optional, for debugging and such. owerflowable by a strcpy. + + lua_State *L; + // + // M: prepares the state, and reads results + // S: while S is running, M must keep out of modifying the state + + volatile enum e_status status; + // + // M: sets to PENDING (before launching) + // S: updates -> RUNNING/WAITING -> DONE/ERROR_ST/CANCELLED + + volatile bool_t cancel_request; + // + // M: sets to FALSE, flags TRUE for cancel request + // S: reads to see if cancel is requested + +#if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) + SIGNAL_T done_signal_; + // + // M: Waited upon at lane ending (if Posix with no PTHREAD_TIMEDJOIN) + // S: sets the signal once cancellation is noticed (avoids a kill) + + MUTEX_T done_lock_; + // + // Lock required by 'done_signal' condition variable, protecting + // lane status changes to DONE/ERROR_ST/CANCELLED. +#endif + + volatile enum { + NORMAL, // normal master side state + KILLED // issued an OS kill + } mstatus; + // + // M: sets to NORMAL, if issued a kill changes to KILLED + // S: not used + + struct s_lane * volatile selfdestruct_next; + // + // M: sets to non-NULL if facing lane handle '__gc' cycle but the lane + // is still running + // S: cleans up after itself if non-NULL at lane exit +}; + static bool_t cancel_test( lua_State *L ); static void cancel_error( lua_State *L ); @@ -360,10 +420,11 @@ int keeper_call( lua_State* K, const char *func_name, int Ktos= lua_gettop(K); int retvals; + STACK_GROW( K, 2 ); + lua_getglobal( K, func_name ); ASSERT_L( lua_isfunction(K,-1) ); - STACK_GROW( K, 1 ); lua_pushlightuserdata( K, linda ); luaG_inter_copy( L,K, args ); // L->K @@ -408,6 +469,8 @@ LUAG_FUNC( linda_send ) { struct s_Keeper *K; time_d timeout= -1.0; uint_t key_i= 2; // index of first key, if timeout not there + + luaL_argcheck( L, linda, 1, "expected a linda object!"); if (lua_isnumber(L,2)) { timeout= SIGNAL_TIMEOUT_PREPARE( lua_tonumber(L,2) ); @@ -449,10 +512,36 @@ STACK_MID(KL,0) cancel= cancel_test( L ); // testing here causes no delays if (cancel) break; +// Bugfix by Benoit Germain Dec-2009: change status of lane to "waiting" +// +#if 1 +{ + struct s_lane *s; + enum e_status prev_status = ERROR_ST; // prevent 'might be used uninitialized' warnings + STACK_GROW(L,1); + + STACK_CHECK(L) + lua_pushlightuserdata( L, CANCEL_TEST_KEY ); + lua_rawget( L, LUA_REGISTRYINDEX ); + s= lua_touserdata( L, -1 ); // lightuserdata (true 's_lane' pointer) / nil + lua_pop(L,1); + STACK_END(L,0) + if (s) { + prev_status = s->status; + s->status = WAITING; + } + if (!SIGNAL_WAIT( &linda->read_happened, &K->lock_, timeout )) { + if (s) { s->status = prev_status; } + break; + } + if (s) s->status = prev_status; +} +#else // K lock will be released for the duration of wait and re-acquired // if (!SIGNAL_WAIT( &linda->read_happened, &K->lock_, timeout )) break; // timeout +#endif } } STACK_END(KL,0) @@ -483,6 +572,8 @@ LUAG_FUNC( linda_receive ) { time_d timeout= -1.0; uint_t key_i= 2; + luaL_argcheck( L, linda, 1, "expected a linda object!"); + if (lua_isnumber(L,2)) { timeout= SIGNAL_TIMEOUT_PREPARE( lua_tonumber(L,2) ); key_i++; @@ -509,10 +600,36 @@ LUAG_FUNC( linda_receive ) { cancel= cancel_test( L ); // testing here causes no delays if (cancel) break; +// Bugfix by Benoit Germain Dec-2009: change status of lane to "waiting" +// +#if 1 +{ + struct s_lane *s; + enum e_status prev_status = ERROR_ST; // prevent 'might be used uninitialized' warnings + STACK_GROW(L,1); + + STACK_CHECK(L) + lua_pushlightuserdata( L, CANCEL_TEST_KEY ); + lua_rawget( L, LUA_REGISTRYINDEX ); + s= lua_touserdata( L, -1 ); // lightuserdata (true 's_lane' pointer) / nil + lua_pop(L,1); + STACK_END(L,0) + if (s) { + prev_status = s->status; + s->status = WAITING; + } + if (!SIGNAL_WAIT( &linda->write_happened, &K->lock_, timeout )) { + if (s) { s->status = prev_status; } + break; + } + if (s) s->status = prev_status; +} +#else // Release the K lock for the duration of wait, and re-acquire // if (!SIGNAL_WAIT( &linda->write_happened, &K->lock_, timeout )) break; +#endif } } } @@ -535,8 +652,11 @@ LUAG_FUNC( linda_receive ) { LUAG_FUNC( linda_set ) { struct s_Linda *linda= lua_toLinda( L, 1 ); bool_t has_value= !lua_isnil(L,3); + struct s_Keeper *K; - struct s_Keeper *K= keeper_acquire( linda ); + luaL_argcheck( L, linda, 1, "expected a linda object!"); + + K= keeper_acquire( linda ); { int pushed= keeper_call( K->L, "set", L, linda, 2 ); ASSERT_L( pushed==0 ); @@ -561,8 +681,11 @@ LUAG_FUNC( linda_set ) { LUAG_FUNC( linda_get ) { struct s_Linda *linda= lua_toLinda( L, 1 ); int pushed; + struct s_Keeper *K; - struct s_Keeper *K= keeper_acquire( linda ); + luaL_argcheck( L, linda, 1, "expected a linda object!"); + + K= keeper_acquire( linda ); { pushed= keeper_call( K->L, "get", L, linda, 2 ); ASSERT_L( pushed==0 || pushed==1 ); @@ -580,8 +703,11 @@ LUAG_FUNC( linda_get ) { */ LUAG_FUNC( linda_limit ) { struct s_Linda *linda= lua_toLinda( L, 1 ); + struct s_Keeper *K; + + luaL_argcheck( L, linda, 1, "expected a linda object!"); - struct s_Keeper *K= keeper_acquire( linda ); + K= keeper_acquire( linda ); { int pushed= keeper_call( K->L, "limit", L, linda, 2 ); ASSERT_L( pushed==0 ); @@ -604,6 +730,7 @@ LUAG_FUNC( linda_limit ) { */ LUAG_FUNC( linda_deep ) { struct s_Linda *linda= lua_toLinda( L, 1 ); + luaL_argcheck( L, linda, 1, "expected a linda object!"); lua_pushlightuserdata( L, linda ); // just the address return 1; } @@ -761,13 +888,13 @@ static int run_finalizers( lua_State *L, int lua_rc ) return 0; // no finalizers tbl_index= lua_gettop(L); - error_index= (lua_rc!=0) ? tbl_index-1 : 0; // absolute indices + error_index= (lua_rc!=0) ? tbl_index-2 : 0; // absolute indices STACK_GROW(L,4); // [-1]: { func [, ...] } // - for( n= lua_objlen(L,-1); n>0; n-- ) { + for( n= (unsigned int)lua_objlen(L,-1); n>0; n-- ) { unsigned args= 0; lua_pushinteger( L,n ); lua_gettable( L, -2 ); @@ -805,57 +932,6 @@ static int run_finalizers( lua_State *L, int lua_rc ) /*---=== Threads ===--- */ -// NOTE: values to be changed by either thread, during execution, without -// locking, are marked "volatile" -// -struct s_lane { - THREAD_T thread; - // - // M: sub-thread OS thread - // S: not used - - lua_State *L; - // - // M: prepares the state, and reads results - // S: while S is running, M must keep out of modifying the state - - volatile enum e_status status; - // - // M: sets to PENDING (before launching) - // S: updates -> RUNNING/WAITING -> DONE/ERROR_ST/CANCELLED - - volatile bool_t cancel_request; - // - // M: sets to FALSE, flags TRUE for cancel request - // S: reads to see if cancel is requested - -#if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) - SIGNAL_T done_signal_; - // - // M: Waited upon at lane ending (if Posix with no PTHREAD_TIMEDJOIN) - // S: sets the signal once cancellation is noticed (avoids a kill) - - MUTEX_T done_lock_; - // - // Lock required by 'done_signal' condition variable, protecting - // lane status changes to DONE/ERROR_ST/CANCELLED. -#endif - - volatile enum { - NORMAL, // normal master side state - KILLED // issued an OS kill - } mstatus; - // - // M: sets to NORMAL, if issued a kill changes to KILLED - // S: not used - - struct s_lane * volatile selfdestruct_next; - // - // M: sets to non-NULL if facing lane handle '__gc' cycle but the lane - // is still running - // S: cleans up after itself if non-NULL at lane exit -}; - static MUTEX_T selfdestruct_cs; // // Protects modifying the selfdestruct chain @@ -985,11 +1061,13 @@ static void selfdestruct_atexit( void ) { // Linux (at least 64-bit): CAUSES A SEGFAULT IF THIS BLOCK IS ENABLED // and works without the block (so let's leave those lanes running) // -#if 1 +//we want to free memory and such when we exit. +#if 0 // 2.0.2: at least timer lane is still here // - //fprintf( stderr, "Left %d lane(s) with cancel request at process end.\n", n ); + DEBUGEXEC(fprintf( stderr, "Left %d lane(s) with cancel request at process end.\n", n )); #else + n=0; MUTEX_LOCK( &selfdestruct_cs ); { struct s_lane *s= selfdestruct_first; @@ -998,6 +1076,8 @@ static void selfdestruct_atexit( void ) { s->selfdestruct_next= NULL; // detach from selfdestruct chain THREAD_KILL( &s->thread ); + lua_close(s->L); + free(s); s= next_s; n++; } @@ -1005,9 +1085,16 @@ static void selfdestruct_atexit( void ) { } MUTEX_UNLOCK( &selfdestruct_cs ); - fprintf( stderr, "Killed %d lane(s) at process end.\n", n ); + DEBUGEXEC(fprintf( stderr, "Killed %d lane(s) at process end.\n", n )); #endif } + { + int i; + for(i=0;iL; - s->status= RUNNING; // PENDING -> RUNNING + +#if defined PLATFORM_WIN32 && !defined __GNUC__ + SetThreadName(-1, s->threadName); +#endif + + s->status= RUNNING; // PENDING -> RUNNING // Tie "set_finalizer()" to the state // @@ -1243,7 +1367,7 @@ static int lane_error( lua_State *L ) { // We're a free-running thread and no-one's there to clean us up. // lua_close( s->L ); - L= 0; + s->L = L = 0; #if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) SIGNAL_FREE( &s->done_signal_ ); @@ -1290,121 +1414,144 @@ static int lane_error( lua_State *L ) { // LUAG_FUNC( thread_new ) { - lua_State *L2; - struct s_lane *s; - struct s_lane **ud; - - const char *libs= lua_tostring( L, 2 ); - uint_t cs= luaG_optunsigned( L, 3,0); - int prio= luaL_optinteger( L, 4,0); - uint_t glob= luaG_isany(L,5) ? 5:0; - - #define FIXED_ARGS (5) - uint_t args= lua_gettop(L) - FIXED_ARGS; - - if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) { - luaL_error( L, "Priority out of range: %d..+%d (%d)", - THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio ); - } - - /* --- Create and prepare the sub state --- */ - - L2 = luaL_newstate(); // uses standard 'realloc()'-based allocator, - // sets the panic callback - - if (!L2) luaL_error( L, "'luaL_newstate()' failed; out of memory" ); - - STACK_GROW( L,2 ); - - // Setting the globals table (needs to be done before loading stdlibs, - // and the lane function) - // - if (glob!=0) { -STACK_CHECK(L) - if (!lua_istable(L,glob)) - luaL_error( L, "Expected table, got %s", luaG_typename(L,glob) ); - - lua_pushvalue( L, glob ); - luaG_inter_move( L,L2, 1 ); // moves the table to L2 - - // L2 [-1]: table of globals - - // "You can change the global environment of a Lua thread using lua_replace" - // (refman-5.0.pdf p. 30) - // - lua_replace( L2, LUA_GLOBALSINDEX ); -STACK_END(L,0) - } - - // Selected libraries - // - if (libs) { - const char *err= luaG_openlibs( L2, libs ); - ASSERT_L( !err ); // bad libs should have been noticed by 'lanes.lua' - - serialize_require( L2 ); - } - - // Lane main function - // -STACK_CHECK(L) - lua_pushvalue( L, 1 ); - luaG_inter_move( L,L2, 1 ); // L->L2 -STACK_MID(L,0) - - ASSERT_L( lua_gettop(L2) == 1 ); - ASSERT_L( lua_isfunction(L2,1) ); - - // revive arguments - // - if (args) luaG_inter_copy( L,L2, args ); // L->L2 -STACK_MID(L,0) - -ASSERT_L( (uint_t)lua_gettop(L2) == 1+args ); -ASSERT_L( lua_isfunction(L2,1) ); - - // 's' is allocated from heap, not Lua, since its life span may surpass - // the handle's (if free running thread) - // - ud= lua_newuserdata( L, sizeof(struct s_lane*) ); - ASSERT_L(ud); - - s= *ud= malloc( sizeof(struct s_lane) ); - ASSERT_L(s); - - //memset( s, 0, sizeof(struct s_lane) ); - s->L= L2; - s->status= PENDING; - s->cancel_request= FALSE; + lua_State *L2; + struct s_lane *s; + struct s_lane **ud; + const char *threadName = 0; + + const char *libs= lua_tostring( L, 2 ); + uint_t cs= luaG_optunsigned( L, 3,0); + int prio= (int)luaL_optinteger( L, 4,0); + uint_t glob= luaG_isany(L,5) ? 5:0; + +#define FIXED_ARGS (5) + uint_t args= lua_gettop(L) - FIXED_ARGS; + + if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) + { + luaL_error( L, "Priority out of range: %d..+%d (%d)", + THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio ); + } + + /* --- Create and prepare the sub state --- */ + + L2 = luaL_newstate(); // uses standard 'realloc()'-based allocator, + // sets the panic callback + + if (!L2) luaL_error( L, "'luaL_newstate()' failed; out of memory" ); + + STACK_GROW( L,2 ); + + // Setting the globals table (needs to be done before loading stdlibs, + // and the lane function) + // + if (glob!=0) + { + STACK_CHECK(L) + if (!lua_istable(L,glob)) + luaL_error( L, "Expected table, got %s", luaG_typename(L,glob) ); + + lua_pushvalue( L, glob ); + lua_pushstring( L, "threadName"); + lua_gettable( L, -2); + threadName = lua_tostring( L, -1); + lua_pop( L, 1); + luaG_inter_move( L,L2, 1 ); // moves the table to L2 + + // L2 [-1]: table of globals + + // "You can change the global environment of a Lua thread using lua_replace" + // (refman-5.0.pdf p. 30) + // + lua_replace( L2, LUA_GLOBALSINDEX ); + STACK_END(L,0) + } + + // Selected libraries + // + if (libs) + { + const char *err= luaG_openlibs( L2, libs ); + ASSERT_L( !err ); // bad libs should have been noticed by 'lanes.lua' + + serialize_require( L2 ); + } + + // Lane main function + // + STACK_CHECK(L) + if( lua_type(L, 1) == LUA_TFUNCTION) + { + lua_pushvalue( L, 1 ); + luaG_inter_move( L,L2, 1 ); // L->L2 + STACK_MID(L,0) + } + else if( lua_type(L, 1) == LUA_TSTRING) + { + // compile the string + if( luaL_loadstring( L2, lua_tostring( L, 1)) != 0) + { + luaL_error( L, "error when parsing lane function code"); + } + } + + ASSERT_L( lua_gettop(L2) == 1 ); + ASSERT_L( lua_isfunction(L2,1) ); + + // revive arguments + // + if (args) luaG_inter_copy( L,L2, args ); // L->L2 + STACK_MID(L,0) + + ASSERT_L( (uint_t)lua_gettop(L2) == 1+args ); + ASSERT_L( lua_isfunction(L2,1) ); + + // 's' is allocated from heap, not Lua, since its life span may surpass + // the handle's (if free running thread) + // + ud= lua_newuserdata( L, sizeof(struct s_lane*) ); + ASSERT_L(ud); + + s= *ud= malloc( sizeof(struct s_lane) ); + ASSERT_L(s); + + //memset( s, 0, sizeof(struct s_lane) ); + s->L= L2; + s->status= PENDING; + s->cancel_request= FALSE; + + threadName = threadName ? threadName : ""; + strcpy(s->threadName, threadName); #if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) - MUTEX_INIT( &s->done_lock_ ); - SIGNAL_INIT( &s->done_signal_ ); + MUTEX_INIT( &s->done_lock_ ); + SIGNAL_INIT( &s->done_signal_ ); #endif - s->mstatus= NORMAL; - s->selfdestruct_next= NULL; - - // Set metatable for the userdata - // - lua_pushvalue( L, lua_upvalueindex(1) ); - lua_setmetatable( L, -2 ); -STACK_MID(L,1) - - // Place 's' to registry, for 'cancel_test()' (even if 'cs'==0 we still - // do cancel tests at pending send/receive). - // - lua_pushlightuserdata( L2, CANCEL_TEST_KEY ); - lua_pushlightuserdata( L2, s ); - lua_rawset( L2, LUA_REGISTRYINDEX ); - - if (cs) { - lua_sethook( L2, cancel_hook, LUA_MASKCOUNT, cs ); - } - - THREAD_CREATE( &s->thread, lane_main, s, prio ); -STACK_END(L,1) - - return 1; + s->mstatus= NORMAL; + s->selfdestruct_next= NULL; + + // Set metatable for the userdata + // + lua_pushvalue( L, lua_upvalueindex(1) ); + lua_setmetatable( L, -2 ); + STACK_MID(L,1) + + // Place 's' to registry, for 'cancel_test()' (even if 'cs'==0 we still + // do cancel tests at pending send/receive). + // + lua_pushlightuserdata( L2, CANCEL_TEST_KEY ); + lua_pushlightuserdata( L2, s ); + lua_rawset( L2, LUA_REGISTRYINDEX ); + + if (cs) + { + lua_sethook( L2, cancel_hook, LUA_MASKCOUNT, cs ); + } + + THREAD_CREATE( &s->thread, lane_main, s, prio ); + STACK_END(L,1) + + return 1; } @@ -1428,45 +1575,56 @@ STACK_END(L,1) // // Todo: Maybe we should have a clear #define for selecting either behaviour. // -LUAG_FUNC( thread_gc ) { - struct s_lane *s= lua_toLane(L,1); - - // We can read 's->status' without locks, but not wait for it - // - if (s->status < DONE) { - // - selfdestruct_add(s); - assert( s->selfdestruct_next ); - return 0; - - } else if (s->mstatus==KILLED) { - // Make sure a kill has proceeded, before cleaning up the data structure. - // - // If not doing 'THREAD_WAIT()' we should close the Lua state here - // (can it be out of order, since we killed the lane abruptly?) - // +LUAG_FUNC( thread_gc ) +{ + struct s_lane *s= lua_toLane(L,1); + + // We can read 's->status' without locks, but not wait for it + // + if (s->status < DONE) + { + // + selfdestruct_add(s); + assert( s->selfdestruct_next ); + return 0; + + } + else if (s->mstatus==KILLED) + { + // Make sure a kill has proceeded, before cleaning up the data structure. + // + // If not doing 'THREAD_WAIT()' we should close the Lua state here + // (can it be out of order, since we killed the lane abruptly?) + // #if 0 - lua_close( s->L ); + lua_close( s->L ); + s->L = 0; #else -fprintf( stderr, "** Joining with a killed thread (needs testing) **" ); + DEBUGEXEC(fprintf( stderr, "** Joining with a killed thread (needs testing) **" )); #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) - THREAD_WAIT( &s->thread, -1 ); + THREAD_WAIT( &s->thread, -1 ); #else - THREAD_WAIT( &s->thread, &s->done_signal_, &s->done_lock_, &s->status, -1 ); + THREAD_WAIT( &s->thread, &s->done_signal_, &s->done_lock_, &s->status, -1 ); #endif -fprintf( stderr, "** Joined ok **" ); + DEBUGEXEC(fprintf( stderr, "** Joined ok **" )); #endif - } - - // Clean up after a (finished) thread - // + } + else if( s->L) + { + lua_close( s->L); + s->L = 0; + } + + // Clean up after a (finished) thread + // #if (! ((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN))) - SIGNAL_FREE( &s->done_signal_ ); - MUTEX_FREE( &s->done_lock_ ); - free(s); + SIGNAL_FREE( &s->done_signal_ ); + MUTEX_FREE( &s->done_lock_ ); #endif - return 0; + free(s); + + return 0; } @@ -1614,10 +1772,11 @@ LUAG_FUNC( thread_join ) break; default: - fprintf( stderr, "Status: %d\n", s->status ); + DEBUGEXEC(fprintf( stderr, "Status: %d\n", s->status )); ASSERT_L( FALSE ); ret= 0; } lua_close(L2); + s->L = L2 = 0; return ret; } @@ -1626,48 +1785,6 @@ LUAG_FUNC( thread_join ) /*---=== Timer support ===--- */ -/* -* Push a timer gateway Linda object; only one deep userdata is -* created for this, each lane will get its own proxy. -* -* Note: this needs to be done on the C side; Lua wouldn't be able -* to even see, when we've been initialized for the very first -* time (with us, they will be). -*/ -static -void push_timer_gateway( lua_State *L ) { - - /* No need to lock; 'static' is just fine - */ - static DEEP_PRELUDE *p; // = NULL - - STACK_CHECK(L) - if (!p) { - // Create the Linda (only on first time) - // - // proxy_ud= deep_userdata( idfunc ) - // - lua_pushcfunction( L, luaG_deep_userdata ); - lua_pushcfunction( L, LG_linda_id ); - lua_call( L, 1 /*args*/, 1 /*retvals*/ ); - - ASSERT_L( lua_isuserdata(L,-1) ); - - // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer - // - p= * (DEEP_PRELUDE**) lua_touserdata( L, -1 ); - ASSERT_L(p && p->refcount==1 && p->deep); - - // [-1]: proxy for accessing the Linda - - } else { - /* Push a proxy based on the deep userdata we stored. - */ - luaG_push_proxy( L, LG_linda_id, p ); - } - STACK_END(L,1) -} - /* * secs= now_secs() * @@ -1697,12 +1814,12 @@ LUAG_FUNC( wakeup_conv ) // .isdst (daylight saving on/off) STACK_CHECK(L) - lua_getfield( L, 1, "year" ); year= lua_tointeger(L,-1); lua_pop(L,1); - lua_getfield( L, 1, "month" ); month= lua_tointeger(L,-1); lua_pop(L,1); - lua_getfield( L, 1, "day" ); day= lua_tointeger(L,-1); lua_pop(L,1); - lua_getfield( L, 1, "hour" ); hour= lua_tointeger(L,-1); lua_pop(L,1); - lua_getfield( L, 1, "min" ); min= lua_tointeger(L,-1); lua_pop(L,1); - lua_getfield( L, 1, "sec" ); sec= lua_tointeger(L,-1); lua_pop(L,1); + lua_getfield( L, 1, "year" ); year= (int)lua_tointeger(L,-1); lua_pop(L,1); + lua_getfield( L, 1, "month" ); month= (int)lua_tointeger(L,-1); lua_pop(L,1); + lua_getfield( L, 1, "day" ); day= (int)lua_tointeger(L,-1); lua_pop(L,1); + lua_getfield( L, 1, "hour" ); hour= (int)lua_tointeger(L,-1); lua_pop(L,1); + lua_getfield( L, 1, "min" ); min= (int)lua_tointeger(L,-1); lua_pop(L,1); + lua_getfield( L, 1, "sec" ); sec= (int)lua_tointeger(L,-1); lua_pop(L,1); // If Lua table has '.isdst' we trust that. If it does not, we'll let // 'mktime' decide on whether the time is within DST or not (value -1). @@ -1744,19 +1861,11 @@ LUAG_FUNC( wakeup_conv ) lua_pushinteger( L, val ); \ lua_setglobal( L, #name ) - -int -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) -__declspec(dllexport) -#endif - luaopen_lanes( lua_State *L ) { +/* +* One-time initializations +*/ +static void init_once_LOCKED( lua_State *L, volatile DEEP_PRELUDE ** timer_deep_ref ) { const char *err; - static volatile char been_here; // =0 - - // One time initializations: - // - if (!been_here) { - been_here= TRUE; #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) now_secs(); // initialize 'now_secs()' internal offset @@ -1806,10 +1915,87 @@ __declspec(dllexport) #endif #endif err= init_keepers(); - if (err) + if (err) { luaL_error( L, "Unable to initialize: %s", err ); } + // Initialize 'timer_deep'; a common Linda object shared by all states + // + ASSERT_L( timer_deep_ref && (!(*timer_deep_ref)) ); + + STACK_CHECK(L) + { + // proxy_ud= deep_userdata( idfunc ) + // + lua_pushcfunction( L, luaG_deep_userdata ); + lua_pushcfunction( L, LG_linda_id ); + lua_call( L, 1 /*args*/, 1 /*retvals*/ ); + + ASSERT_L( lua_isuserdata(L,-1) ); + + // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer + // + *timer_deep_ref= * (DEEP_PRELUDE**) lua_touserdata( L, -1 ); + ASSERT_L( (*timer_deep_ref) && (*timer_deep_ref)->refcount==1 && (*timer_deep_ref)->deep ); + + lua_pop(L,1); // we don't need the proxy + } + STACK_END(L,0) +} + +int +#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) +__declspec(dllexport) +#endif + luaopen_lanes( lua_State *L ) { + + // Initialized by 'init_once_LOCKED()': the deep userdata Linda object + // used for timers (each lane will get a proxy to this) + // + static volatile DEEP_PRELUDE *timer_deep; // = NULL + + /* + * Making one-time initializations. + * + * When the host application is single-threaded (and all threading happens via Lanes) + * there is no problem. But if the host is multithreaded, we need to lock around the + * initializations. + */ + static volatile int /*bool*/ go_ahead; // = 0 +#ifdef PLATFORM_WIN32 + { + // TBD: Someone please replace this with reliable Win32 API code. Problem is, + // there's no autoinitializing locks (s.a. PTHREAD_MUTEX_INITIALIZER) in + // Windows so 'InterlockedIncrement' or something needs to be used. + // This is 99.9999% safe, though (and always safe if host is single-threaded) + // -- AKa 24-Jun-2009 + // + static volatile unsigned my_number; // = 0 + + if (my_number++ == 0) { // almost atomic + init_once_LOCKED(L, &timer_deep); + go_ahead= 1; // let others pass + } else { + while( !go_ahead ) { Sleep(1); } // changes threads + } + } +#else + if (!go_ahead) { + static pthread_mutex_t my_lock= PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_lock(&my_lock); + { + // Recheck now that we're within the lock + // + if (!go_ahead) { + init_once_LOCKED(L, &timer_deep); + go_ahead= 1; + } + } + pthread_mutex_unlock(&my_lock); + } +#endif + assert( timer_deep != 0 ); + // Linda identity function // REG_FUNC( linda_id ); @@ -1835,7 +2021,7 @@ __declspec(dllexport) REG_FUNC( now_secs ); REG_FUNC( wakeup_conv ); - push_timer_gateway(L); + luaG_push_proxy( L, LG_linda_id, (DEEP_PRELUDE *) timer_deep ); lua_setglobal( L, "timer_gateway" ); REG_INT2( max_prio, THREAD_PRIO_MAX ); diff --git a/src/lanes.lua b/src/lanes.lua index c68506d..7ec8c76 100644 --- a/src/lanes.lua +++ b/src/lanes.lua @@ -6,7 +6,8 @@ -- Author: Asko Kauppi -- -- History: --- Jun-08 AKa: major revise +-- 3-Dec-10 BGe: Added support to generate a lane from a string +-- Jun-08 AKa: major revise -- 15-May-07 AKa: pthread_join():less version, some speedup & ability to -- handle more threads (~ 8000-9000, up from ~ 5000) -- 26-Feb-07 AKa: serialization working (C side) @@ -15,7 +16,7 @@ --[[ =============================================================================== -Copyright (C) 2007-08 Asko Kauppi +Copyright (C) 2007-10 Asko Kauppi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -89,7 +90,7 @@ ABOUT= author= "Asko Kauppi ", description= "Running multiple Lua states in parallel", license= "MIT/X11", - copyright= "Copyright (c) 2007-08, Asko Kauppi", + copyright= "Copyright (c) 2007-10, Asko Kauppi", version= _version, } @@ -123,6 +124,14 @@ end -- -- lane_h.state: "pending"/"running"/"waiting"/"done"/"error"/"cancelled" -- +-- Note: Would be great to be able to have '__ipairs' metamethod, that gets +-- called by 'ipairs()' function to custom iterate objects. We'd use it +-- for making sure a lane has ended (results are available); not requiring +-- the user to precede a loop by explicit 'h[0]' or 'h:join()'. +-- +-- Or, even better, 'ipairs()' should start valuing '__index' instead +-- of using raw reads that bypass it. +-- local lane_mt= { __index= function( me, k ) if type(k) == "number" then @@ -260,8 +269,9 @@ function gen( ... ) end local func= select(n,...) - if type(func)~="function" then - error( "Last parameter not function: "..tostring(func) ) + local functype = type(func) + if functype ~= "function" and functype ~= "string" then + error( "Last parameter not function or string: "..tostring(func)) end -- Check 'libs' already here, so the error goes in the right place @@ -302,9 +312,10 @@ lane_proxy= function( ud ) local proxy= { _ud= ud, - -- void= me:cancel() + -- true|false= me:cancel() -- - cancel= function(me) thread_cancel(me._ud) end, + cancel= function(me, time, force) return thread_cancel(me._ud, time, force) end, + -- [...] | [nil,err,stack_tbl]= me:join( [wait_secs=-1] ) -- @@ -495,14 +506,18 @@ if first_time then -- We let the timer lane be a "free running" thread; no handle to it -- remains. -- - gen( "io", { priority=max_prio }, function() + gen( "io", { priority=max_prio, globals={threadName="LanesTimer"} }, function() while true do local next_wakeup= check_timers() -- Sleep until next timer to wake up, or a set/clear command -- - local secs= next_wakeup and (next_wakeup - now_secs()) or nil + local secs + if next_wakeup then + secs = next_wakeup - now_secs() + if secs < 0 then secs = 0 end + end local linda= timer_gateway:receive( secs, TGW_KEY ) if linda then diff --git a/src/threading.c b/src/threading.c index 68d1e41..00be243 100644 --- a/src/threading.c +++ b/src/threading.c @@ -1,5 +1,5 @@ /* - * THREADING.C Copyright (c) 2007-08, Asko Kauppi + * THREADING.C Copyright (c) 2007-10, Asko Kauppi * * Lua Lanes OS threading specific code. * @@ -10,7 +10,7 @@ /* =============================================================================== -Copyright (C) 2007-08 Asko Kauppi +Copyright (C) 2007-10 Asko Kauppi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -178,6 +178,11 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { ts->tv_sec= floor( abs_secs ); ts->tv_nsec= ((long)((abs_secs - ts->tv_sec) * 1000.0 +0.5)) * 1000000UL; // 1ms = 1000000ns + if (ts->tv_nsec == 1000000000UL) + { + ts->tv_nsec = 0; + ts->tv_sec = ts->tv_sec + 1; + } } #endif diff --git a/src/tools.c b/src/tools.c index a2ec517..2f3140d 100644 --- a/src/tools.c +++ b/src/tools.c @@ -1,5 +1,5 @@ /* - * TOOLS.C Copyright (c) 2002-08, Asko Kauppi + * TOOLS.C Copyright (c) 2002-10, Asko Kauppi * * Lua tools to support Lanes. */ @@ -7,7 +7,7 @@ /* =============================================================================== -Copyright (C) 2002-08 Asko Kauppi +Copyright (C) 2002-10 Asko Kauppi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -40,8 +40,6 @@ THE SOFTWARE. #include #include -static volatile lua_CFunction hijacked_tostring; // = NULL - MUTEX_T deep_lock; MUTEX_T mtid_lock; @@ -600,7 +598,7 @@ uint_t get_mt_id( lua_State *L, int i ) { // [-2]: reg[REG_MTID] // [-1]: nil/uint - id= lua_tointeger(L,-1); // 0 for nil + id= (uint_t)lua_tointeger(L,-1); // 0 for nil lua_pop(L,1); STACK_MID(L,1) @@ -644,73 +642,60 @@ static int buf_writer( lua_State *L, const void* b, size_t n, void* B ) { * Returns TRUE if the table was cached (no need to fill it!); FALSE if * it's a virgin. */ -static -bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) { - bool_t ret; - - ASSERT_L( hijacked_tostring ); - ASSERT_L( L2_cache_i != 0 ); - - STACK_GROW(L,2); - STACK_GROW(L2,3); +static bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) +{ + bool_t ret; - // Create an identity string for table at [i]; it should stay unique at - // least during copying of the data (then we can clear the caches). - // - STACK_CHECK(L) - lua_pushcfunction( L, hijacked_tostring ); - lua_pushvalue( L, i ); - lua_call( L, 1 /*args*/, 1 /*retvals*/ ); - // - // [-1]: "table: 0x...." + ASSERT_L( L2_cache_i != 0 ); - STACK_END(L,1) - ASSERT_L( lua_type(L,-1) == LUA_TSTRING ); + STACK_GROW(L2,3); - // L2_cache[id_str]= [{...}] - // - STACK_CHECK(L2) + // L2_cache[id_str]= [{...}] + // + STACK_CHECK(L2) - // We don't need to use the from state ('L') in ID since the life span - // is only for the duration of a copy (both states are locked). - // - lua_pushstring( L2, lua_tostring(L,-1) ); - lua_pop(L,1); // remove the 'tostring(tbl)' value (in L!) + // We don't need to use the from state ('L') in ID since the life span + // is only for the duration of a copy (both states are locked). + // + lua_pushlightuserdata( L2, (void*)lua_topointer( L, i )); // push a light userdata uniquely representing the table -//fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); + //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); - lua_pushvalue( L2, -1 ); - lua_rawget( L2, L2_cache_i ); - // - // [-2]: identity string ("table: 0x...") - // [-1]: table|nil - - if (lua_isnil(L2,-1)) { - lua_pop(L2,1); - lua_newtable(L2); - lua_pushvalue(L2,-1); - lua_insert(L2,-3); - // - // [-3]: new table (2nd ref) - // [-2]: identity string - // [-1]: new table + lua_pushvalue( L2, -1 ); + lua_rawget( L2, L2_cache_i ); + // + // [-2]: identity table pointer lightuserdata + // [-1]: table|nil - lua_rawset(L2, L2_cache_i); - // - // [-1]: new table (tied to 'L2_cache' table') - - ret= FALSE; // brand new - - } else { - lua_remove(L2,-2); - ret= TRUE; // from cache - } - STACK_END(L2,1) - // - // L2 [-1]: table to use as destination + if (lua_isnil(L2,-1)) + { + lua_pop(L2,1); + lua_newtable(L2); + lua_pushvalue(L2,-1); + lua_insert(L2,-3); + // + // [-3]: new table (2nd ref) + // [-2]: identity table pointer lightuserdata + // [-1]: new table - ASSERT_L( lua_istable(L2,-1) ); - return ret; + lua_rawset(L2, L2_cache_i); + // + // [-1]: new table (tied to 'L2_cache' table') + + ret= FALSE; // brand new + + } + else + { + lua_remove(L2,-2); + ret= TRUE; // from cache + } + STACK_END(L2,1) + // + // L2 [-1]: table to use as destination + + ASSERT_L( lua_istable(L2,-1) ); + return ret; } @@ -722,82 +707,76 @@ bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t */ static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ); -static -void push_cached_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) { - // TBD: Merge this and same code for tables +static void push_cached_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) +{ + // TBD: Merge this and same code for tables - ASSERT_L( hijacked_tostring ); - ASSERT_L( L2_cache_i != 0 ); + ASSERT_L( L2_cache_i != 0 ); - STACK_GROW(L,2); - STACK_GROW(L2,3); + STACK_GROW(L2,3); - STACK_CHECK(L) - lua_pushcfunction( L, hijacked_tostring ); - lua_pushvalue( L, i ); - lua_call( L, 1 /*args*/, 1 /*retvals*/ ); - // - // [-1]: "function: 0x...." + // L2_cache[id_str]= function + // + STACK_CHECK(L2) - STACK_END(L,1) - ASSERT_L( lua_type(L,-1) == LUA_TSTRING ); - - // L2_cache[id_str]= function - // - STACK_CHECK(L2) + // We don't need to use the from state ('L') in ID since the life span + // is only for the duration of a copy (both states are locked). + // + lua_pushlightuserdata( L2, (void*)lua_topointer( L, i )); // push a light userdata uniquely representing the function - // We don't need to use the from state ('L') in ID since the life span - // is only for the duration of a copy (both states are locked). - // - lua_pushstring( L2, lua_tostring(L,-1) ); - lua_pop(L,1); // remove the 'tostring(tbl)' value (in L!) + //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); -//fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); + lua_pushvalue( L2, -1 ); + lua_rawget( L2, L2_cache_i ); + // + // [-2]: identity lightuserdata function pointer + // [-1]: function|nil|true (true means: we're working on it; recursive) - lua_pushvalue( L2, -1 ); - lua_rawget( L2, L2_cache_i ); - // - // [-2]: identity string ("function: 0x...") - // [-1]: function|nil|true (true means: we're working on it; recursive) + if (lua_isnil(L2,-1)) + { + lua_pop(L2,1); - if (lua_isnil(L2,-1)) { - lua_pop(L2,1); - - // Set to 'true' for the duration of creation; need to find self-references - // via upvalues - // - lua_pushboolean(L2,TRUE); - lua_setfield( L2, L2_cache_i, lua_tostring(L2,-2) ); - - inter_copy_func( L2, L2_cache_i, L, i ); // pushes a copy of the func + // Set to 'true' for the duration of creation; need to find self-references + // via upvalues + // + lua_pushvalue( L2, -1); + lua_pushboolean(L2,TRUE); + lua_rawset( L2, L2_cache_i); - lua_pushvalue(L2,-1); - lua_insert(L2,-3); - // - // [-3]: function (2nd ref) - // [-2]: identity string - // [-1]: function + inter_copy_func( L2, L2_cache_i, L, i ); // pushes a copy of the func - lua_rawset(L2,L2_cache_i); - // - // [-1]: function (tied to 'L2_cache' table') - - } else if (lua_isboolean(L2,-1)) { - // Loop in preparing upvalues; either direct or via a table - // - // Note: This excludes the case where a function directly addresses - // itself as an upvalue (recursive lane creation). - // - luaL_error( L, "Recursive use of upvalues; cannot copy the function" ); - - } else { - lua_remove(L2,-2); - } - STACK_END(L2,1) - // - // L2 [-1]: function + lua_pushvalue(L2,-1); + lua_insert(L2,-3); + // + // [-3]: function (2nd ref) + // [-2]: identity lightuserdata function pointer + // [-1]: function - ASSERT_L( lua_isfunction(L2,-1) ); + lua_rawset(L2,L2_cache_i); + // + // [-1]: function (tied to 'L2_cache' table') + + } + else if (lua_isboolean(L2,-1)) + { + // Loop in preparing upvalues; either direct or via a table + // + // Note: This excludes the case where a function directly addresses + // itself as an upvalue (recursive lane creation). + // + STACK_GROW(L,1); + luaL_error( L, "Recursive use of upvalues; cannot copy the function" ); + + } + else + { + lua_remove(L2,-2); + } + STACK_END(L2,1) + // + // L2 [-1]: function + + ASSERT_L( lua_isfunction(L2,-1) ); } @@ -1137,29 +1116,6 @@ void luaG_inter_copy( lua_State* L, lua_State *L2, uint_t n ) uint_t top_L2= lua_gettop(L2); uint_t i; - /* steal Lua library's 'luaB_tostring()' from the first call. Other calls - * don't have to have access to it. - * - * Note: multiple threads won't come here at once; this function will - * be called before there can be multiple threads (no locking needed). - */ - if (!hijacked_tostring) { - STACK_GROW( L,1 ); - - STACK_CHECK(L) - lua_getglobal( L, "tostring" ); - // - // [-1]: function|nil - - hijacked_tostring= lua_tocfunction( L, -1 ); - lua_pop(L,1); - STACK_END(L,0) - - if (!hijacked_tostring) { - luaL_error( L, "Need to see 'tostring()' once" ); - } - } - if (n > top_L) luaL_error( L, "Not enough values: %d < %d", top_L, n ); diff --git a/src/tools.h b/src/tools.h index d155c65..aad26df 100644 --- a/src/tools.h +++ b/src/tools.h @@ -22,6 +22,7 @@ #define STACK_END(L,c) /*nothing*/ #define STACK_DUMP(L) /*nothing*/ #define DEBUG() /*nothing*/ + #define DEBUGEXEC(_code) {} /*nothing*/ #else #define _ASSERT_L(lua,c) { if (!(c)) luaL_error( lua, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #c ); } // @@ -32,6 +33,7 @@ #define STACK_DUMP(L) luaG_dump(L); #define DEBUG() fprintf( stderr, "<<%s %d>>\n", __FILE__, __LINE__ ); + #define DEBUGEXEC(_code) {_code;} /*nothing*/ #endif #define ASSERT_L(c) _ASSERT_L(L,c) diff --git a/tests/appendud.lua b/tests/appendud.lua new file mode 100644 index 0000000..afea0e9 --- /dev/null +++ b/tests/appendud.lua @@ -0,0 +1,58 @@ +-- +-- APPENDUD.LUA +-- +-- Lanes version for John Belmonte's challenge on Lua list (about finalizers): +-- +-- +-- Needs Lanes >= 2.0.3 +-- +require "lanes" + +local _tab = { + beginupdate = function (this) print('tab.beginupdate') end; + endupdate = function (this) print('tab.endupdate') end; +} +local _ud = { + lock = function (this) print('ud.lock') end; + unlock = function (this) print('ud.unlock') end; + 1,2,3,4,5; +} + +-- +-- This sample is with the 'finalize/guard' patch applied (new keywords): +-- +--function appendud(tab, ud) +-- tab:beginupdate() finalize tab:endupdate() end +-- ud:lock() finalize ud:unlock() end +-- for i = 1,#ud do +-- tab[#tab+1] = ud[i] +-- end +--end + + +function appendud(tab, ud) +io.stderr:write "Starting" + tab:beginupdate() set_finalizer( function() tab:endupdate() end ) + ud:lock() set_finalizer( function() ud:unlock() end ) + for i = 1,#ud do + tab[#tab+1] = ud[i] + end +io.stderr:write "Ending" + return tab -- need to return 'tab' since we're running in a separate thread + -- ('tab' is passed over lanes by value, not by reference) +end + +local t,err= lanes.gen( appendud )( _tab, _ud ) -- create & launch a thread +assert(t) +assert(not err) + +-- test + +t:join() -- Need to explicitly wait for the thread, since 'ipairs()' does not + -- value the '__index' metamethod (wouldn't it be cool if it did..?) + +io.stderr:write(t[1]) + +for k,v in ipairs(t) do + print(k,v) +end diff --git a/tests/basic.lua b/tests/basic.lua index ee31ed1..b1e8fd3 100644 --- a/tests/basic.lua +++ b/tests/basic.lua @@ -2,7 +2,7 @@ -- BASIC.LUA Copyright (c) 2007-08, Asko Kauppi -- -- Selftests for Lua Lanes --- +-- -- To do: -- - ... -- @@ -20,7 +20,7 @@ local function PRINT(...) for i=1,select('#',...) do str= str..tostring(select(i,...)).."\t" end - if io then + if io then io.stderr:write(str.."\n") end end @@ -55,7 +55,7 @@ tables_match= function( a, b ) end ----=== Tasking (basic) ===--- +PRINT( "---=== Tasking (basic) ===---") local function task( a, b, c ) --error "111" -- testing error messages @@ -98,7 +98,7 @@ assert( lane1.status == "done" ) assert( lane1.status == "done" ) ----=== Tasking (cancelling) ===--- +PRINT( "---=== Tasking (cancelling) ===---") local task_launch2= lanes_gen( "", { cancelstep=100, globals={hey=true} }, task ) @@ -136,7 +136,7 @@ PRINT(" "..st) assert( st == "cancelled" ) ----=== Communications ===--- +PRINT( "---=== Communications ===---") local function WR(...) io.stderr:write(...) end @@ -157,7 +157,7 @@ local chunk= function( linda ) send { 'a', 'b', 'c', d=10 }; WR( "{'a','b','c',d=10} sent\n" ) v=receive(); WR( v.." received\n" ); assert( v==4 ) - + WR( "Lane ends!\n" ) end @@ -195,7 +195,7 @@ assert( PEEK() == nil ) SEND(4) ----=== Stdlib naming ===--- +PRINT( "---=== Stdlib naming ===---") local function io_os_f() assert(io) @@ -215,7 +215,7 @@ assert( f2()[1] ) assert( f3()[1] ) ----=== Comms criss cross ===--- +PRINT( "---=== Comms criss cross ===---") -- We make two identical lanes, which are using the same Linda channel. -- @@ -241,7 +241,7 @@ local a,b= tc(linda, "A","B"), tc(linda, "B","A") -- launching two lanes, twis local _= a[1],b[1] -- waits until they are both ready ----=== Receive & send of code ===--- +PRINT( "---=== Receive & send of code ===---") local upvalue="123" @@ -251,21 +251,21 @@ local function chunk2( linda ) -- function name & line number should be there even as separate thread -- local info= debug.getinfo(1) -- 1 = us - -- - for k,v in pairs(info) do PRINT(k,v) end - - assert( info.nups == 2 ) -- one upvalue + PRINT - assert( info.what == "Lua" ) - - --assert( info.name == "chunk2" ) -- name does not seem to come through - assert( string.match( info.source, "^@tests[/\\]basic.lua$" ) ) - assert( string.match( info.short_src, "^tests[/\\]basic.lua$" ) ) - - -- These vary so let's not be picky (they're there..) - -- - assert( info.linedefined > 200 ) -- start of 'chunk2' - assert( info.currentline > info.linedefined ) -- line of 'debug.getinfo' - assert( info.lastlinedefined > info.currentline ) -- end of 'chunk2' + -- + for k,v in pairs(info) do PRINT(k,v) end + + assert( info.nups == 2 ) -- one upvalue + PRINT + assert( info.what == "Lua" ) + + --assert( info.name == "chunk2" ) -- name does not seem to come through + assert( string.match( info.source, "^@basic.lua$" ) ) + assert( string.match( info.short_src, "^basic.lua$" ) ) + + -- These vary so let's not be picky (they're there..) + -- + assert( info.linedefined > 200 ) -- start of 'chunk2' + assert( info.currentline > info.linedefined ) -- line of 'debug.getinfo' + assert( info.lastlinedefined > info.currentline ) -- end of 'chunk2' local func,k= linda:receive( "down" ) assert( type(func)=="function" ) @@ -275,7 +275,7 @@ local function chunk2( linda ) local str= linda:receive( "down" ) assert( str=="ok" ) - + linda:send( "up", function() return ":)" end, "ok2" ) end @@ -304,7 +304,7 @@ local ok2= linda:receive( "up" ) assert( ok2 == "ok2" ) ----=== :join test ===--- +PRINT( "---=== :join test ===---") -- NOTE: 'unpack()' cannot be used on the lane handle; it will always return nil -- (unless [1..n] has been read earlier, in which case it would seemingly diff --git a/tests/func_is_string.lua b/tests/func_is_string.lua new file mode 100644 index 0000000..98ea62b --- /dev/null +++ b/tests/func_is_string.lua @@ -0,0 +1,12 @@ +require "lanes" + +local options = {globals = { b = 666 }} + +-- local gen1 = lanes.gen("*", "dofile('fibonacci.lua')") +local gen2 = lanes.gen(options, "return b") + +-- fibLane = gen1() +retLane1, retLane2 = gen2(), gen2() +-- fibLane:join() + +print( retLane1[1], retLane2[1]) diff --git a/xcode/xcode.xcodeproj/abisoft.mode1 b/xcode/xcode.xcodeproj/abisoft.mode1 new file mode 100644 index 0000000..569158d --- /dev/null +++ b/xcode/xcode.xcodeproj/abisoft.mode1 @@ -0,0 +1,1460 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXRunSessionModule + Name + Run Log + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1 + FavBarConfig + + PBXProjectModuleGUID + 27602E5F0C2F36D60086E627 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1 + MajorVersion + 31 + MinorVersion + 1 + Name + Default + Notifications + + + XCObserverAutoDisconnectKey + + XCObserverDefintionKey + + XCObserverFactoryKey + XCPerspectivesSpecificationIdentifier + XCObserverGUIDKey + XCObserverProjectIdentifier + XCObserverNotificationKey + PBXStatusBuildStateMessageNotification + XCObserverTargetKey + XCMainBuildResultsModuleGUID + XCObserverTriggerKey + awakenModuleWithObserver: + XCObserverValidationKey + + + + OpenEditors + + + Content + + PBXProjectModuleGUID + 2784DBE60CD6544900B13CF3 + PBXProjectModuleLabel + gluax_static.c + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 2784DBE70CD6544900B13CF3 + PBXProjectModuleLabel + gluax_static.c + _historyCapacity + 0 + bookmark + 2736316D0CD721CA00A12F3E + history + + 27F8E2020CD71E630081A54F + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {1057, 709}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 349 236 1057 750 0 0 1680 1028 + + + + Content + + PBXProjectModuleGUID + 27F6DA310C4416540054E42A + PBXProjectModuleLabel + gluax.c + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 27F6DA320C4416540054E42A + PBXProjectModuleLabel + gluax.c + _historyCapacity + 0 + bookmark + 2736316E0CD721CA00A12F3E + history + + 27F8E2030CD71E630081A54F + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {1057, 709}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 540 110 1057 750 0 0 1680 1028 + + + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-target-popup + active-buildstyle-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-runOrDebug + com.apple.ide.PBXToolbarStopButton + get-info + toggle-editor + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 08FB7794FE84155DC02AAC07 + 1AB674ADFE9D54B511CA2CBB + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 12 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 503}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 521}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 243 337 880 562 0 0 1680 1028 + + Module + PBXSmartGroupTreeModule + Proportion + 203pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + MyNewFile14.java + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + MyNewFile14.java + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {672, 0}} + RubberWindowFrame + 243 337 880 562 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 5}, {672, 516}} + RubberWindowFrame + 243 337 880 562 0 0 1680 1028 + + Module + XCDetailModule + Proportion + 516pt + + + Proportion + 672pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 2736315A0CD71F3400A12F3E + 1CE0B1FE06471DED0097A5F4 + 2736315B0CD71F3400A12F3E + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.short + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 215425482.989885 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 2736315E0CD71F3400A12F3E + 2736315F0CD71F3400A12F3E + 274A5F0A0C2F4351000A66CF + 273631580CD71F2400A12F3E + 27F6DA310C4416540054E42A + 2784DBE60CD6544900B13CF3 + /Users/abisoft/Slug/public/2007/Lua Modules/Lanes/xcode/xcode.xcodeproj + 27602E740C2F3B100086E627 + 1CD10A99069EF8BA00B06720 + + WindowString + 243 337 880 562 0 0 1680 1028 + WindowTools + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {983, 267}} + RubberWindowFrame + 541 112 983 821 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 267pt + + + BecomeActive + + ContentConfiguration + + PBXBuildLogShowsTranscriptDefaultKey + {{0, 5}, {983, 503}} + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1010 + + GeometryConfiguration + + Frame + {{0, 272}, {983, 508}} + RubberWindowFrame + 541 112 983 821 0 0 1680 1028 + + Module + PBXBuildResultsModule + Proportion + 508pt + + + Proportion + 780pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 27602E740C2F3B100086E627 + 273631510CD71F2400A12F3E + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.build + WindowString + 541 112 983 821 0 0 1680 1028 + WindowToolGUID + 27602E740C2F3B100086E627 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {437, 275}} + {{437, 0}, {584, 275}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {1021, 275}} + {{0, 275}, {1021, 605}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleDrawerSize + {100, 120} + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {1021, 880}} + RubberWindowFrame + 504 97 1021 921 0 0 1680 1028 + + Module + PBXDebugSessionModule + Proportion + 880pt + + + Proportion + 880pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + 273631520CD71F2400A12F3E + 1C162984064C10D400B95A72 + 273631530CD71F2400A12F3E + 273631540CD71F2400A12F3E + 273631550CD71F2400A12F3E + 273631560CD71F2400A12F3E + 273631570CD71F2400A12F3E + 273631580CD71F2400A12F3E + + ToolbarConfiguration + xcode.toolbar.config.debug + WindowString + 504 97 1021 921 0 0 1680 1028 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + Identifier + windowTool.find + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CD0528D0623707200166675 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {781, 167}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 50% + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{8, 0}, {773, 254}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 50% + + + Proportion + 428pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C530D57069F1CE1000CFCEE + 1C530D58069F1CE1000CFCEE + 1C530D59069F1CE1000CFCEE + 1CDD528C0622207200134675 + 1C530D5A069F1CE1000CFCEE + 1CE0B1FE06471DED0097A5F4 + 1CD0528E0623707200166675 + + WindowString + 62 385 781 470 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + 0 + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {873, 523}} + RubberWindowFrame + 114 193 873 564 0 0 1680 1028 + + Module + PBXDebugCLIModule + Proportion + 523pt + + + Proportion + 523pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 274A5F0A0C2F4351000A66CF + 273631590CD71F2400A12F3E + 1C78EAAC065D492600B07095 + + WindowString + 114 193 873 564 0 0 1680 1028 + WindowToolGUID + 274A5F0A0C2F4351000A66CF + WindowToolIsVisible + + + + Identifier + windowTool.run + Layout + + + Dock + + + ContentConfiguration + + LauncherConfigVersion + 3 + PBXProjectModuleGUID + 1CD0528B0623707200166675 + PBXProjectModuleLabel + Run + Runner + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {493, 167}} + {{0, 176}, {493, 267}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {405, 443}} + {{414, 0}, {514, 443}} + + + + + GeometryConfiguration + + Frame + {{0, 0}, {460, 159}} + RubberWindowFrame + 316 696 459 200 0 0 1280 1002 + + Module + PBXRunSessionModule + Proportion + 159pt + + + Proportion + 159pt + + + Name + Run Log + ServiceClasses + + PBXRunSessionModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C0AD2B3069F1EA900FABCE6 + 1C0AD2B4069F1EA900FABCE6 + 1CD0528B0623707200166675 + 1C0AD2B5069F1EA900FABCE6 + + ToolbarConfiguration + xcode.toolbar.config.run + WindowString + 316 696 459 200 0 0 1280 1002 + WindowToolGUID + 1C0AD2B3069F1EA900FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.09500122070312 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.breakpoints + IsVertical + + Layout + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + 1C3E0DCA080725EA00A55177 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 1 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 365}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + + GeometryConfiguration + + Frame + {{0, 0}, {185, 383}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 713 435 871 424 0 0 1680 1028 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {681, 383}} + RubberWindowFrame + 713 435 871 424 0 0 1680 1028 + + Module + XCDetailModule + Proportion + 681pt + + + Proportion + 383pt + + + MajorVersion + 2 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + + TableOfContents + + 271333C40C4602BB005FEE0E + 271333C50C4602BB005FEE0E + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpoints + WindowString + 713 435 871 424 0 0 1680 1028 + WindowToolGUID + 271333C40C4602BB005FEE0E + WindowToolIsVisible + + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimator + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + + diff --git a/xcode/xcode.xcodeproj/abisoft.pbxuser b/xcode/xcode.xcodeproj/abisoft.pbxuser new file mode 100644 index 0000000..3da9848 --- /dev/null +++ b/xcode/xcode.xcodeproj/abisoft.pbxuser @@ -0,0 +1,411 @@ +// !$*UTF8*$! +{ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + activeArchitecture = ppc; + activeBuildConfigurationName = Debug; + activeExecutable = 274A5EFC0C2F41FB000A66CF /* Lua 5.1 */; + activeTarget = D2AAC0620554660B00DB518D /* xcode */; + addToTargets = ( + D2AAC0620554660B00DB518D /* xcode */, + ); + breakpoints = ( + 27280DE10C495CCB000FD317 /* gluax_static.c:667 */, + 27280DE60C495D0C000FD317 /* gluax_static.c:663 */, + 27E802B50C4978C700B1E216 /* sdl_module.cpp:630 */, + 277CF6980C4A631C0044B79E /* gluax.c:2476 */, + 2784DBE20CD64B1000B13CF3 /* gluax_static.c:164 */, + 273631630CD71FBC00A12F3E /* lanes.c:1429 */, + 27BD9DD60E403B490056C472 /* lanes.c:1168 */, + 27BD9DEB0E403C250056C472 /* lanes.c:1246 */, + ); + codeSenseManager = 27602E610C2F36D60086E627 /* Code sense */; + executables = ( + 274A5EFC0C2F41FB000A66CF /* Lua 5.1 */, + ); + perUserDictionary = { + "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 20, + 253, + 20, + 152, + 151, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXBreakpointsDataSource_ActionID, + PBXBreakpointsDataSource_TypeID, + PBXBreakpointsDataSource_BreakpointID, + PBXBreakpointsDataSource_UseID, + PBXBreakpointsDataSource_LocationID, + PBXBreakpointsDataSource_ConditionID, + PBXBreakpointsDataSource_ContinueID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 300, + 304, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + PBXExecutablesDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 416, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 200, + 230, + 20, + 48, + 43, + 43, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXTargetDataSource_PrimaryAttribute, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 239090487; + PBXWorkspaceStateSaveDate = 239090487; + }; + perUserProjectItems = { + 27BD9DD90E403B640056C472 /* PBXTextBookmark */ = 27BD9DD90E403B640056C472 /* PBXTextBookmark */; + 27BD9DDA0E403B640056C472 /* PBXTextBookmark */ = 27BD9DDA0E403B640056C472 /* PBXTextBookmark */; + 27BD9DDB0E403B640056C472 /* PBXTextBookmark */ = 27BD9DDB0E403B640056C472 /* PBXTextBookmark */; + 27BD9DEE0E403C960056C472 /* PBXTextBookmark */ = 27BD9DEE0E403C960056C472 /* PBXTextBookmark */; + }; + sourceControlManager = 27602E600C2F36D60086E627 /* Source Control */; + userBuildSettings = { + }; + }; + 27280DE10C495CCB000FD317 /* gluax_static.c:667 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 27602E620C2F37390086E627 /* gluax_static.c */; + hitCount = 0; + ignoreCount = 0; + lineNumber = 667; + modificationTime = 239090794.843809; + state = 1; + }; + 27280DE60C495D0C000FD317 /* gluax_static.c:663 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 27602E620C2F37390086E627 /* gluax_static.c */; + hitCount = 0; + ignoreCount = 0; + lineNumber = 663; + modificationTime = 239090794.844094; + state = 1; + }; + 273631630CD71FBC00A12F3E /* lanes.c:1429 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 279F2E690C4A463C0020A321 /* lanes.c */; + functionName = "GLUA_FUNC()"; + hitCount = 0; + ignoreCount = 0; + lineNumber = 1429; + modificationTime = 239090794.843223; + state = 1; + }; + 274A5EFC0C2F41FB000A66CF /* Lua 5.1 */ = { + isa = PBXExecutable; + activeArgIndices = ( + NO, + YES, + ); + argumentStrings = ( + "-lstrict ../fibonacci.lua", + tests/basic.lua, + ); + autoAttachOnCrash = 1; + breakpointsEnabled = 1; + configStateDict = { + "PBXLSLaunchAction-0" = { + PBXLSLaunchAction = 0; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXLSRunLaunchConfig; + commandLineArgs = ( + ); + displayName = "Executable Runner"; + environment = { + }; + identifier = com.apple.Xcode.launch.runConfig; + remoteHostInfo = ""; + startActionInfo = ""; + }; + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + { + active = YES; + name = LUA_PATH; + value = "src/?.lua;/sw/share/lua/5.1/?.lua"; + }, + { + active = YES; + name = LUA_CPATH; + value = "xcode/build/Debug/lib?.bundle"; + }, + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + launchableReference = 274A5EFD0C2F41FB000A66CF /* lua */; + libgmallocEnabled = 0; + name = "Lua 5.1"; + savedGlobals = { + }; + sourceDirectories = ( + ); + startupPath = /Users/abisoft/Slug/public/2008/Lanes/; + variableFormatDictionary = { + }; + }; + 274A5EFD0C2F41FB000A66CF /* lua */ = { + isa = PBXFileReference; + explicitFileType = "compiled.mach-o.executable"; + name = lua; + path = /sw/bin/lua; + sourceTree = ""; + }; + 27602E600C2F36D60086E627 /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + }; + scmType = ""; + }; + 27602E610C2F36D60086E627 /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + 27602E620C2F37390086E627 /* gluax_static.c */ = { + isa = PBXFileReference; + fileEncoding = 30; + lastKnownFileType = sourcecode.c.c; + name = gluax_static.c; + path = /Users/abisoft/Slug/public/2008/gluax/gluax_static.c; + sourceTree = ""; + }; + 27602E640C2F37390086E627 /* gluax.c */ = { + isa = PBXFileReference; + fileEncoding = 30; + lastKnownFileType = sourcecode.c.c; + name = gluax.c; + path = /Users/abisoft/Slug/public/2008/gluax/gluax.c; + sourceTree = ""; + }; + 27602E660C2F37390086E627 /* sdl_module.cpp */ = { + isa = PBXFileReference; + fileEncoding = 30; + lastKnownFileType = sourcecode.cpp.cpp; + name = sdl_module.cpp; + path = /Users/abisoft/Slug/public/2007/Lanes/sdl_module.cpp; + sourceTree = ""; + }; + 277CF6980C4A631C0044B79E /* gluax.c:2476 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 27602E640C2F37390086E627 /* gluax.c */; + hitCount = 0; + ignoreCount = 0; + lineNumber = 2476; + modificationTime = 239090794.84353; + state = 1; + }; + 2784DBE20CD64B1000B13CF3 /* gluax_static.c:164 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 27602E620C2F37390086E627 /* gluax_static.c */; + functionName = "Loc_PushMetatableRef_()"; + hitCount = 0; + ignoreCount = 0; + lineNumber = 164; + modificationTime = 239090794.842868; + state = 1; + }; + 279F2E690C4A463C0020A321 /* lanes.c */ = { + isa = PBXFileReference; + fileEncoding = 30; + lastKnownFileType = sourcecode.c.c; + name = lanes.c; + path = /Users/abisoft/Slug/public/2008/Lanes/lanes.c; + sourceTree = ""; + }; + 27ACDA660E4031F6004F5C28 /* lanes.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {822, 17500}}"; + sepNavSelRange = "{31197, 0}"; + sepNavVisRange = "{30733, 1064}"; + sepNavWindowFrame = "{{86, 51}, {1052, 971}}"; + }; + }; + 27ACDA680E4031F6004F5C28 /* tools.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {594, 13790}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 1259}"; + }; + }; + 27BD9DD60E403B490056C472 /* lanes.c:1168 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 27ACDA660E4031F6004F5C28 /* lanes.c */; + functionName = "luaopen_lanes()"; + hitCount = 1; + ignoreCount = 0; + lineNumber = 1168; + location = "liblua51-lanes.bundle"; + modificationTime = 239090520.812976; + state = 1; + }; + 27BD9DD90E403B640056C472 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 27ACDA680E4031F6004F5C28 /* tools.c */; + name = "tools.c: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1259; + vrLoc = 0; + }; + 27BD9DDA0E403B640056C472 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 27ACDA660E4031F6004F5C28 /* lanes.c */; + rLen = 0; + rLoc = 1167; + rType = 1; + }; + 27BD9DDB0E403B640056C472 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 27ACDA680E4031F6004F5C28 /* tools.c */; + name = "tools.c: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1259; + vrLoc = 0; + }; + 27BD9DEB0E403C250056C472 /* lanes.c:1246 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 27ACDA660E4031F6004F5C28 /* lanes.c */; + functionName = "luaopen_lanes()"; + hitCount = 0; + ignoreCount = 0; + lineNumber = 1246; + location = "liblua51-lanes.bundle"; + modificationTime = 239090725.673196; + state = 1; + }; + 27BD9DEE0E403C960056C472 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 27ACDA660E4031F6004F5C28 /* lanes.c */; + name = "lanes.c: 1168"; + rLen = 0; + rLoc = 31197; + rType = 0; + vrLen = 1064; + vrLoc = 30733; + }; + 27E802B50C4978C700B1E216 /* sdl_module.cpp:630 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 27602E660C2F37390086E627 /* sdl_module.cpp */; + functionName = "GLUA_FUNC()"; + hitCount = 0; + ignoreCount = 0; + lineNumber = 630; + modificationTime = 239090794.842249; + state = 1; + }; + D2AAC0620554660B00DB518D /* xcode */ = { + activeExec = 0; + }; +} diff --git a/xcode/xcode.xcodeproj/project.pbxproj b/xcode/xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d3b3442 --- /dev/null +++ b/xcode/xcode.xcodeproj/project.pbxproj @@ -0,0 +1,268 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 27602E840C2F3CA40086E627 /* liblua.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 27602E830C2F3CA40086E627 /* liblua.dylib */; }; + 27ACDA690E4031F6004F5C28 /* lanes.c in Sources */ = {isa = PBXBuildFile; fileRef = 27ACDA660E4031F6004F5C28 /* lanes.c */; }; + 27ACDA6A0E4031F6004F5C28 /* threading.c in Sources */ = {isa = PBXBuildFile; fileRef = 27ACDA670E4031F6004F5C28 /* threading.c */; }; + 27ACDA6B0E4031F6004F5C28 /* tools.c in Sources */ = {isa = PBXBuildFile; fileRef = 27ACDA680E4031F6004F5C28 /* tools.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 27602E830C2F3CA40086E627 /* liblua.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = liblua.dylib; path = /sw/lib/liblua.dylib; sourceTree = ""; }; + 279F2E7B0C4A477B0020A321 /* liblua51-lanes.bundle */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "liblua51-lanes.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; + 27ACDA660E4031F6004F5C28 /* lanes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lanes.c; path = ../src/lanes.c; sourceTree = SOURCE_ROOT; }; + 27ACDA670E4031F6004F5C28 /* threading.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = threading.c; path = ../src/threading.c; sourceTree = SOURCE_ROOT; }; + 27ACDA680E4031F6004F5C28 /* tools.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tools.c; path = ../src/tools.c; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D289988505E68E00004EDB86 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 27602E840C2F3CA40086E627 /* liblua.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* xcode */ = { + isa = PBXGroup; + children = ( + 27602E830C2F3CA40086E627 /* liblua.dylib */, + 08FB7795FE84155DC02AAC07 /* Source */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + ); + comments = "\nTo use this XCode project, set \"active build configuration\" to Debug.\n\nYou may need to add \"custom executable\" to the \"Executables\" tree of the project, with:\n- path /sw/bin/lua\n- custom directory /Users/xxx/.../SDL/\n- arguments \"test.lua\"\n- environment LUA_CPATH xcode/build/Debug/lib?.bundle\n- \n\n---\nAK 25.6.2007 (open):\n\nHow to NOT have the \"lib\" prefix for bundles? Tried everything, still XCode places it there. :((\n\n /usr/bin/g++-4.0 -o /Users/abisoft/Slug/public/2007/SDL/xcode/build/Debug/liblua51-sdl.bundle ...\n\nHave to change the LUA_CPATH instead, so we can debug with this.\n\n---\nAK 25.6.2007 (solved):\nAfter changing dylib->bundle there were some issues, same as:\nhttp://osdir.com/ml/lang.realbasic.plugins/2007-01/msg00033.html\n\n\"Perform single-object prelink\" needs to be ticked.\n"; + name = xcode; + sourceTree = ""; + }; + 08FB7795FE84155DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 27ACDA660E4031F6004F5C28 /* lanes.c */, + 27ACDA670E4031F6004F5C28 /* threading.c */, + 27ACDA680E4031F6004F5C28 /* tools.c */, + ); + name = Source; + sourceTree = ""; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 279F2E7B0C4A477B0020A321 /* liblua51-lanes.bundle */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D2AAC0600554660B00DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D2AAC0620554660B00DB518D /* xcode */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "xcode" */; + buildPhases = ( + D2AAC0600554660B00DB518D /* Headers */, + D2AAC0610554660B00DB518D /* Sources */, + D289988505E68E00004EDB86 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = xcode; + productName = xcode; + productReference = 279F2E7B0C4A477B0020A321 /* liblua51-lanes.bundle */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "xcode" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + mainGroup = 08FB7794FE84155DC02AAC07 /* xcode */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D2AAC0620554660B00DB518D /* xcode */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + D2AAC0610554660B00DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 27ACDA690E4031F6004F5C28 /* lanes.c in Sources */, + 27ACDA6A0E4031F6004F5C28 /* threading.c in Sources */, + 27ACDA6B0E4031F6004F5C28 /* tools.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1DEB914B08733D8E0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + EXECUTABLE_PREFIX = lib; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = /usr/local/lib; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + /sw/lib, + ); + PRODUCT_NAME = "lua51-lanes"; + ZERO_LINK = NO; + }; + name = Debug; + }; + 1DEB914C08733D8E0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = NO; + EXECUTABLE_PREFIX = lib; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = /usr/local/lib; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + /sw/lib, + ); + PRODUCT_NAME = "lua51-lanes"; + ZERO_LINK = NO; + }; + name = Release; + }; + 1DEB914F08733D8E0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = /sw/bin/lua; + DYLIB_COMPATIBILITY_VERSION = ""; + DYLIB_CURRENT_VERSION = ""; + EXECUTABLE_EXTENSION = bundle; + EXECUTABLE_PREFIX = ""; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + GLUA_LUA51, + "_GNU_SOURCE=1", + _THREAD_SAFE, + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_PEDANTIC = NO; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_MASTER_OBJECT_FILE = YES; + HEADER_SEARCH_PATHS = ( + ../../gluax, + /sw/include, + ); + LIBRARY_SEARCH_PATHS = /sw/lib; + MACH_O_TYPE = mh_bundle; + OTHER_LDFLAGS = ( + "-framework", + Cocoa, + ); + PREBINDING = NO; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; + PRELINK_LIBS = ""; + PRODUCT_NAME = "lua51-lanes"; + SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SHARED_PRECOMPS_DIR = ""; + }; + name = Debug; + }; + 1DEB915008733D8E0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = /sw/bin/lua; + DYLIB_COMPATIBILITY_VERSION = ""; + DYLIB_CURRENT_VERSION = ""; + EXECUTABLE_EXTENSION = bundle; + EXECUTABLE_PREFIX = ""; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + GLUA_LUA51, + "_GNU_SOURCE=1", + _THREAD_SAFE, + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_PEDANTIC = NO; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_MASTER_OBJECT_FILE = YES; + HEADER_SEARCH_PATHS = ( + ../../gluax, + /sw/include, + ); + LIBRARY_SEARCH_PATHS = /sw/lib; + MACH_O_TYPE = mh_bundle; + OTHER_LDFLAGS = ( + "-framework", + Cocoa, + ); + PREBINDING = NO; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; + PRELINK_LIBS = ""; + PRODUCT_NAME = "lua51-lanes"; + SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SHARED_PRECOMPS_DIR = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB914B08733D8E0010E9CD /* Debug */, + 1DEB914C08733D8E0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB914F08733D8E0010E9CD /* Debug */, + 1DEB915008733D8E0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/xcode/xcode.xcodeproj/soumya.pbxuser b/xcode/xcode.xcodeproj/soumya.pbxuser new file mode 100644 index 0000000..20ae264 --- /dev/null +++ b/xcode/xcode.xcodeproj/soumya.pbxuser @@ -0,0 +1,124 @@ +// !$*UTF8*$! +{ + 0429C3740C416BB800EC1476 /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + }; + scmType = ""; + }; + 0429C3750C416BB800EC1476 /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + 04C412EF0C42B7D500A0AD77 /* Lua */ = { + isa = PBXExecutable; + activeArgIndex = 0; + activeArgIndices = ( + YES, + ); + argumentStrings = ( + test.lua, + ); + autoAttachOnCrash = 1; + comments = "This is not stored in svn, is it?\n"; + configStateDict = { + "PBXLSLaunchAction-0" = { + PBXLSLaunchAction = 0; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXLSRunLaunchConfig; + displayName = "Executable Runner"; + identifier = com.apple.Xcode.launch.runConfig; + remoteHostInfo = ""; + startActionInfo = ""; + }; + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + { + active = YES; + name = LUA_CPATH; + value = "xcode/build/Debug/lib?.bundle"; + }, + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + launchableReference = 04C412F00C42B7D500A0AD77 /* lua */; + libgmallocEnabled = 0; + name = Lua; + savedGlobals = { + }; + sourceDirectories = ( + ); + startupPath = /Users/soumya/Slug/public/2007/SDL/; + }; + 04C412F00C42B7D500A0AD77 /* lua */ = { + isa = PBXFileReference; + explicitFileType = "compiled.mach-o.executable"; + name = lua; + path = /sw/bin/lua; + sourceTree = ""; + }; + 08FB7793FE84155DC02AAC07 /* Project object */ = { + activeBuildConfigurationName = Debug; + activeExecutable = 04C412EF0C42B7D500A0AD77 /* Lua */; + activeTarget = D2AAC0620554660B00DB518D /* xcode */; + codeSenseManager = 0429C3750C416BB800EC1476 /* Code sense */; + executables = ( + 04C412EF0C42B7D500A0AD77 /* Lua */, + ); + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 300, + 225, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + PBXExecutablesDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 338, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 205699730; + PBXWorkspaceStateSaveDate = 205699730; + }; + sourceControlManager = 0429C3740C416BB800EC1476 /* Source Control */; + userBuildSettings = { + }; + }; + D2AAC0620554660B00DB518D /* xcode */ = { + activeExec = 0; + }; +} -- cgit v1.2.3-55-g6feb