diff options
-rw-r--r-- | BUGS | 111 | ||||
-rw-r--r-- | CHANGES | 74 | ||||
-rw-r--r-- | COPYRIGHT | 2 | ||||
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | TODO | 17 | ||||
-rw-r--r-- | docs/comparison.html | 28 | ||||
-rw-r--r-- | docs/index.html | 44 | ||||
-rw-r--r-- | lanes-2.0-2.rockspec | 95 | ||||
-rw-r--r-- | lanes-2.0.2.tgz | bin | 0 -> 312965 bytes | |||
-rw-r--r-- | setup-vc.cmd | 8 | ||||
-rw-r--r-- | src/keeper.lua | 4 | ||||
-rw-r--r-- | src/lanes.c | 732 | ||||
-rw-r--r-- | src/lanes.lua | 33 | ||||
-rw-r--r-- | src/threading.c | 9 | ||||
-rw-r--r-- | src/tools.c | 260 | ||||
-rw-r--r-- | src/tools.h | 2 | ||||
-rw-r--r-- | tests/appendud.lua | 58 | ||||
-rw-r--r-- | tests/basic.lua | 52 | ||||
-rw-r--r-- | tests/func_is_string.lua | 12 | ||||
-rw-r--r-- | xcode/xcode.xcodeproj/abisoft.mode1 | 1460 | ||||
-rw-r--r-- | xcode/xcode.xcodeproj/abisoft.pbxuser | 411 | ||||
-rw-r--r-- | xcode/xcode.xcodeproj/project.pbxproj | 268 | ||||
-rw-r--r-- | xcode/xcode.xcodeproj/soumya.pbxuser | 124 |
23 files changed, 3319 insertions, 492 deletions
@@ -1,6 +1,117 @@ | |||
1 | 1 | ||
2 | BUGS: | 2 | BUGS: |
3 | 3 | ||
4 | - Reported by Pierre LeMoine (Dec-2009: | ||
5 | << | ||
6 | Hi! | ||
7 | I think i've located an error in Lanes. When a finalizer is called, it | ||
8 | receive two tables. The second one seems to be the table containing | ||
9 | the finalizers. The attached test reproduces the error, and is tested | ||
10 | on binaries built by myself and from the LfW project. | ||
11 | The following line from run_finalizers in lanes.c seems to be wrong to me: | ||
12 | |||
13 | error_index= (lua_rc!=0) ? tbl_index-1 : 0; // absolute indices | ||
14 | |||
15 | I think it should be -2 there, since the stack at this point should look like | ||
16 | [-1] finalizer table <- tbl_index | ||
17 | [-2] stack table | ||
18 | [-3] error string | ||
19 | |||
20 | Also, in some places, checks for valid returns from lua_toLinda are | ||
21 | missing, leading to crashes. (for example, linda.get) | ||
22 | |||
23 | Sometimes when i use lanes i get a "recursive use of upvalues"-error, | ||
24 | i fail to see how upvalues can be recursive? =) | ||
25 | |||
26 | /Pierre | ||
27 | << | ||
28 | |||
29 | |||
30 | - Reported by Benoit Germain (Dec-2009): | ||
31 | << | ||
32 | Doc says : | ||
33 | |||
34 | The current execution state of a lane can be read via its status member, providing one of these values: | ||
35 | |||
36 | |||
37 | "waiting" waiting at a Linda :receive() or :send() | ||
38 | |||
39 | |||
40 | |||
41 | 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 : | ||
42 | |||
43 | LUAG_FUNC( linda_receive ) { | ||
44 | ... | ||
45 | // BBB HACK: fetch the lane object to update the status | ||
46 | { | ||
47 | struct s_lane *s; | ||
48 | enum e_status prev_status; | ||
49 | STACK_GROW(L,1); | ||
50 | |||
51 | STACK_CHECK(L) | ||
52 | lua_pushlightuserdata( L, CANCEL_TEST_KEY ); | ||
53 | lua_rawget( L, LUA_REGISTRYINDEX ); | ||
54 | s= lua_touserdata( L, -1 ); // lightuserdata (true 's_lane' pointer) / nil | ||
55 | lua_pop(L,1); | ||
56 | STACK_END(L,0) | ||
57 | if( s) | ||
58 | { | ||
59 | prev_status = s->status; | ||
60 | s->status = WAITING; | ||
61 | } | ||
62 | if (!SIGNAL_WAIT( &linda->write_happened, &K->lock_, timeout )) | ||
63 | { | ||
64 | if( s) s->status = prev_status; | ||
65 | break; | ||
66 | } | ||
67 | if( s) s->status = prev_status; | ||
68 | } | ||
69 | |||
70 | 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? | ||
71 | << | ||
72 | |||
73 | |||
74 | - The use of 'static' and "one time" initialization of things is not suitable | ||
75 | to a situation where a Lua state is run, using Lanes, then terminated. If | ||
76 | another Lua state later is launched, the initializations will get cramped. | ||
77 | |||
78 | Reported by Boris Ouretskey (25-Jun-09) | ||
79 | |||
80 | |||
81 | - a 'require "lanes"' and speedy exit from the process causes a segfault | ||
82 | on ArchLinux (reported by kkndrox@gmail.com 1-Jun-2009). | ||
83 | |||
84 | This issue is not reproducible on Ubuntu (8.04 or 9.04) and has not therefore | ||
85 | been fixed. A patch is welcome. The issue is most likely caused by the | ||
86 | Linda thread not being properly launched when the process itself already | ||
87 | quits. | ||
88 | |||
89 | << | ||
90 | With Lanes 2.0.3, the following code *always* gives me a segmentation | ||
91 | fault: | ||
92 | |||
93 | -- begin | ||
94 | require("lanes") | ||
95 | -- end | ||
96 | |||
97 | But this: | ||
98 | |||
99 | -- begin | ||
100 | require("lanes") | ||
101 | garbagecollect('collect') | ||
102 | -- end | ||
103 | |||
104 | always work. | ||
105 | |||
106 | Based on this experimentation, if I require lanes and the program end | ||
107 | without any garbage collecting, I receive a segmentation fault. | ||
108 | I'm using Arch Linux (32bits), Lua 5.1.4 and it was compiled with gcc 4.3 | ||
109 | << | ||
110 | |||
111 | Also simply waiting a bit ('os.execute("sleep 1")') avoids the crash. | ||
112 | |||
113 | |||
4 | - tests/irayo_closure.lua fails (trouble with setting globals right | 114 | - tests/irayo_closure.lua fails (trouble with setting globals right |
5 | for functions carried over to another Lua state) | 115 | for functions carried over to another Lua state) |
6 | 116 | ||
117 | - "make appendud" causes a segfault on OS X PowerPC. | ||
@@ -3,11 +3,51 @@ CHANGES: | |||
3 | 3 | ||
4 | CHANGE X: | 4 | CHANGE X: |
5 | 5 | ||
6 | CHANGE 21 (bugfixes) BGe 3-Jan-2011: | ||
7 | Several fixes by Martin Krpan: | ||
8 | - linda_send was waiting on the wrong signal | ||
9 | - buildfix when using i586-mingw32msvc-gcc cross compiler | ||
10 | - lanes_h:cancel() returns a boolean as it should | ||
11 | - timers could get blocked sometimes because they were initialized with negative values | ||
12 | - prepare_timeout could generate an illegal setting | ||
13 | |||
14 | CHANGE 20 BGe 3-Dec-2010: | ||
15 | Enable to specify a string as lane code instead of a function so that we dont use lua_dump, which | ||
16 | isn't supported by LuaJIT. | ||
17 | |||
18 | CHANGE 19 BGe 2-Dec-2010: | ||
19 | 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. | ||
20 | |||
21 | CHANGE 18 BGe 6-Oct-2010: | ||
22 | Fixed 'memory leak' in some situations where a free running lane is collected before application shutdown | ||
23 | A bit of code cleanup | ||
24 | |||
25 | CHANGE 17 BGe 21-Sept-2010: | ||
26 | Fixed stupid compilation errors. | ||
27 | |||
28 | CHANGE 16 PLM 24-Aug-2010: | ||
29 | Releasing memory at gc / atexit. | ||
30 | Finalizers actually get error strings. | ||
31 | Fixed missing argument propagation in lane:cancel | ||
32 | Added variable threadName sent trough globals-table. Set in s_lane, and in debuggers on windows. | ||
33 | Added argument checking for linda-objects, where missing them caused crashes. | ||
34 | |||
35 | CHANGE 15 (minor) BGe 27-Jul-2010: | ||
36 | Version bump for a true upgrade release (2.0.4 package was only a renamed 2.0.3) | ||
37 | |||
38 | CHANGE 14 (bug fix) BGe 09-Jul-2010: | ||
39 | Fixed lane status to be correctly returned as "waiting" when it should. | ||
40 | |||
41 | CHANGE 13 (fix for multithreaded host apps) AKa 24-Jun-2009: | ||
42 | <borisusun-at-gmail> mentioned Lanes expects the host application to be singlethreaded, | ||
43 | and there are troubles if Lanes is used from multiple threads, opened by the host | ||
44 | (before requiring Lanes). This is true, and fix should now be in place. | ||
45 | |||
6 | CHANGE 12 (bug fix on Windows, 2.0.3) AKa 25-Jan-2009: | 46 | CHANGE 12 (bug fix on Windows, 2.0.3) AKa 25-Jan-2009: |
7 | Did CHANGE 9 the way it should be done. | 47 | Did CHANGE 9 the way it should be done. |
8 | 48 | ||
9 | CHANGE 11 (new feature, 2.0.3) AKa 23-Jan-2009: | 49 | CHANGE 11 (new feature, 2.0.3) AKa 23-Jan-2009: |
10 | Finalizers ('set_finalizer()') for being able to do cleanup of a lane's | 50 | Finalizers ('set_finalizer()') for being able to do cleanup of a lane's |
11 | resources, whether it returned succesfully or via an error. | 51 | resources, whether it returned succesfully or via an error. |
12 | 52 | ||
13 | CHANGE 10 (new feature, 2.0.3) AKa 23-Jan-2009: | 53 | 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: | |||
18 | CHANGE 9 (bug fix on Windows) AKa 10-Dec-2008 (> 2.0.2): | 58 | CHANGE 9 (bug fix on Windows) AKa 10-Dec-2008 (> 2.0.2): |
19 | Applied patch from Kriss Daniels to avoid issues on 'now_time()' in Win32 | 59 | Applied patch from Kriss Daniels to avoid issues on 'now_time()' in Win32 |
20 | (http://luaforge.net/forum/forum.php?thread_id=22704&forum_id=1781). | 60 | (http://luaforge.net/forum/forum.php?thread_id=22704&forum_id=1781). |
21 | 61 | ||
22 | CHANGE 8 (bug fix) AKa 26-Oct-2008: | 62 | CHANGE 8 (bug fix) AKa 26-Oct-2008: |
23 | Avoids occasional segfault at process exit (on multicore CPUs). Does this | 63 | Avoids occasional segfault at process exit (on multicore CPUs). Does this |
24 | by keeping track of "free running" threads (s.a. the time thread) and | 64 | by keeping track of "free running" threads (s.a. the time thread) and |
25 | cancelling them at process exit. | 65 | cancelling them at process exit. |
26 | 66 | ||
27 | Tested (2.0.2) on Linux 64,x86, OS X, WinXP. | 67 | Tested (2.0.2) on Linux 64,x86, OS X, WinXP. |
28 | 68 | ||
29 | CHANGE 7 (bug fix) AKa 15-Oct-2008: | 69 | CHANGE 7 (bug fix) AKa 15-Oct-2008: |
@@ -34,15 +74,15 @@ CHANGE 6 (bug fix) AKa 15-Oct-2008: | |||
34 | Added local caches of the following to src/lanes.lua (was otherwise getting | 74 | Added local caches of the following to src/lanes.lua (was otherwise getting |
35 | errors at least in 'tests/irayo_recursive.lua'). | 75 | errors at least in 'tests/irayo_recursive.lua'). |
36 | 76 | ||
37 | local assert= assert | 77 | local assert= assert |
38 | local string_gmatch= assert( string.gmatch ) | 78 | local string_gmatch= assert( string.gmatch ) |
39 | local select= assert( select ) | 79 | local select= assert( select ) |
40 | local type= assert( type ) | 80 | local type= assert( type ) |
41 | local pairs= assert( pairs ) | 81 | local pairs= assert( pairs ) |
42 | local tostring= assert( tostring ) | 82 | local tostring= assert( tostring ) |
43 | local error= assert( error ) | 83 | local error= assert( error ) |
44 | local setmetatable= assert( setmetatable ) | 84 | local setmetatable= assert( setmetatable ) |
45 | local rawget= assert( rawget ) | 85 | local rawget= assert( rawget ) |
46 | 86 | ||
47 | Thanks to Irayo for detecting and reporting this. | 87 | Thanks to Irayo for detecting and reporting this. |
48 | 88 | ||
@@ -55,17 +95,17 @@ CHANGE 4 (new feature): | |||
55 | CHANGE 3 (bug fix) AKa 5-Aug-2008: | 95 | CHANGE 3 (bug fix) AKa 5-Aug-2008: |
56 | The '__gc' method was not tied to thread userdata, at all. Caused memory | 96 | The '__gc' method was not tied to thread userdata, at all. Caused memory |
57 | lifespan problems at least on OS X when threads were cancelled (EINVAL). | 97 | lifespan problems at least on OS X when threads were cancelled (EINVAL). |
58 | 98 | ||
59 | CHANGE 2 (bug fix) AKa 5-Aug-2008: | 99 | CHANGE 2 (bug fix) AKa 5-Aug-2008: |
60 | Better calculation of timeouts, always making them absolute (even in Win32) | 100 | Better calculation of timeouts, always making them absolute (even in Win32) |
61 | to allow for events that wake the lane up but don't read/write the Linda | 101 | to allow for events that wake the lane up but don't read/write the Linda |
62 | key that it was observing. | 102 | key that it was observing. |
63 | 103 | ||
64 | CHANGE 1 (bug fix) AKa 4-Aug-2008: | 104 | CHANGE 1 (bug fix) AKa 4-Aug-2008: |
65 | Signalling woke up only one waiting thread, not all. This caused i.e. | 105 | Signalling woke up only one waiting thread, not all. This caused i.e. |
66 | receive to not wake up if there was another thread waiting on the same | 106 | receive to not wake up if there was another thread waiting on the same |
67 | Linda object. | 107 | Linda object. |
68 | 108 | ||
69 | PThread fix: using 'pthread_cond_broadcast()' instead of 'pthread_cond_signal()' | 109 | PThread fix: using 'pthread_cond_broadcast()' instead of 'pthread_cond_signal()' |
70 | Win32 fix: using manual events and 'PulseEvent()' | 110 | Win32 fix: using manual events and 'PulseEvent()' |
71 | 111 | ||
@@ -6,7 +6,7 @@ For details and rationale, see http://www.lua.org/license.html | |||
6 | 6 | ||
7 | =============================================================================== | 7 | =============================================================================== |
8 | 8 | ||
9 | Copyright (C) 2007-09 Asko Kauppi, <akauppi@gmail.com> | 9 | Copyright (C) 2007-11 Asko Kauppi, <akauppi@gmail.com> |
10 | 10 | ||
11 | Permission is hereby granted, free of charge, to any person obtaining a copy | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy |
12 | of this software and associated documentation files (the "Software"), to deal | 12 | of this software and associated documentation files (the "Software"), to deal |
@@ -82,6 +82,7 @@ test: | |||
82 | $(MAKE) objects | 82 | $(MAKE) objects |
83 | $(MAKE) fibonacci | 83 | $(MAKE) fibonacci |
84 | $(MAKE) recursive | 84 | $(MAKE) recursive |
85 | $(MAKE) func_is_string | ||
85 | 86 | ||
86 | basic: tests/basic.lua $(_TARGET_SO) | 87 | basic: tests/basic.lua $(_TARGET_SO) |
87 | $(_PREFIX) $(LUA) $< | 88 | $(_PREFIX) $(LUA) $< |
@@ -143,6 +144,12 @@ finalizer: tests/finalizer.lua $(_TARGET_SO) | |||
143 | error-test: tests/error.lua $(_TARGET_SO) | 144 | error-test: tests/error.lua $(_TARGET_SO) |
144 | $(_PREFIX) $(LUA) $< | 145 | $(_PREFIX) $(LUA) $< |
145 | 146 | ||
147 | appendud: tests/appendud.lua $(_TARGET_SO) | ||
148 | $(_PREFIX) $(LUA) $< | ||
149 | |||
150 | func_is_string: tests/func_is_string.lua $(_TARGET_SO) | ||
151 | $(_PREFIX) $(LUA) $< | ||
152 | |||
146 | #--- | 153 | #--- |
147 | perftest-plain: tests/perftest.lua $(_TARGET_SO) | 154 | perftest-plain: tests/perftest.lua $(_TARGET_SO) |
148 | $(MAKE) _perftest ARGS="$< $(N) -plain" | 155 | $(MAKE) _perftest ARGS="$< $(N) -plain" |
@@ -1,4 +1,21 @@ | |||
1 | 1 | ||
2 | TODO: | 2 | TODO: |
3 | 3 | ||
4 | - Use of 'atexit()' is not good. It's possible to be called at "program (process) | ||
5 | exit", when the so might already be out. Tying to OS specific so cleanup | ||
6 | is way better. | ||
7 | |||
4 | - Testing Lane killing (not cancellation, but actual killing) | 8 | - Testing Lane killing (not cancellation, but actual killing) |
9 | |||
10 | - Like luaproc: Lanes to have M:N relationship to kernel threads | ||
11 | (= give a maximum number of kernel threads to run, then juggle those to run a Lane, | ||
12 | until the lane suspends, blocks, or exits) | ||
13 | (default could be twice the kernel threads of the CPU count, or something.) | ||
14 | |||
15 | - Like luaproc: | ||
16 | "only the basic standard | ||
17 | library and our own library are automatically loaded into each new Lua process. The re- | ||
18 | maining standard libraries (io, os, table, string, math, and debug) are pre-registered and | ||
19 | can be loaded with a standard call to Lua’s require function. " | ||
20 | |||
21 | - 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: | |||
49 | 49 | ||
50 | Cons: | 50 | Cons: |
51 | - requires OS threads | 51 | - requires OS threads |
52 | - currently 1:1 mapping to OS threads (limits scalability and maybe performance) | ||
52 | - not utilizing network parallelism (all threads on one CPU) | 53 | - not utilizing network parallelism (all threads on one CPU) |
53 | 54 | ||
54 | Sample: | 55 | Sample: |
@@ -70,6 +71,31 @@ Sample: | |||
70 | << | 71 | << |
71 | 72 | ||
72 | 73 | ||
74 | =========== | ||
75 | luaproc (by Skyrme, Rodriguez and Ierusalimschy) | ||
76 | =========== | ||
77 | |||
78 | <A HREF="http://www.inf.puc-rio.br/~roberto/docs/ry08-05.pdf">http://www.inf.puc-rio.br/~roberto/docs/ry08-05.pdf</A> | ||
79 | |||
80 | The PDF seems to be an authorative voyage into how Lua could handle multithreading, | ||
81 | in a multicore "separate universes" manner (not like what coroutines already do). | ||
82 | |||
83 | Pros: | ||
84 | - Tackles both multicore and network parallelism | ||
85 | - M:N relationship to kernel threads (one kernel thread runs multiple luaprocs) | ||
86 | - Simple (so they say) | ||
87 | - Lua author (Roberto) included | ||
88 | - Can be used also without _any_ OS threading support (works like Rings, then) | ||
89 | |||
90 | Cons: | ||
91 | - Data passing for "strings, number, or booleans" only | ||
92 | "More complex types must be encoded in some form" | ||
93 | (serializing data is slower than the stack-to-stack copies used by i.e. Lanes) | ||
94 | (yet, serializing allows for network parallelism) | ||
95 | - Message passing is synchronous (only). The sender will wait until the | ||
96 | receiver has taken the message. | ||
97 | |||
98 | |||
73 | ================== | 99 | ================== |
74 | Lua coroutines (by Lua authors) | 100 | Lua coroutines (by Lua authors) |
75 | ================== | 101 | ================== |
@@ -157,7 +183,7 @@ but it won't use more than one CPU core. Other differences include: | |||
157 | (Lanes opens the needed ones) | 183 | (Lanes opens the needed ones) |
158 | 184 | ||
159 | - marshalls numbers, strings, booleans, userdata | 185 | - marshalls numbers, strings, booleans, userdata |
160 | (Lanes marshalls also non-cyclic tables) | 186 | (Lanes also marshalls tables, functions, upvalues, ..) |
161 | 187 | ||
162 | - "remotedostring" allows executing code in the master state | 188 | - "remotedostring" allows executing code in the master state |
163 | (Lanes does _not_ allow subthreads to trouble/modify master automatically, | 189 | (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 @@ | |||
54 | <a href="#changes">Change log</a> | 54 | <a href="#changes">Change log</a> |
55 | <!-- ... --> | 55 | <!-- ... --> |
56 | 56 | ||
57 | <p><br/><font size="-1"><i>Copyright © 2007-08 Asko Kauppi. All rights reserved.</i> | 57 | <p><br/><font size="-1"><i>Copyright © 2007-11 Asko Kauppi. All rights reserved.</i> |
58 | <br>Lua Lanes is published under the same <A HREF="http://en.wikipedia.org/wiki/MIT_License">MIT license</A> as Lua 5.1. | 58 | <br>Lua Lanes is published under the same <A HREF="http://en.wikipedia.org/wiki/MIT_License">MIT license</A> as Lua 5.1. |
59 | </p><p>This document was revised on 23-Jan-09, and applies to version 2.0.3. | 59 | </p><p>This document was revised on 3-Jan-11, and applies to version 2.0.10. |
60 | </font></p> | 60 | </font></p> |
61 | 61 | ||
62 | </center> | 62 | </center> |
@@ -195,6 +195,9 @@ joins the threads, waiting for any results not already there. | |||
195 | launching any number of lanes. They will share code, options, initial globals, | 195 | launching any number of lanes. They will share code, options, initial globals, |
196 | but the particular arguments may vary. Only calling the generator function | 196 | but the particular arguments may vary. Only calling the generator function |
197 | actually launches a lane, and provides a handle for controlling it. | 197 | actually launches a lane, and provides a handle for controlling it. |
198 | Alternatively, <tt>lane_func</tt> may be a string, in which case it will be compiled | ||
199 | in the lane. This is to be able to launch lanes whith LuaJIT, | ||
200 | which does not support lua_dump, used internally to transfer functions to the lane. | ||
198 | <!-- | 201 | <!-- |
199 | </p> | 202 | </p> |
200 | <p>This prepares <tt>lane_func</tt> to be called in parallel. It does not yet start | 203 | <p>This prepares <tt>lane_func</tt> to be called in parallel. It does not yet start |
@@ -237,7 +240,7 @@ also in the new lanes. | |||
237 | <tr valign=top><td/><td> | 240 | <tr valign=top><td/><td> |
238 | <code>.cancelstep</code> <br/><nobr>N / true</nobr></td> | 241 | <code>.cancelstep</code> <br/><nobr>N / true</nobr></td> |
239 | <td> | 242 | <td> |
240 | By default, lanes are only cancellable when they enter a pending | 243 | By default, lanes are only cancellable when they <u>enter</u> a pending |
241 | <tt>:receive()</tt> or <tt>:send()</tt> call. | 244 | <tt>:receive()</tt> or <tt>:send()</tt> call. |
242 | With this option, one can set cancellation check to occur every <tt>N</tt> | 245 | With this option, one can set cancellation check to occur every <tt>N</tt> |
243 | Lua statements. The value <tt>true</tt> uses a default value (100). | 246 | Lua statements. The value <tt>true</tt> uses a default value (100). |
@@ -250,7 +253,7 @@ also in the new lanes. | |||
250 | them constants. | 253 | them constants. |
251 | </p><p> | 254 | </p><p> |
252 | The global values of different lanes are in no manner connected; | 255 | The global values of different lanes are in no manner connected; |
253 | modifying one will only affect the particular lane. | 256 | modifying one will only affect the particular lane. Settings the variable 'threadName' in this table makes VS display the sent name instead of the normal thread name while debugging. |
254 | </td></tr> | 257 | </td></tr> |
255 | 258 | ||
256 | <tr valign=top><td width=40><td> | 259 | <tr valign=top><td width=40><td> |
@@ -360,6 +363,12 @@ between a timed out join and the moment you read it). | |||
360 | </pre> | 363 | </pre> |
361 | </table> | 364 | </table> |
362 | 365 | ||
366 | <p> | ||
367 | If you want to wait for multiple lanes to finish (any of a set of lanes), use | ||
368 | a <a href="#lindas">Linda</a> object. Give each lane a specific id, and send | ||
369 | that id over a Linda once that thread is done (as the last thing you do). | ||
370 | </p> | ||
371 | |||
363 | 372 | ||
364 | <!-- cancelling +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 373 | <!-- cancelling +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
365 | <hr/> | 374 | <hr/> |
@@ -378,7 +387,7 @@ If the lane is still running and <tt>force_kill</tt> is <tt>true</tt>, the | |||
378 | OS thread running the lane is forcefully killed. This means no GC, and should | 387 | OS thread running the lane is forcefully killed. This means no GC, and should |
379 | generally be the last resort. | 388 | generally be the last resort. |
380 | </p> | 389 | </p> |
381 | <p>Cancellation is tested before going to sleep in <tt>receive()</tt> or <tt>send()</tt> calls | 390 | <p>Cancellation is tested <u>before</u> going to sleep in <tt>receive()</tt> or <tt>send()</tt> calls |
382 | and after executing <tt>cancelstep</tt> Lua statements. A currently pending <tt>receive</tt> | 391 | and after executing <tt>cancelstep</tt> Lua statements. A currently pending <tt>receive</tt> |
383 | or <tt>send</tt> call is currently not awakened, and may be a reason for a non-detected cancel. | 392 | or <tt>send</tt> call is currently not awakened, and may be a reason for a non-detected cancel. |
384 | </p> | 393 | </p> |
@@ -920,6 +929,30 @@ its actual value. | |||
920 | <h2 id="changes">Change log</h2> | 929 | <h2 id="changes">Change log</h2> |
921 | 930 | ||
922 | <p> | 931 | <p> |
932 | Jan-2011 (2.0.10): | ||
933 | <ul> | ||
934 | <li>linda_send was waiting on the wrong signal</li> | ||
935 | <li>buildfix when using i586-mingw32msvc-gcc cross compiler</li> | ||
936 | <li>lanes_h:cancel() returns a boolean as it should</li> | ||
937 | <li>timers could get blocked sometimes because they were initialized with negative values</li> | ||
938 | <li>prepare_timeout could generate an illegal setting</li> | ||
939 | </ul> | ||
940 | |||
941 | Dec-2010 (2.0.9): | ||
942 | <ul> | ||
943 | <li>Fixed 'memory leak' in some situations where a free running lane is collected before application shutdown</li> | ||
944 | <li>Fix LuaJIT2 incompatibility (no 'tostring' hijack anymore)</li> | ||
945 | <li>Added support to generate a lane from a string</li> | ||
946 | </ul> | ||
947 | |||
948 | Aug-2010 (2.0.6): | ||
949 | <ul> | ||
950 | <li>Fixed some memory leaks</li> | ||
951 | <li>Fixed error in passing parameters to finalizers</li> | ||
952 | <li>Fixed missing argument propagation in lane:cancel</li> | ||
953 | <li>Added thread name debugging in VS</li> | ||
954 | </ul> | ||
955 | |||
923 | Jan-2009 (2.0.3): | 956 | Jan-2009 (2.0.3): |
924 | <ul> | 957 | <ul> |
925 | <li>Added 'finalizer' to lane options. (TBD: not implemented yet!) | 958 | <li>Added 'finalizer' to lane options. (TBD: not implemented yet!) |
@@ -942,6 +975,7 @@ Jul-2008 (2.0): | |||
942 | <UL> | 975 | <UL> |
943 | <li><A HREF="http://luaforge.net/projects/lanes">Lanes @ LuaForge</A></li> | 976 | <li><A HREF="http://luaforge.net/projects/lanes">Lanes @ LuaForge</A></li> |
944 | <li><A HREF="mailto:akauppi@gmail.com">the author</A></li> | 977 | <li><A HREF="mailto:akauppi@gmail.com">the author</A></li> |
978 | <li><A HREF="http://www.lua.org/lua-l.html">the lua mailing list</A></li> | ||
945 | </UL> | 979 | </UL> |
946 | </p> | 980 | </p> |
947 | 981 | ||
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 @@ | |||
1 | -- | ||
2 | -- Lanes rockspec | ||
3 | -- | ||
4 | -- Ref: | ||
5 | -- <http://luarocks.org/en/Rockspec_format> | ||
6 | -- | ||
7 | -- History: | ||
8 | -- AKa 1-Sep-2008: 2.0-2 (NOT sent to list): fixed VC++ not finding DLL issue | ||
9 | -- AKa 20-Aug-2008: 2.0-1 sent to luarocks-developers | ||
10 | -- | ||
11 | |||
12 | package = "Lanes" | ||
13 | |||
14 | version = "2.0-2" | ||
15 | |||
16 | source= { | ||
17 | url= "http://akauppi.googlepages.com/lanes-2.0.tgz", | ||
18 | md5= "27a807828de0bda3787dbcd2d4947019" | ||
19 | } | ||
20 | |||
21 | description = { | ||
22 | summary= "Multithreading support for Lua", | ||
23 | detailed= [[ | ||
24 | Lua Lanes is a portable, message passing multithreading library | ||
25 | providing the possibility to run multiple Lua states in parallel. | ||
26 | ]], | ||
27 | license= "MIT/X11", | ||
28 | homepage="http://kotisivu.dnainternet.net/askok/lanes/", | ||
29 | maintainer="Asko Kauppi <akauppi@gmail.com>" | ||
30 | } | ||
31 | |||
32 | -- Q: What is the difference of "windows" and "win32"? Seems there is none; | ||
33 | -- so should we list either one or both? | ||
34 | -- | ||
35 | supported_platforms= { "win32", | ||
36 | "macosx", | ||
37 | "linux", | ||
38 | "freebsd", -- TBD: not tested | ||
39 | "msys", -- TBD: not supported by LuaRocks 1.0 (or is it?) | ||
40 | } | ||
41 | |||
42 | dependencies= { | ||
43 | "lua >= 5.1, < 5.2", | ||
44 | } | ||
45 | |||
46 | -- | ||
47 | -- Non-Win32: build using the Makefile | ||
48 | -- Win32: build using 'make-vc.cmd' and "manual" copy of products | ||
49 | -- | ||
50 | -- TBD: How is MSYS treated? We'd like (really) it to use the Makefile. | ||
51 | -- It should be a target like "cygwin", not defining "windows". | ||
52 | -- "windows" should actually guarantee Visual C++ as the compiler. | ||
53 | -- | ||
54 | -- Q: Does "win32" guarantee we have Visual C++ 2005/2008 command line tools? | ||
55 | -- | ||
56 | -- Note: Cannot use the simple "module" build type, because we need to precompile | ||
57 | -- 'src/keeper.lua' -> keeper.lch and bake it into lanes.c. | ||
58 | -- | ||
59 | build = { | ||
60 | |||
61 | -- Win32 (Visual C++) uses 'make-vc.cmd' for building | ||
62 | -- | ||
63 | platforms= { | ||
64 | windows= { | ||
65 | type= "command", | ||
66 | build_command= "make-vc.cmd", | ||
67 | install= { | ||
68 | lua = { "src/lanes.lua" }, | ||
69 | lib = { "lua51-lanes.dll" } | ||
70 | } | ||
71 | } | ||
72 | }, | ||
73 | |||
74 | -- Other platforms use the Makefile | ||
75 | -- | ||
76 | -- LuaRocks defines CFLAGS, LIBFLAG and LUA_INCDIR for 'make rock', | ||
77 | -- defines LIBDIR, LUADIR for 'make install' | ||
78 | -- | ||
79 | -- Ref: <http://www.luarocks.org/en/Paths_and_external_dependencies> | ||
80 | -- | ||
81 | type = "make", | ||
82 | |||
83 | build_target = "rock", | ||
84 | build_variables= { | ||
85 | CFLAGS= "$(CFLAGS) -I$(LUA_INCDIR)", | ||
86 | LIBFLAG= "$(LIBFLAG)", | ||
87 | }, | ||
88 | |||
89 | install_target = "install", | ||
90 | install_variables= { | ||
91 | LUA_LIBDIR= "$(LIBDIR)", | ||
92 | LUA_SHAREDIR= "$(LUADIR)", | ||
93 | } | ||
94 | } | ||
95 | |||
diff --git a/lanes-2.0.2.tgz b/lanes-2.0.2.tgz new file mode 100644 index 0000000..666de3b --- /dev/null +++ b/lanes-2.0.2.tgz | |||
Binary files 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 | |||
17 | REM LuaBinaries and LfW. All prebuilt modules and lua.exe are built | 17 | REM LuaBinaries and LfW. All prebuilt modules and lua.exe are built |
18 | REM with it. | 18 | REM with it. |
19 | REM | 19 | REM |
20 | set VSINSTALLDIR=C:\Program Files\Microsoft Visual Studio 8 | 20 | set VSINSTALLDIR=%ProgramFiles%\Microsoft Visual Studio 8 |
21 | if not exist "%VSINSTALLDIR%\VC\vcvarsall.bat" goto TRY_VC9 | 21 | if not exist "%VSINSTALLDIR%\VC\vcvarsall.bat" goto TRY_VC9 |
22 | 22 | ||
23 | REM Win32 headers must be separately downloaded for VC++2005 | 23 | REM Win32 headers must be separately downloaded for VC++2005 |
24 | REM (VC++2008 SP1 carries an SDK with it) | 24 | REM (VC++2008 SP1 carries an SDK with it) |
25 | REM | 25 | REM |
26 | set _SDK=C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\SetEnv.cmd | 26 | set _SDK=%ProgramFiles%\Microsoft Platform SDK for Windows Server 2003 R2\SetEnv.cmd |
27 | if not exist "%_SDK%" goto ERR_NOSDK | 27 | if not exist "%_SDK%" goto ERR_NOSDK |
28 | call "%_SDK%" | 28 | call "%_SDK%" |
29 | goto FOUND_VC | 29 | goto FOUND_VC |
30 | 30 | ||
31 | :TRY_VC9 | 31 | :TRY_VC9 |
32 | set VSINSTALLDIR=C:\Program Files\Microsoft Visual Studio 9.0 | 32 | set VSINSTALLDIR=%ProgramFiles%\Microsoft Visual Studio 9.0 |
33 | if not exist "%VSINSTALLDIR%\VC\vcvarsall.bat" goto ERR_NOVC | 33 | if not exist "%VSINSTALLDIR%\VC\vcvarsall.bat" goto ERR_NOVC |
34 | 34 | ||
35 | echo. | 35 | echo. |
@@ -54,7 +54,7 @@ call "%VSINSTALLDIR%\VC\vcvarsall.bat" | |||
54 | 54 | ||
55 | REM 'timeit.exe' is part of the MS Server Res Kit Tools (needed for "make perftest") | 55 | REM 'timeit.exe' is part of the MS Server Res Kit Tools (needed for "make perftest") |
56 | REM | 56 | REM |
57 | set _RESKIT=C:\Program Files\Windows Resource Kits\Tools\ | 57 | set _RESKIT=%ProgramFiles%\Windows Resource Kits\Tools\ |
58 | if not exist "%_RESKIT%\timeit.exe" goto WARN_NOTIMEIT | 58 | if not exist "%_RESKIT%\timeit.exe" goto WARN_NOTIMEIT |
59 | PATH=%PATH%;%_RESKIT% | 59 | PATH=%PATH%;%_RESKIT% |
60 | goto EXIT | 60 | 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 @@ | |||
11 | --[[ | 11 | --[[ |
12 | =============================================================================== | 12 | =============================================================================== |
13 | 13 | ||
14 | Copyright (C) 2008 Asko Kauppi <akauppi@gmail.com> | 14 | Copyright (C) 2008-10 Asko Kauppi <akauppi@gmail.com> |
15 | 15 | ||
16 | Permission is hereby granted, free of charge, to any person obtaining a copy | 16 | Permission is hereby granted, free of charge, to any person obtaining a copy |
17 | of this software and associated documentation files (the "Software"), to deal | 17 | of this software and associated documentation files (the "Software"), to deal |
@@ -135,7 +135,7 @@ function send( ud, key, ... ) | |||
135 | local m= limits[key] | 135 | local m= limits[key] |
136 | 136 | ||
137 | if m and len+n > m then | 137 | if m and len+n > m then |
138 | return false -- would exceed the limit; try again later | 138 | return false -- would exceed the limit; try again later |
139 | end | 139 | end |
140 | 140 | ||
141 | for i=1,n do | 141 | 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 @@ | |||
4 | * Multithreading in Lua. | 4 | * Multithreading in Lua. |
5 | * | 5 | * |
6 | * History: | 6 | * History: |
7 | * 3-Jan-11 (2.0.10): linda_send bugfix, was waiting on the wrong signal | ||
8 | * 3-Dec-10 (2.0.9): Added support to generate a lane from a string | ||
9 | * 2-Dec-10 (2.0.8): Fix LuaJIT2 incompatibility (no 'tostring' hijack anymore) | ||
10 | * ???????? (2.0.7): Fixed 'memory leak' in some situations where a free running | ||
11 | * lane is collected before application shutdown | ||
12 | * 24-Aug-10 (2.0.6): Mem fixes, argument checking (lua_toLinda result), thread name | ||
13 | * 24-Jun-09 (2.0.4): Made friendly to already multithreaded host apps. | ||
7 | * 20-Oct-08 (2.0.2): Added closing of free-running threads, but it does | 14 | * 20-Oct-08 (2.0.2): Added closing of free-running threads, but it does |
8 | * not seem to eliminate the occasional segfaults at process | 15 | * not seem to eliminate the occasional segfaults at process |
9 | * exit. | 16 | * exit. |
@@ -13,10 +20,9 @@ | |||
13 | * 18-Sep-06 AKa: Started the module. | 20 | * 18-Sep-06 AKa: Started the module. |
14 | * | 21 | * |
15 | * Platforms (tested internally): | 22 | * Platforms (tested internally): |
16 | * OS X (10.5.4 PowerPC/Intel) | 23 | * OS X (10.5.7 PowerPC/Intel) |
17 | * Linux x86 (Ubuntu 8.04) | 24 | * Linux x86 (Ubuntu 8.04) |
18 | * Win32 (Windows XP Home SP2, Visual C++ 2005/2008 Express) | 25 | * Win32 (Windows XP Home SP2, Visual C++ 2005/2008 Express) |
19 | * PocketPC (TBD) | ||
20 | * | 26 | * |
21 | * Platforms (tested externally): | 27 | * Platforms (tested externally): |
22 | * Win32 (MSYS) by Ross Berteig. | 28 | * Win32 (MSYS) by Ross Berteig. |
@@ -54,15 +60,16 @@ | |||
54 | * | 60 | * |
55 | * To-do: | 61 | * To-do: |
56 | * | 62 | * |
63 | * Make waiting threads cancelable. | ||
57 | * ... | 64 | * ... |
58 | */ | 65 | */ |
59 | 66 | ||
60 | const char *VERSION= "2.0.3"; | 67 | const char *VERSION= "2.0.10"; |
61 | 68 | ||
62 | /* | 69 | /* |
63 | =============================================================================== | 70 | =============================================================================== |
64 | 71 | ||
65 | Copyright (C) 2007-08 Asko Kauppi <akauppi@gmail.com> | 72 | Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> |
66 | 73 | ||
67 | Permission is hereby granted, free of charge, to any person obtaining a copy | 74 | Permission is hereby granted, free of charge, to any person obtaining a copy |
68 | of this software and associated documentation files (the "Software"), to deal | 75 | of this software and associated documentation files (the "Software"), to deal |
@@ -84,10 +91,11 @@ THE SOFTWARE. | |||
84 | 91 | ||
85 | =============================================================================== | 92 | =============================================================================== |
86 | */ | 93 | */ |
94 | |||
87 | #include <string.h> | 95 | #include <string.h> |
88 | #include <stdio.h> | 96 | #include <stdio.h> |
89 | #include <ctype.h> | ||
90 | #include <stdlib.h> | 97 | #include <stdlib.h> |
98 | #include <ctype.h> | ||
91 | 99 | ||
92 | #include "lua.h" | 100 | #include "lua.h" |
93 | #include "lauxlib.h" | 101 | #include "lauxlib.h" |
@@ -127,7 +135,59 @@ THE SOFTWARE. | |||
127 | static char keeper_chunk[]= | 135 | static char keeper_chunk[]= |
128 | #include "keeper.lch" | 136 | #include "keeper.lch" |
129 | 137 | ||
130 | struct s_lane; | 138 | // NOTE: values to be changed by either thread, during execution, without |
139 | // locking, are marked "volatile" | ||
140 | // | ||
141 | struct s_lane { | ||
142 | THREAD_T thread; | ||
143 | // | ||
144 | // M: sub-thread OS thread | ||
145 | // S: not used | ||
146 | |||
147 | char threadName[64]; //Optional, for debugging and such. owerflowable by a strcpy. | ||
148 | |||
149 | lua_State *L; | ||
150 | // | ||
151 | // M: prepares the state, and reads results | ||
152 | // S: while S is running, M must keep out of modifying the state | ||
153 | |||
154 | volatile enum e_status status; | ||
155 | // | ||
156 | // M: sets to PENDING (before launching) | ||
157 | // S: updates -> RUNNING/WAITING -> DONE/ERROR_ST/CANCELLED | ||
158 | |||
159 | volatile bool_t cancel_request; | ||
160 | // | ||
161 | // M: sets to FALSE, flags TRUE for cancel request | ||
162 | // S: reads to see if cancel is requested | ||
163 | |||
164 | #if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) | ||
165 | SIGNAL_T done_signal_; | ||
166 | // | ||
167 | // M: Waited upon at lane ending (if Posix with no PTHREAD_TIMEDJOIN) | ||
168 | // S: sets the signal once cancellation is noticed (avoids a kill) | ||
169 | |||
170 | MUTEX_T done_lock_; | ||
171 | // | ||
172 | // Lock required by 'done_signal' condition variable, protecting | ||
173 | // lane status changes to DONE/ERROR_ST/CANCELLED. | ||
174 | #endif | ||
175 | |||
176 | volatile enum { | ||
177 | NORMAL, // normal master side state | ||
178 | KILLED // issued an OS kill | ||
179 | } mstatus; | ||
180 | // | ||
181 | // M: sets to NORMAL, if issued a kill changes to KILLED | ||
182 | // S: not used | ||
183 | |||
184 | struct s_lane * volatile selfdestruct_next; | ||
185 | // | ||
186 | // M: sets to non-NULL if facing lane handle '__gc' cycle but the lane | ||
187 | // is still running | ||
188 | // S: cleans up after itself if non-NULL at lane exit | ||
189 | }; | ||
190 | |||
131 | static bool_t cancel_test( lua_State *L ); | 191 | static bool_t cancel_test( lua_State *L ); |
132 | static void cancel_error( lua_State *L ); | 192 | static void cancel_error( lua_State *L ); |
133 | 193 | ||
@@ -360,10 +420,11 @@ int keeper_call( lua_State* K, const char *func_name, | |||
360 | int Ktos= lua_gettop(K); | 420 | int Ktos= lua_gettop(K); |
361 | int retvals; | 421 | int retvals; |
362 | 422 | ||
423 | STACK_GROW( K, 2 ); | ||
424 | |||
363 | lua_getglobal( K, func_name ); | 425 | lua_getglobal( K, func_name ); |
364 | ASSERT_L( lua_isfunction(K,-1) ); | 426 | ASSERT_L( lua_isfunction(K,-1) ); |
365 | 427 | ||
366 | STACK_GROW( K, 1 ); | ||
367 | lua_pushlightuserdata( K, linda ); | 428 | lua_pushlightuserdata( K, linda ); |
368 | 429 | ||
369 | luaG_inter_copy( L,K, args ); // L->K | 430 | luaG_inter_copy( L,K, args ); // L->K |
@@ -408,6 +469,8 @@ LUAG_FUNC( linda_send ) { | |||
408 | struct s_Keeper *K; | 469 | struct s_Keeper *K; |
409 | time_d timeout= -1.0; | 470 | time_d timeout= -1.0; |
410 | uint_t key_i= 2; // index of first key, if timeout not there | 471 | uint_t key_i= 2; // index of first key, if timeout not there |
472 | |||
473 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | ||
411 | 474 | ||
412 | if (lua_isnumber(L,2)) { | 475 | if (lua_isnumber(L,2)) { |
413 | timeout= SIGNAL_TIMEOUT_PREPARE( lua_tonumber(L,2) ); | 476 | timeout= SIGNAL_TIMEOUT_PREPARE( lua_tonumber(L,2) ); |
@@ -449,10 +512,36 @@ STACK_MID(KL,0) | |||
449 | cancel= cancel_test( L ); // testing here causes no delays | 512 | cancel= cancel_test( L ); // testing here causes no delays |
450 | if (cancel) break; | 513 | if (cancel) break; |
451 | 514 | ||
515 | // Bugfix by Benoit Germain Dec-2009: change status of lane to "waiting" | ||
516 | // | ||
517 | #if 1 | ||
518 | { | ||
519 | struct s_lane *s; | ||
520 | enum e_status prev_status = ERROR_ST; // prevent 'might be used uninitialized' warnings | ||
521 | STACK_GROW(L,1); | ||
522 | |||
523 | STACK_CHECK(L) | ||
524 | lua_pushlightuserdata( L, CANCEL_TEST_KEY ); | ||
525 | lua_rawget( L, LUA_REGISTRYINDEX ); | ||
526 | s= lua_touserdata( L, -1 ); // lightuserdata (true 's_lane' pointer) / nil | ||
527 | lua_pop(L,1); | ||
528 | STACK_END(L,0) | ||
529 | if (s) { | ||
530 | prev_status = s->status; | ||
531 | s->status = WAITING; | ||
532 | } | ||
533 | if (!SIGNAL_WAIT( &linda->read_happened, &K->lock_, timeout )) { | ||
534 | if (s) { s->status = prev_status; } | ||
535 | break; | ||
536 | } | ||
537 | if (s) s->status = prev_status; | ||
538 | } | ||
539 | #else | ||
452 | // K lock will be released for the duration of wait and re-acquired | 540 | // K lock will be released for the duration of wait and re-acquired |
453 | // | 541 | // |
454 | if (!SIGNAL_WAIT( &linda->read_happened, &K->lock_, timeout )) | 542 | if (!SIGNAL_WAIT( &linda->read_happened, &K->lock_, timeout )) |
455 | break; // timeout | 543 | break; // timeout |
544 | #endif | ||
456 | } | 545 | } |
457 | } | 546 | } |
458 | STACK_END(KL,0) | 547 | STACK_END(KL,0) |
@@ -483,6 +572,8 @@ LUAG_FUNC( linda_receive ) { | |||
483 | time_d timeout= -1.0; | 572 | time_d timeout= -1.0; |
484 | uint_t key_i= 2; | 573 | uint_t key_i= 2; |
485 | 574 | ||
575 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | ||
576 | |||
486 | if (lua_isnumber(L,2)) { | 577 | if (lua_isnumber(L,2)) { |
487 | timeout= SIGNAL_TIMEOUT_PREPARE( lua_tonumber(L,2) ); | 578 | timeout= SIGNAL_TIMEOUT_PREPARE( lua_tonumber(L,2) ); |
488 | key_i++; | 579 | key_i++; |
@@ -509,10 +600,36 @@ LUAG_FUNC( linda_receive ) { | |||
509 | cancel= cancel_test( L ); // testing here causes no delays | 600 | cancel= cancel_test( L ); // testing here causes no delays |
510 | if (cancel) break; | 601 | if (cancel) break; |
511 | 602 | ||
603 | // Bugfix by Benoit Germain Dec-2009: change status of lane to "waiting" | ||
604 | // | ||
605 | #if 1 | ||
606 | { | ||
607 | struct s_lane *s; | ||
608 | enum e_status prev_status = ERROR_ST; // prevent 'might be used uninitialized' warnings | ||
609 | STACK_GROW(L,1); | ||
610 | |||
611 | STACK_CHECK(L) | ||
612 | lua_pushlightuserdata( L, CANCEL_TEST_KEY ); | ||
613 | lua_rawget( L, LUA_REGISTRYINDEX ); | ||
614 | s= lua_touserdata( L, -1 ); // lightuserdata (true 's_lane' pointer) / nil | ||
615 | lua_pop(L,1); | ||
616 | STACK_END(L,0) | ||
617 | if (s) { | ||
618 | prev_status = s->status; | ||
619 | s->status = WAITING; | ||
620 | } | ||
621 | if (!SIGNAL_WAIT( &linda->write_happened, &K->lock_, timeout )) { | ||
622 | if (s) { s->status = prev_status; } | ||
623 | break; | ||
624 | } | ||
625 | if (s) s->status = prev_status; | ||
626 | } | ||
627 | #else | ||
512 | // Release the K lock for the duration of wait, and re-acquire | 628 | // Release the K lock for the duration of wait, and re-acquire |
513 | // | 629 | // |
514 | if (!SIGNAL_WAIT( &linda->write_happened, &K->lock_, timeout )) | 630 | if (!SIGNAL_WAIT( &linda->write_happened, &K->lock_, timeout )) |
515 | break; | 631 | break; |
632 | #endif | ||
516 | } | 633 | } |
517 | } | 634 | } |
518 | } | 635 | } |
@@ -535,8 +652,11 @@ LUAG_FUNC( linda_receive ) { | |||
535 | LUAG_FUNC( linda_set ) { | 652 | LUAG_FUNC( linda_set ) { |
536 | struct s_Linda *linda= lua_toLinda( L, 1 ); | 653 | struct s_Linda *linda= lua_toLinda( L, 1 ); |
537 | bool_t has_value= !lua_isnil(L,3); | 654 | bool_t has_value= !lua_isnil(L,3); |
655 | struct s_Keeper *K; | ||
538 | 656 | ||
539 | struct s_Keeper *K= keeper_acquire( linda ); | 657 | luaL_argcheck( L, linda, 1, "expected a linda object!"); |
658 | |||
659 | K= keeper_acquire( linda ); | ||
540 | { | 660 | { |
541 | int pushed= keeper_call( K->L, "set", L, linda, 2 ); | 661 | int pushed= keeper_call( K->L, "set", L, linda, 2 ); |
542 | ASSERT_L( pushed==0 ); | 662 | ASSERT_L( pushed==0 ); |
@@ -561,8 +681,11 @@ LUAG_FUNC( linda_set ) { | |||
561 | LUAG_FUNC( linda_get ) { | 681 | LUAG_FUNC( linda_get ) { |
562 | struct s_Linda *linda= lua_toLinda( L, 1 ); | 682 | struct s_Linda *linda= lua_toLinda( L, 1 ); |
563 | int pushed; | 683 | int pushed; |
684 | struct s_Keeper *K; | ||
564 | 685 | ||
565 | struct s_Keeper *K= keeper_acquire( linda ); | 686 | luaL_argcheck( L, linda, 1, "expected a linda object!"); |
687 | |||
688 | K= keeper_acquire( linda ); | ||
566 | { | 689 | { |
567 | pushed= keeper_call( K->L, "get", L, linda, 2 ); | 690 | pushed= keeper_call( K->L, "get", L, linda, 2 ); |
568 | ASSERT_L( pushed==0 || pushed==1 ); | 691 | ASSERT_L( pushed==0 || pushed==1 ); |
@@ -580,8 +703,11 @@ LUAG_FUNC( linda_get ) { | |||
580 | */ | 703 | */ |
581 | LUAG_FUNC( linda_limit ) { | 704 | LUAG_FUNC( linda_limit ) { |
582 | struct s_Linda *linda= lua_toLinda( L, 1 ); | 705 | struct s_Linda *linda= lua_toLinda( L, 1 ); |
706 | struct s_Keeper *K; | ||
707 | |||
708 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | ||
583 | 709 | ||
584 | struct s_Keeper *K= keeper_acquire( linda ); | 710 | K= keeper_acquire( linda ); |
585 | { | 711 | { |
586 | int pushed= keeper_call( K->L, "limit", L, linda, 2 ); | 712 | int pushed= keeper_call( K->L, "limit", L, linda, 2 ); |
587 | ASSERT_L( pushed==0 ); | 713 | ASSERT_L( pushed==0 ); |
@@ -604,6 +730,7 @@ LUAG_FUNC( linda_limit ) { | |||
604 | */ | 730 | */ |
605 | LUAG_FUNC( linda_deep ) { | 731 | LUAG_FUNC( linda_deep ) { |
606 | struct s_Linda *linda= lua_toLinda( L, 1 ); | 732 | struct s_Linda *linda= lua_toLinda( L, 1 ); |
733 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | ||
607 | lua_pushlightuserdata( L, linda ); // just the address | 734 | lua_pushlightuserdata( L, linda ); // just the address |
608 | return 1; | 735 | return 1; |
609 | } | 736 | } |
@@ -761,13 +888,13 @@ static int run_finalizers( lua_State *L, int lua_rc ) | |||
761 | return 0; // no finalizers | 888 | return 0; // no finalizers |
762 | 889 | ||
763 | tbl_index= lua_gettop(L); | 890 | tbl_index= lua_gettop(L); |
764 | error_index= (lua_rc!=0) ? tbl_index-1 : 0; // absolute indices | 891 | error_index= (lua_rc!=0) ? tbl_index-2 : 0; // absolute indices |
765 | 892 | ||
766 | STACK_GROW(L,4); | 893 | STACK_GROW(L,4); |
767 | 894 | ||
768 | // [-1]: { func [, ...] } | 895 | // [-1]: { func [, ...] } |
769 | // | 896 | // |
770 | for( n= lua_objlen(L,-1); n>0; n-- ) { | 897 | for( n= (unsigned int)lua_objlen(L,-1); n>0; n-- ) { |
771 | unsigned args= 0; | 898 | unsigned args= 0; |
772 | lua_pushinteger( L,n ); | 899 | lua_pushinteger( L,n ); |
773 | lua_gettable( L, -2 ); | 900 | lua_gettable( L, -2 ); |
@@ -805,57 +932,6 @@ static int run_finalizers( lua_State *L, int lua_rc ) | |||
805 | /*---=== Threads ===--- | 932 | /*---=== Threads ===--- |
806 | */ | 933 | */ |
807 | 934 | ||
808 | // NOTE: values to be changed by either thread, during execution, without | ||
809 | // locking, are marked "volatile" | ||
810 | // | ||
811 | struct s_lane { | ||
812 | THREAD_T thread; | ||
813 | // | ||
814 | // M: sub-thread OS thread | ||
815 | // S: not used | ||
816 | |||
817 | lua_State *L; | ||
818 | // | ||
819 | // M: prepares the state, and reads results | ||
820 | // S: while S is running, M must keep out of modifying the state | ||
821 | |||
822 | volatile enum e_status status; | ||
823 | // | ||
824 | // M: sets to PENDING (before launching) | ||
825 | // S: updates -> RUNNING/WAITING -> DONE/ERROR_ST/CANCELLED | ||
826 | |||
827 | volatile bool_t cancel_request; | ||
828 | // | ||
829 | // M: sets to FALSE, flags TRUE for cancel request | ||
830 | // S: reads to see if cancel is requested | ||
831 | |||
832 | #if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) | ||
833 | SIGNAL_T done_signal_; | ||
834 | // | ||
835 | // M: Waited upon at lane ending (if Posix with no PTHREAD_TIMEDJOIN) | ||
836 | // S: sets the signal once cancellation is noticed (avoids a kill) | ||
837 | |||
838 | MUTEX_T done_lock_; | ||
839 | // | ||
840 | // Lock required by 'done_signal' condition variable, protecting | ||
841 | // lane status changes to DONE/ERROR_ST/CANCELLED. | ||
842 | #endif | ||
843 | |||
844 | volatile enum { | ||
845 | NORMAL, // normal master side state | ||
846 | KILLED // issued an OS kill | ||
847 | } mstatus; | ||
848 | // | ||
849 | // M: sets to NORMAL, if issued a kill changes to KILLED | ||
850 | // S: not used | ||
851 | |||
852 | struct s_lane * volatile selfdestruct_next; | ||
853 | // | ||
854 | // M: sets to non-NULL if facing lane handle '__gc' cycle but the lane | ||
855 | // is still running | ||
856 | // S: cleans up after itself if non-NULL at lane exit | ||
857 | }; | ||
858 | |||
859 | static MUTEX_T selfdestruct_cs; | 935 | static MUTEX_T selfdestruct_cs; |
860 | // | 936 | // |
861 | // Protects modifying the selfdestruct chain | 937 | // Protects modifying the selfdestruct chain |
@@ -985,11 +1061,13 @@ static void selfdestruct_atexit( void ) { | |||
985 | // Linux (at least 64-bit): CAUSES A SEGFAULT IF THIS BLOCK IS ENABLED | 1061 | // Linux (at least 64-bit): CAUSES A SEGFAULT IF THIS BLOCK IS ENABLED |
986 | // and works without the block (so let's leave those lanes running) | 1062 | // and works without the block (so let's leave those lanes running) |
987 | // | 1063 | // |
988 | #if 1 | 1064 | //we want to free memory and such when we exit. |
1065 | #if 0 | ||
989 | // 2.0.2: at least timer lane is still here | 1066 | // 2.0.2: at least timer lane is still here |
990 | // | 1067 | // |
991 | //fprintf( stderr, "Left %d lane(s) with cancel request at process end.\n", n ); | 1068 | DEBUGEXEC(fprintf( stderr, "Left %d lane(s) with cancel request at process end.\n", n )); |
992 | #else | 1069 | #else |
1070 | n=0; | ||
993 | MUTEX_LOCK( &selfdestruct_cs ); | 1071 | MUTEX_LOCK( &selfdestruct_cs ); |
994 | { | 1072 | { |
995 | struct s_lane *s= selfdestruct_first; | 1073 | struct s_lane *s= selfdestruct_first; |
@@ -998,6 +1076,8 @@ static void selfdestruct_atexit( void ) { | |||
998 | s->selfdestruct_next= NULL; // detach from selfdestruct chain | 1076 | s->selfdestruct_next= NULL; // detach from selfdestruct chain |
999 | 1077 | ||
1000 | THREAD_KILL( &s->thread ); | 1078 | THREAD_KILL( &s->thread ); |
1079 | lua_close(s->L); | ||
1080 | free(s); | ||
1001 | s= next_s; | 1081 | s= next_s; |
1002 | n++; | 1082 | n++; |
1003 | } | 1083 | } |
@@ -1005,9 +1085,16 @@ static void selfdestruct_atexit( void ) { | |||
1005 | } | 1085 | } |
1006 | MUTEX_UNLOCK( &selfdestruct_cs ); | 1086 | MUTEX_UNLOCK( &selfdestruct_cs ); |
1007 | 1087 | ||
1008 | fprintf( stderr, "Killed %d lane(s) at process end.\n", n ); | 1088 | DEBUGEXEC(fprintf( stderr, "Killed %d lane(s) at process end.\n", n )); |
1009 | #endif | 1089 | #endif |
1010 | } | 1090 | } |
1091 | { | ||
1092 | int i; | ||
1093 | for(i=0;i<KEEPER_STATES_N;i++){ | ||
1094 | lua_close(keeper[i].L); | ||
1095 | keeper[i].L = 0; | ||
1096 | } | ||
1097 | } | ||
1011 | } | 1098 | } |
1012 | 1099 | ||
1013 | 1100 | ||
@@ -1153,6 +1240,38 @@ static int lane_error( lua_State *L ) { | |||
1153 | } | 1240 | } |
1154 | #endif | 1241 | #endif |
1155 | 1242 | ||
1243 | #if defined PLATFORM_WIN32 && !defined __GNUC__ | ||
1244 | //see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx | ||
1245 | #define MS_VC_EXCEPTION 0x406D1388 | ||
1246 | #pragma pack(push,8) | ||
1247 | typedef struct tagTHREADNAME_INFO | ||
1248 | { | ||
1249 | DWORD dwType; // Must be 0x1000. | ||
1250 | LPCSTR szName; // Pointer to name (in user addr space). | ||
1251 | DWORD dwThreadID; // Thread ID (-1=caller thread). | ||
1252 | DWORD dwFlags; // Reserved for future use, must be zero. | ||
1253 | } THREADNAME_INFO; | ||
1254 | #pragma pack(pop) | ||
1255 | |||
1256 | void SetThreadName( DWORD dwThreadID, char* threadName) | ||
1257 | { | ||
1258 | THREADNAME_INFO info; | ||
1259 | Sleep(10); | ||
1260 | info.dwType = 0x1000; | ||
1261 | info.szName = threadName; | ||
1262 | info.dwThreadID = dwThreadID; | ||
1263 | info.dwFlags = 0; | ||
1264 | |||
1265 | __try | ||
1266 | { | ||
1267 | RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); | ||
1268 | } | ||
1269 | __except(EXCEPTION_EXECUTE_HANDLER) | ||
1270 | { | ||
1271 | } | ||
1272 | } | ||
1273 | #endif | ||
1274 | |||
1156 | 1275 | ||
1157 | //--- | 1276 | //--- |
1158 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 1277 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) |
@@ -1165,7 +1284,12 @@ static int lane_error( lua_State *L ) { | |||
1165 | int rc, rc2; | 1284 | int rc, rc2; |
1166 | lua_State *L= s->L; | 1285 | lua_State *L= s->L; |
1167 | 1286 | ||
1168 | s->status= RUNNING; // PENDING -> RUNNING | 1287 | |
1288 | #if defined PLATFORM_WIN32 && !defined __GNUC__ | ||
1289 | SetThreadName(-1, s->threadName); | ||
1290 | #endif | ||
1291 | |||
1292 | s->status= RUNNING; // PENDING -> RUNNING | ||
1169 | 1293 | ||
1170 | // Tie "set_finalizer()" to the state | 1294 | // Tie "set_finalizer()" to the state |
1171 | // | 1295 | // |
@@ -1243,7 +1367,7 @@ static int lane_error( lua_State *L ) { | |||
1243 | // We're a free-running thread and no-one's there to clean us up. | 1367 | // We're a free-running thread and no-one's there to clean us up. |
1244 | // | 1368 | // |
1245 | lua_close( s->L ); | 1369 | lua_close( s->L ); |
1246 | L= 0; | 1370 | s->L = L = 0; |
1247 | 1371 | ||
1248 | #if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) | 1372 | #if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) |
1249 | SIGNAL_FREE( &s->done_signal_ ); | 1373 | SIGNAL_FREE( &s->done_signal_ ); |
@@ -1290,121 +1414,144 @@ static int lane_error( lua_State *L ) { | |||
1290 | // | 1414 | // |
1291 | LUAG_FUNC( thread_new ) | 1415 | LUAG_FUNC( thread_new ) |
1292 | { | 1416 | { |
1293 | lua_State *L2; | 1417 | lua_State *L2; |
1294 | struct s_lane *s; | 1418 | struct s_lane *s; |
1295 | struct s_lane **ud; | 1419 | struct s_lane **ud; |
1296 | 1420 | const char *threadName = 0; | |
1297 | const char *libs= lua_tostring( L, 2 ); | 1421 | |
1298 | uint_t cs= luaG_optunsigned( L, 3,0); | 1422 | const char *libs= lua_tostring( L, 2 ); |
1299 | int prio= luaL_optinteger( L, 4,0); | 1423 | uint_t cs= luaG_optunsigned( L, 3,0); |
1300 | uint_t glob= luaG_isany(L,5) ? 5:0; | 1424 | int prio= (int)luaL_optinteger( L, 4,0); |
1301 | 1425 | uint_t glob= luaG_isany(L,5) ? 5:0; | |
1302 | #define FIXED_ARGS (5) | 1426 | |
1303 | uint_t args= lua_gettop(L) - FIXED_ARGS; | 1427 | #define FIXED_ARGS (5) |
1304 | 1428 | uint_t args= lua_gettop(L) - FIXED_ARGS; | |
1305 | if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) { | 1429 | |
1306 | luaL_error( L, "Priority out of range: %d..+%d (%d)", | 1430 | if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) |
1307 | THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio ); | 1431 | { |
1308 | } | 1432 | luaL_error( L, "Priority out of range: %d..+%d (%d)", |
1309 | 1433 | THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio ); | |
1310 | /* --- Create and prepare the sub state --- */ | 1434 | } |
1311 | 1435 | ||
1312 | L2 = luaL_newstate(); // uses standard 'realloc()'-based allocator, | 1436 | /* --- Create and prepare the sub state --- */ |
1313 | // sets the panic callback | 1437 | |
1314 | 1438 | L2 = luaL_newstate(); // uses standard 'realloc()'-based allocator, | |
1315 | if (!L2) luaL_error( L, "'luaL_newstate()' failed; out of memory" ); | 1439 | // sets the panic callback |
1316 | 1440 | ||
1317 | STACK_GROW( L,2 ); | 1441 | if (!L2) luaL_error( L, "'luaL_newstate()' failed; out of memory" ); |
1318 | 1442 | ||
1319 | // Setting the globals table (needs to be done before loading stdlibs, | 1443 | STACK_GROW( L,2 ); |
1320 | // and the lane function) | 1444 | |
1321 | // | 1445 | // Setting the globals table (needs to be done before loading stdlibs, |
1322 | if (glob!=0) { | 1446 | // and the lane function) |
1323 | STACK_CHECK(L) | 1447 | // |
1324 | if (!lua_istable(L,glob)) | 1448 | if (glob!=0) |
1325 | luaL_error( L, "Expected table, got %s", luaG_typename(L,glob) ); | 1449 | { |
1326 | 1450 | STACK_CHECK(L) | |
1327 | lua_pushvalue( L, glob ); | 1451 | if (!lua_istable(L,glob)) |
1328 | luaG_inter_move( L,L2, 1 ); // moves the table to L2 | 1452 | luaL_error( L, "Expected table, got %s", luaG_typename(L,glob) ); |
1329 | 1453 | ||
1330 | // L2 [-1]: table of globals | 1454 | lua_pushvalue( L, glob ); |
1331 | 1455 | lua_pushstring( L, "threadName"); | |
1332 | // "You can change the global environment of a Lua thread using lua_replace" | 1456 | lua_gettable( L, -2); |
1333 | // (refman-5.0.pdf p. 30) | 1457 | threadName = lua_tostring( L, -1); |
1334 | // | 1458 | lua_pop( L, 1); |
1335 | lua_replace( L2, LUA_GLOBALSINDEX ); | 1459 | luaG_inter_move( L,L2, 1 ); // moves the table to L2 |
1336 | STACK_END(L,0) | 1460 | |
1337 | } | 1461 | // L2 [-1]: table of globals |
1338 | 1462 | ||
1339 | // Selected libraries | 1463 | // "You can change the global environment of a Lua thread using lua_replace" |
1340 | // | 1464 | // (refman-5.0.pdf p. 30) |
1341 | if (libs) { | 1465 | // |
1342 | const char *err= luaG_openlibs( L2, libs ); | 1466 | lua_replace( L2, LUA_GLOBALSINDEX ); |
1343 | ASSERT_L( !err ); // bad libs should have been noticed by 'lanes.lua' | 1467 | STACK_END(L,0) |
1344 | 1468 | } | |
1345 | serialize_require( L2 ); | 1469 | |
1346 | } | 1470 | // Selected libraries |
1347 | 1471 | // | |
1348 | // Lane main function | 1472 | if (libs) |
1349 | // | 1473 | { |
1350 | STACK_CHECK(L) | 1474 | const char *err= luaG_openlibs( L2, libs ); |
1351 | lua_pushvalue( L, 1 ); | 1475 | ASSERT_L( !err ); // bad libs should have been noticed by 'lanes.lua' |
1352 | luaG_inter_move( L,L2, 1 ); // L->L2 | 1476 | |
1353 | STACK_MID(L,0) | 1477 | serialize_require( L2 ); |
1354 | 1478 | } | |
1355 | ASSERT_L( lua_gettop(L2) == 1 ); | 1479 | |
1356 | ASSERT_L( lua_isfunction(L2,1) ); | 1480 | // Lane main function |
1357 | 1481 | // | |
1358 | // revive arguments | 1482 | STACK_CHECK(L) |
1359 | // | 1483 | if( lua_type(L, 1) == LUA_TFUNCTION) |
1360 | if (args) luaG_inter_copy( L,L2, args ); // L->L2 | 1484 | { |
1361 | STACK_MID(L,0) | 1485 | lua_pushvalue( L, 1 ); |
1362 | 1486 | luaG_inter_move( L,L2, 1 ); // L->L2 | |
1363 | ASSERT_L( (uint_t)lua_gettop(L2) == 1+args ); | 1487 | STACK_MID(L,0) |
1364 | ASSERT_L( lua_isfunction(L2,1) ); | 1488 | } |
1365 | 1489 | else if( lua_type(L, 1) == LUA_TSTRING) | |
1366 | // 's' is allocated from heap, not Lua, since its life span may surpass | 1490 | { |
1367 | // the handle's (if free running thread) | 1491 | // compile the string |
1368 | // | 1492 | if( luaL_loadstring( L2, lua_tostring( L, 1)) != 0) |
1369 | ud= lua_newuserdata( L, sizeof(struct s_lane*) ); | 1493 | { |
1370 | ASSERT_L(ud); | 1494 | luaL_error( L, "error when parsing lane function code"); |
1371 | 1495 | } | |
1372 | s= *ud= malloc( sizeof(struct s_lane) ); | 1496 | } |
1373 | ASSERT_L(s); | 1497 | |
1374 | 1498 | ASSERT_L( lua_gettop(L2) == 1 ); | |
1375 | //memset( s, 0, sizeof(struct s_lane) ); | 1499 | ASSERT_L( lua_isfunction(L2,1) ); |
1376 | s->L= L2; | 1500 | |
1377 | s->status= PENDING; | 1501 | // revive arguments |
1378 | s->cancel_request= FALSE; | 1502 | // |
1503 | if (args) luaG_inter_copy( L,L2, args ); // L->L2 | ||
1504 | STACK_MID(L,0) | ||
1505 | |||
1506 | ASSERT_L( (uint_t)lua_gettop(L2) == 1+args ); | ||
1507 | ASSERT_L( lua_isfunction(L2,1) ); | ||
1508 | |||
1509 | // 's' is allocated from heap, not Lua, since its life span may surpass | ||
1510 | // the handle's (if free running thread) | ||
1511 | // | ||
1512 | ud= lua_newuserdata( L, sizeof(struct s_lane*) ); | ||
1513 | ASSERT_L(ud); | ||
1514 | |||
1515 | s= *ud= malloc( sizeof(struct s_lane) ); | ||
1516 | ASSERT_L(s); | ||
1517 | |||
1518 | //memset( s, 0, sizeof(struct s_lane) ); | ||
1519 | s->L= L2; | ||
1520 | s->status= PENDING; | ||
1521 | s->cancel_request= FALSE; | ||
1522 | |||
1523 | threadName = threadName ? threadName : "<unnamed thread>"; | ||
1524 | strcpy(s->threadName, threadName); | ||
1379 | 1525 | ||
1380 | #if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) | 1526 | #if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) |
1381 | MUTEX_INIT( &s->done_lock_ ); | 1527 | MUTEX_INIT( &s->done_lock_ ); |
1382 | SIGNAL_INIT( &s->done_signal_ ); | 1528 | SIGNAL_INIT( &s->done_signal_ ); |
1383 | #endif | 1529 | #endif |
1384 | s->mstatus= NORMAL; | 1530 | s->mstatus= NORMAL; |
1385 | s->selfdestruct_next= NULL; | 1531 | s->selfdestruct_next= NULL; |
1386 | 1532 | ||
1387 | // Set metatable for the userdata | 1533 | // Set metatable for the userdata |
1388 | // | 1534 | // |
1389 | lua_pushvalue( L, lua_upvalueindex(1) ); | 1535 | lua_pushvalue( L, lua_upvalueindex(1) ); |
1390 | lua_setmetatable( L, -2 ); | 1536 | lua_setmetatable( L, -2 ); |
1391 | STACK_MID(L,1) | 1537 | STACK_MID(L,1) |
1392 | 1538 | ||
1393 | // Place 's' to registry, for 'cancel_test()' (even if 'cs'==0 we still | 1539 | // Place 's' to registry, for 'cancel_test()' (even if 'cs'==0 we still |
1394 | // do cancel tests at pending send/receive). | 1540 | // do cancel tests at pending send/receive). |
1395 | // | 1541 | // |
1396 | lua_pushlightuserdata( L2, CANCEL_TEST_KEY ); | 1542 | lua_pushlightuserdata( L2, CANCEL_TEST_KEY ); |
1397 | lua_pushlightuserdata( L2, s ); | 1543 | lua_pushlightuserdata( L2, s ); |
1398 | lua_rawset( L2, LUA_REGISTRYINDEX ); | 1544 | lua_rawset( L2, LUA_REGISTRYINDEX ); |
1399 | 1545 | ||
1400 | if (cs) { | 1546 | if (cs) |
1401 | lua_sethook( L2, cancel_hook, LUA_MASKCOUNT, cs ); | 1547 | { |
1402 | } | 1548 | lua_sethook( L2, cancel_hook, LUA_MASKCOUNT, cs ); |
1403 | 1549 | } | |
1404 | THREAD_CREATE( &s->thread, lane_main, s, prio ); | 1550 | |
1405 | STACK_END(L,1) | 1551 | THREAD_CREATE( &s->thread, lane_main, s, prio ); |
1406 | 1552 | STACK_END(L,1) | |
1407 | return 1; | 1553 | |
1554 | return 1; | ||
1408 | } | 1555 | } |
1409 | 1556 | ||
1410 | 1557 | ||
@@ -1428,45 +1575,56 @@ STACK_END(L,1) | |||
1428 | // | 1575 | // |
1429 | // Todo: Maybe we should have a clear #define for selecting either behaviour. | 1576 | // Todo: Maybe we should have a clear #define for selecting either behaviour. |
1430 | // | 1577 | // |
1431 | LUAG_FUNC( thread_gc ) { | 1578 | LUAG_FUNC( thread_gc ) |
1432 | struct s_lane *s= lua_toLane(L,1); | 1579 | { |
1433 | 1580 | struct s_lane *s= lua_toLane(L,1); | |
1434 | // We can read 's->status' without locks, but not wait for it | 1581 | |
1435 | // | 1582 | // We can read 's->status' without locks, but not wait for it |
1436 | if (s->status < DONE) { | 1583 | // |
1437 | // | 1584 | if (s->status < DONE) |
1438 | selfdestruct_add(s); | 1585 | { |
1439 | assert( s->selfdestruct_next ); | 1586 | // |
1440 | return 0; | 1587 | selfdestruct_add(s); |
1441 | 1588 | assert( s->selfdestruct_next ); | |
1442 | } else if (s->mstatus==KILLED) { | 1589 | return 0; |
1443 | // Make sure a kill has proceeded, before cleaning up the data structure. | 1590 | |
1444 | // | 1591 | } |
1445 | // If not doing 'THREAD_WAIT()' we should close the Lua state here | 1592 | else if (s->mstatus==KILLED) |
1446 | // (can it be out of order, since we killed the lane abruptly?) | 1593 | { |
1447 | // | 1594 | // Make sure a kill has proceeded, before cleaning up the data structure. |
1595 | // | ||
1596 | // If not doing 'THREAD_WAIT()' we should close the Lua state here | ||
1597 | // (can it be out of order, since we killed the lane abruptly?) | ||
1598 | // | ||
1448 | #if 0 | 1599 | #if 0 |
1449 | lua_close( s->L ); | 1600 | lua_close( s->L ); |
1601 | s->L = 0; | ||
1450 | #else | 1602 | #else |
1451 | fprintf( stderr, "** Joining with a killed thread (needs testing) **" ); | 1603 | DEBUGEXEC(fprintf( stderr, "** Joining with a killed thread (needs testing) **" )); |
1452 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) | 1604 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) |
1453 | THREAD_WAIT( &s->thread, -1 ); | 1605 | THREAD_WAIT( &s->thread, -1 ); |
1454 | #else | 1606 | #else |
1455 | THREAD_WAIT( &s->thread, &s->done_signal_, &s->done_lock_, &s->status, -1 ); | 1607 | THREAD_WAIT( &s->thread, &s->done_signal_, &s->done_lock_, &s->status, -1 ); |
1456 | #endif | 1608 | #endif |
1457 | fprintf( stderr, "** Joined ok **" ); | 1609 | DEBUGEXEC(fprintf( stderr, "** Joined ok **" )); |
1458 | #endif | 1610 | #endif |
1459 | } | 1611 | } |
1460 | 1612 | else if( s->L) | |
1461 | // Clean up after a (finished) thread | 1613 | { |
1462 | // | 1614 | lua_close( s->L); |
1615 | s->L = 0; | ||
1616 | } | ||
1617 | |||
1618 | // Clean up after a (finished) thread | ||
1619 | // | ||
1463 | #if (! ((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN))) | 1620 | #if (! ((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN))) |
1464 | SIGNAL_FREE( &s->done_signal_ ); | 1621 | SIGNAL_FREE( &s->done_signal_ ); |
1465 | MUTEX_FREE( &s->done_lock_ ); | 1622 | MUTEX_FREE( &s->done_lock_ ); |
1466 | free(s); | ||
1467 | #endif | 1623 | #endif |
1468 | 1624 | ||
1469 | return 0; | 1625 | free(s); |
1626 | |||
1627 | return 0; | ||
1470 | } | 1628 | } |
1471 | 1629 | ||
1472 | 1630 | ||
@@ -1614,10 +1772,11 @@ LUAG_FUNC( thread_join ) | |||
1614 | break; | 1772 | break; |
1615 | 1773 | ||
1616 | default: | 1774 | default: |
1617 | fprintf( stderr, "Status: %d\n", s->status ); | 1775 | DEBUGEXEC(fprintf( stderr, "Status: %d\n", s->status )); |
1618 | ASSERT_L( FALSE ); ret= 0; | 1776 | ASSERT_L( FALSE ); ret= 0; |
1619 | } | 1777 | } |
1620 | lua_close(L2); | 1778 | lua_close(L2); |
1779 | s->L = L2 = 0; | ||
1621 | 1780 | ||
1622 | return ret; | 1781 | return ret; |
1623 | } | 1782 | } |
@@ -1627,48 +1786,6 @@ LUAG_FUNC( thread_join ) | |||
1627 | */ | 1786 | */ |
1628 | 1787 | ||
1629 | /* | 1788 | /* |
1630 | * Push a timer gateway Linda object; only one deep userdata is | ||
1631 | * created for this, each lane will get its own proxy. | ||
1632 | * | ||
1633 | * Note: this needs to be done on the C side; Lua wouldn't be able | ||
1634 | * to even see, when we've been initialized for the very first | ||
1635 | * time (with us, they will be). | ||
1636 | */ | ||
1637 | static | ||
1638 | void push_timer_gateway( lua_State *L ) { | ||
1639 | |||
1640 | /* No need to lock; 'static' is just fine | ||
1641 | */ | ||
1642 | static DEEP_PRELUDE *p; // = NULL | ||
1643 | |||
1644 | STACK_CHECK(L) | ||
1645 | if (!p) { | ||
1646 | // Create the Linda (only on first time) | ||
1647 | // | ||
1648 | // proxy_ud= deep_userdata( idfunc ) | ||
1649 | // | ||
1650 | lua_pushcfunction( L, luaG_deep_userdata ); | ||
1651 | lua_pushcfunction( L, LG_linda_id ); | ||
1652 | lua_call( L, 1 /*args*/, 1 /*retvals*/ ); | ||
1653 | |||
1654 | ASSERT_L( lua_isuserdata(L,-1) ); | ||
1655 | |||
1656 | // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer | ||
1657 | // | ||
1658 | p= * (DEEP_PRELUDE**) lua_touserdata( L, -1 ); | ||
1659 | ASSERT_L(p && p->refcount==1 && p->deep); | ||
1660 | |||
1661 | // [-1]: proxy for accessing the Linda | ||
1662 | |||
1663 | } else { | ||
1664 | /* Push a proxy based on the deep userdata we stored. | ||
1665 | */ | ||
1666 | luaG_push_proxy( L, LG_linda_id, p ); | ||
1667 | } | ||
1668 | STACK_END(L,1) | ||
1669 | } | ||
1670 | |||
1671 | /* | ||
1672 | * secs= now_secs() | 1789 | * secs= now_secs() |
1673 | * | 1790 | * |
1674 | * Returns the current time, as seconds (millisecond resolution). | 1791 | * Returns the current time, as seconds (millisecond resolution). |
@@ -1697,12 +1814,12 @@ LUAG_FUNC( wakeup_conv ) | |||
1697 | // .isdst (daylight saving on/off) | 1814 | // .isdst (daylight saving on/off) |
1698 | 1815 | ||
1699 | STACK_CHECK(L) | 1816 | STACK_CHECK(L) |
1700 | lua_getfield( L, 1, "year" ); year= lua_tointeger(L,-1); lua_pop(L,1); | 1817 | lua_getfield( L, 1, "year" ); year= (int)lua_tointeger(L,-1); lua_pop(L,1); |
1701 | lua_getfield( L, 1, "month" ); month= lua_tointeger(L,-1); lua_pop(L,1); | 1818 | lua_getfield( L, 1, "month" ); month= (int)lua_tointeger(L,-1); lua_pop(L,1); |
1702 | lua_getfield( L, 1, "day" ); day= lua_tointeger(L,-1); lua_pop(L,1); | 1819 | lua_getfield( L, 1, "day" ); day= (int)lua_tointeger(L,-1); lua_pop(L,1); |
1703 | lua_getfield( L, 1, "hour" ); hour= lua_tointeger(L,-1); lua_pop(L,1); | 1820 | lua_getfield( L, 1, "hour" ); hour= (int)lua_tointeger(L,-1); lua_pop(L,1); |
1704 | lua_getfield( L, 1, "min" ); min= lua_tointeger(L,-1); lua_pop(L,1); | 1821 | lua_getfield( L, 1, "min" ); min= (int)lua_tointeger(L,-1); lua_pop(L,1); |
1705 | lua_getfield( L, 1, "sec" ); sec= lua_tointeger(L,-1); lua_pop(L,1); | 1822 | lua_getfield( L, 1, "sec" ); sec= (int)lua_tointeger(L,-1); lua_pop(L,1); |
1706 | 1823 | ||
1707 | // If Lua table has '.isdst' we trust that. If it does not, we'll let | 1824 | // If Lua table has '.isdst' we trust that. If it does not, we'll let |
1708 | // 'mktime' decide on whether the time is within DST or not (value -1). | 1825 | // 'mktime' decide on whether the time is within DST or not (value -1). |
@@ -1744,19 +1861,11 @@ LUAG_FUNC( wakeup_conv ) | |||
1744 | lua_pushinteger( L, val ); \ | 1861 | lua_pushinteger( L, val ); \ |
1745 | lua_setglobal( L, #name ) | 1862 | lua_setglobal( L, #name ) |
1746 | 1863 | ||
1747 | 1864 | /* | |
1748 | int | 1865 | * One-time initializations |
1749 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 1866 | */ |
1750 | __declspec(dllexport) | 1867 | static void init_once_LOCKED( lua_State *L, volatile DEEP_PRELUDE ** timer_deep_ref ) { |
1751 | #endif | ||
1752 | luaopen_lanes( lua_State *L ) { | ||
1753 | const char *err; | 1868 | const char *err; |
1754 | static volatile char been_here; // =0 | ||
1755 | |||
1756 | // One time initializations: | ||
1757 | // | ||
1758 | if (!been_here) { | ||
1759 | been_here= TRUE; | ||
1760 | 1869 | ||
1761 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 1870 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) |
1762 | now_secs(); // initialize 'now_secs()' internal offset | 1871 | now_secs(); // initialize 'now_secs()' internal offset |
@@ -1806,10 +1915,87 @@ __declspec(dllexport) | |||
1806 | #endif | 1915 | #endif |
1807 | #endif | 1916 | #endif |
1808 | err= init_keepers(); | 1917 | err= init_keepers(); |
1809 | if (err) | 1918 | if (err) { |
1810 | luaL_error( L, "Unable to initialize: %s", err ); | 1919 | luaL_error( L, "Unable to initialize: %s", err ); |
1811 | } | 1920 | } |
1812 | 1921 | ||
1922 | // Initialize 'timer_deep'; a common Linda object shared by all states | ||
1923 | // | ||
1924 | ASSERT_L( timer_deep_ref && (!(*timer_deep_ref)) ); | ||
1925 | |||
1926 | STACK_CHECK(L) | ||
1927 | { | ||
1928 | // proxy_ud= deep_userdata( idfunc ) | ||
1929 | // | ||
1930 | lua_pushcfunction( L, luaG_deep_userdata ); | ||
1931 | lua_pushcfunction( L, LG_linda_id ); | ||
1932 | lua_call( L, 1 /*args*/, 1 /*retvals*/ ); | ||
1933 | |||
1934 | ASSERT_L( lua_isuserdata(L,-1) ); | ||
1935 | |||
1936 | // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer | ||
1937 | // | ||
1938 | *timer_deep_ref= * (DEEP_PRELUDE**) lua_touserdata( L, -1 ); | ||
1939 | ASSERT_L( (*timer_deep_ref) && (*timer_deep_ref)->refcount==1 && (*timer_deep_ref)->deep ); | ||
1940 | |||
1941 | lua_pop(L,1); // we don't need the proxy | ||
1942 | } | ||
1943 | STACK_END(L,0) | ||
1944 | } | ||
1945 | |||
1946 | int | ||
1947 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | ||
1948 | __declspec(dllexport) | ||
1949 | #endif | ||
1950 | luaopen_lanes( lua_State *L ) { | ||
1951 | |||
1952 | // Initialized by 'init_once_LOCKED()': the deep userdata Linda object | ||
1953 | // used for timers (each lane will get a proxy to this) | ||
1954 | // | ||
1955 | static volatile DEEP_PRELUDE *timer_deep; // = NULL | ||
1956 | |||
1957 | /* | ||
1958 | * Making one-time initializations. | ||
1959 | * | ||
1960 | * When the host application is single-threaded (and all threading happens via Lanes) | ||
1961 | * there is no problem. But if the host is multithreaded, we need to lock around the | ||
1962 | * initializations. | ||
1963 | */ | ||
1964 | static volatile int /*bool*/ go_ahead; // = 0 | ||
1965 | #ifdef PLATFORM_WIN32 | ||
1966 | { | ||
1967 | // TBD: Someone please replace this with reliable Win32 API code. Problem is, | ||
1968 | // there's no autoinitializing locks (s.a. PTHREAD_MUTEX_INITIALIZER) in | ||
1969 | // Windows so 'InterlockedIncrement' or something needs to be used. | ||
1970 | // This is 99.9999% safe, though (and always safe if host is single-threaded) | ||
1971 | // -- AKa 24-Jun-2009 | ||
1972 | // | ||
1973 | static volatile unsigned my_number; // = 0 | ||
1974 | |||
1975 | if (my_number++ == 0) { // almost atomic | ||
1976 | init_once_LOCKED(L, &timer_deep); | ||
1977 | go_ahead= 1; // let others pass | ||
1978 | } else { | ||
1979 | while( !go_ahead ) { Sleep(1); } // changes threads | ||
1980 | } | ||
1981 | } | ||
1982 | #else | ||
1983 | if (!go_ahead) { | ||
1984 | static pthread_mutex_t my_lock= PTHREAD_MUTEX_INITIALIZER; | ||
1985 | pthread_mutex_lock(&my_lock); | ||
1986 | { | ||
1987 | // Recheck now that we're within the lock | ||
1988 | // | ||
1989 | if (!go_ahead) { | ||
1990 | init_once_LOCKED(L, &timer_deep); | ||
1991 | go_ahead= 1; | ||
1992 | } | ||
1993 | } | ||
1994 | pthread_mutex_unlock(&my_lock); | ||
1995 | } | ||
1996 | #endif | ||
1997 | assert( timer_deep != 0 ); | ||
1998 | |||
1813 | // Linda identity function | 1999 | // Linda identity function |
1814 | // | 2000 | // |
1815 | REG_FUNC( linda_id ); | 2001 | REG_FUNC( linda_id ); |
@@ -1835,7 +2021,7 @@ __declspec(dllexport) | |||
1835 | REG_FUNC( now_secs ); | 2021 | REG_FUNC( now_secs ); |
1836 | REG_FUNC( wakeup_conv ); | 2022 | REG_FUNC( wakeup_conv ); |
1837 | 2023 | ||
1838 | push_timer_gateway(L); | 2024 | luaG_push_proxy( L, LG_linda_id, (DEEP_PRELUDE *) timer_deep ); |
1839 | lua_setglobal( L, "timer_gateway" ); | 2025 | lua_setglobal( L, "timer_gateway" ); |
1840 | 2026 | ||
1841 | REG_INT2( max_prio, THREAD_PRIO_MAX ); | 2027 | 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 @@ | |||
6 | -- Author: Asko Kauppi <akauppi@gmail.com> | 6 | -- Author: Asko Kauppi <akauppi@gmail.com> |
7 | -- | 7 | -- |
8 | -- History: | 8 | -- History: |
9 | -- Jun-08 AKa: major revise | 9 | -- 3-Dec-10 BGe: Added support to generate a lane from a string |
10 | -- Jun-08 AKa: major revise | ||
10 | -- 15-May-07 AKa: pthread_join():less version, some speedup & ability to | 11 | -- 15-May-07 AKa: pthread_join():less version, some speedup & ability to |
11 | -- handle more threads (~ 8000-9000, up from ~ 5000) | 12 | -- handle more threads (~ 8000-9000, up from ~ 5000) |
12 | -- 26-Feb-07 AKa: serialization working (C side) | 13 | -- 26-Feb-07 AKa: serialization working (C side) |
@@ -15,7 +16,7 @@ | |||
15 | --[[ | 16 | --[[ |
16 | =============================================================================== | 17 | =============================================================================== |
17 | 18 | ||
18 | Copyright (C) 2007-08 Asko Kauppi <akauppi@gmail.com> | 19 | Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> |
19 | 20 | ||
20 | Permission is hereby granted, free of charge, to any person obtaining a copy | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy |
21 | of this software and associated documentation files (the "Software"), to deal | 22 | of this software and associated documentation files (the "Software"), to deal |
@@ -89,7 +90,7 @@ ABOUT= | |||
89 | author= "Asko Kauppi <akauppi@gmail.com>", | 90 | author= "Asko Kauppi <akauppi@gmail.com>", |
90 | description= "Running multiple Lua states in parallel", | 91 | description= "Running multiple Lua states in parallel", |
91 | license= "MIT/X11", | 92 | license= "MIT/X11", |
92 | copyright= "Copyright (c) 2007-08, Asko Kauppi", | 93 | copyright= "Copyright (c) 2007-10, Asko Kauppi", |
93 | version= _version, | 94 | version= _version, |
94 | } | 95 | } |
95 | 96 | ||
@@ -123,6 +124,14 @@ end | |||
123 | -- | 124 | -- |
124 | -- lane_h.state: "pending"/"running"/"waiting"/"done"/"error"/"cancelled" | 125 | -- lane_h.state: "pending"/"running"/"waiting"/"done"/"error"/"cancelled" |
125 | -- | 126 | -- |
127 | -- Note: Would be great to be able to have '__ipairs' metamethod, that gets | ||
128 | -- called by 'ipairs()' function to custom iterate objects. We'd use it | ||
129 | -- for making sure a lane has ended (results are available); not requiring | ||
130 | -- the user to precede a loop by explicit 'h[0]' or 'h:join()'. | ||
131 | -- | ||
132 | -- Or, even better, 'ipairs()' should start valuing '__index' instead | ||
133 | -- of using raw reads that bypass it. | ||
134 | -- | ||
126 | local lane_mt= { | 135 | local lane_mt= { |
127 | __index= function( me, k ) | 136 | __index= function( me, k ) |
128 | if type(k) == "number" then | 137 | if type(k) == "number" then |
@@ -260,8 +269,9 @@ function gen( ... ) | |||
260 | end | 269 | end |
261 | 270 | ||
262 | local func= select(n,...) | 271 | local func= select(n,...) |
263 | if type(func)~="function" then | 272 | local functype = type(func) |
264 | error( "Last parameter not function: "..tostring(func) ) | 273 | if functype ~= "function" and functype ~= "string" then |
274 | error( "Last parameter not function or string: "..tostring(func)) | ||
265 | end | 275 | end |
266 | 276 | ||
267 | -- Check 'libs' already here, so the error goes in the right place | 277 | -- Check 'libs' already here, so the error goes in the right place |
@@ -302,9 +312,10 @@ lane_proxy= function( ud ) | |||
302 | local proxy= { | 312 | local proxy= { |
303 | _ud= ud, | 313 | _ud= ud, |
304 | 314 | ||
305 | -- void= me:cancel() | 315 | -- true|false= me:cancel() |
306 | -- | 316 | -- |
307 | cancel= function(me) thread_cancel(me._ud) end, | 317 | cancel= function(me, time, force) return thread_cancel(me._ud, time, force) end, |
318 | |||
308 | 319 | ||
309 | -- [...] | [nil,err,stack_tbl]= me:join( [wait_secs=-1] ) | 320 | -- [...] | [nil,err,stack_tbl]= me:join( [wait_secs=-1] ) |
310 | -- | 321 | -- |
@@ -495,14 +506,18 @@ if first_time then | |||
495 | -- We let the timer lane be a "free running" thread; no handle to it | 506 | -- We let the timer lane be a "free running" thread; no handle to it |
496 | -- remains. | 507 | -- remains. |
497 | -- | 508 | -- |
498 | gen( "io", { priority=max_prio }, function() | 509 | gen( "io", { priority=max_prio, globals={threadName="LanesTimer"} }, function() |
499 | 510 | ||
500 | while true do | 511 | while true do |
501 | local next_wakeup= check_timers() | 512 | local next_wakeup= check_timers() |
502 | 513 | ||
503 | -- Sleep until next timer to wake up, or a set/clear command | 514 | -- Sleep until next timer to wake up, or a set/clear command |
504 | -- | 515 | -- |
505 | local secs= next_wakeup and (next_wakeup - now_secs()) or nil | 516 | local secs |
517 | if next_wakeup then | ||
518 | secs = next_wakeup - now_secs() | ||
519 | if secs < 0 then secs = 0 end | ||
520 | end | ||
506 | local linda= timer_gateway:receive( secs, TGW_KEY ) | 521 | local linda= timer_gateway:receive( secs, TGW_KEY ) |
507 | 522 | ||
508 | if linda then | 523 | 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 @@ | |||
1 | /* | 1 | /* |
2 | * THREADING.C Copyright (c) 2007-08, Asko Kauppi | 2 | * THREADING.C Copyright (c) 2007-10, Asko Kauppi |
3 | * | 3 | * |
4 | * Lua Lanes OS threading specific code. | 4 | * Lua Lanes OS threading specific code. |
5 | * | 5 | * |
@@ -10,7 +10,7 @@ | |||
10 | /* | 10 | /* |
11 | =============================================================================== | 11 | =============================================================================== |
12 | 12 | ||
13 | Copyright (C) 2007-08 Asko Kauppi <akauppi@gmail.com> | 13 | Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> |
14 | 14 | ||
15 | Permission is hereby granted, free of charge, to any person obtaining a copy | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy |
16 | of this software and associated documentation files (the "Software"), to deal | 16 | 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 ) { | |||
178 | 178 | ||
179 | ts->tv_sec= floor( abs_secs ); | 179 | ts->tv_sec= floor( abs_secs ); |
180 | ts->tv_nsec= ((long)((abs_secs - ts->tv_sec) * 1000.0 +0.5)) * 1000000UL; // 1ms = 1000000ns | 180 | ts->tv_nsec= ((long)((abs_secs - ts->tv_sec) * 1000.0 +0.5)) * 1000000UL; // 1ms = 1000000ns |
181 | if (ts->tv_nsec == 1000000000UL) | ||
182 | { | ||
183 | ts->tv_nsec = 0; | ||
184 | ts->tv_sec = ts->tv_sec + 1; | ||
185 | } | ||
181 | } | 186 | } |
182 | #endif | 187 | #endif |
183 | 188 | ||
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 @@ | |||
1 | /* | 1 | /* |
2 | * TOOLS.C Copyright (c) 2002-08, Asko Kauppi | 2 | * TOOLS.C Copyright (c) 2002-10, Asko Kauppi |
3 | * | 3 | * |
4 | * Lua tools to support Lanes. | 4 | * Lua tools to support Lanes. |
5 | */ | 5 | */ |
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | =============================================================================== | 8 | =============================================================================== |
9 | 9 | ||
10 | Copyright (C) 2002-08 Asko Kauppi <akauppi@gmail.com> | 10 | Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com> |
11 | 11 | ||
12 | Permission is hereby granted, free of charge, to any person obtaining a copy | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy |
13 | of this software and associated documentation files (the "Software"), to deal | 13 | of this software and associated documentation files (the "Software"), to deal |
@@ -40,8 +40,6 @@ THE SOFTWARE. | |||
40 | #include <ctype.h> | 40 | #include <ctype.h> |
41 | #include <stdlib.h> | 41 | #include <stdlib.h> |
42 | 42 | ||
43 | static volatile lua_CFunction hijacked_tostring; // = NULL | ||
44 | |||
45 | MUTEX_T deep_lock; | 43 | MUTEX_T deep_lock; |
46 | MUTEX_T mtid_lock; | 44 | MUTEX_T mtid_lock; |
47 | 45 | ||
@@ -600,7 +598,7 @@ uint_t get_mt_id( lua_State *L, int i ) { | |||
600 | // [-2]: reg[REG_MTID] | 598 | // [-2]: reg[REG_MTID] |
601 | // [-1]: nil/uint | 599 | // [-1]: nil/uint |
602 | 600 | ||
603 | id= lua_tointeger(L,-1); // 0 for nil | 601 | id= (uint_t)lua_tointeger(L,-1); // 0 for nil |
604 | lua_pop(L,1); | 602 | lua_pop(L,1); |
605 | STACK_MID(L,1) | 603 | STACK_MID(L,1) |
606 | 604 | ||
@@ -644,73 +642,60 @@ static int buf_writer( lua_State *L, const void* b, size_t n, void* B ) { | |||
644 | * Returns TRUE if the table was cached (no need to fill it!); FALSE if | 642 | * Returns TRUE if the table was cached (no need to fill it!); FALSE if |
645 | * it's a virgin. | 643 | * it's a virgin. |
646 | */ | 644 | */ |
647 | static | 645 | static bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) |
648 | bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) { | 646 | { |
649 | bool_t ret; | 647 | bool_t ret; |
650 | |||
651 | ASSERT_L( hijacked_tostring ); | ||
652 | ASSERT_L( L2_cache_i != 0 ); | ||
653 | |||
654 | STACK_GROW(L,2); | ||
655 | STACK_GROW(L2,3); | ||
656 | 648 | ||
657 | // Create an identity string for table at [i]; it should stay unique at | 649 | ASSERT_L( L2_cache_i != 0 ); |
658 | // least during copying of the data (then we can clear the caches). | ||
659 | // | ||
660 | STACK_CHECK(L) | ||
661 | lua_pushcfunction( L, hijacked_tostring ); | ||
662 | lua_pushvalue( L, i ); | ||
663 | lua_call( L, 1 /*args*/, 1 /*retvals*/ ); | ||
664 | // | ||
665 | // [-1]: "table: 0x...." | ||
666 | 650 | ||
667 | STACK_END(L,1) | 651 | STACK_GROW(L2,3); |
668 | ASSERT_L( lua_type(L,-1) == LUA_TSTRING ); | ||
669 | 652 | ||
670 | // L2_cache[id_str]= [{...}] | 653 | // L2_cache[id_str]= [{...}] |
671 | // | 654 | // |
672 | STACK_CHECK(L2) | 655 | STACK_CHECK(L2) |
673 | 656 | ||
674 | // We don't need to use the from state ('L') in ID since the life span | 657 | // We don't need to use the from state ('L') in ID since the life span |
675 | // is only for the duration of a copy (both states are locked). | 658 | // is only for the duration of a copy (both states are locked). |
676 | // | 659 | // |
677 | lua_pushstring( L2, lua_tostring(L,-1) ); | 660 | lua_pushlightuserdata( L2, (void*)lua_topointer( L, i )); // push a light userdata uniquely representing the table |
678 | lua_pop(L,1); // remove the 'tostring(tbl)' value (in L!) | ||
679 | 661 | ||
680 | //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); | 662 | //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); |
681 | 663 | ||
682 | lua_pushvalue( L2, -1 ); | 664 | lua_pushvalue( L2, -1 ); |
683 | lua_rawget( L2, L2_cache_i ); | 665 | lua_rawget( L2, L2_cache_i ); |
684 | // | 666 | // |
685 | // [-2]: identity string ("table: 0x...") | 667 | // [-2]: identity table pointer lightuserdata |
686 | // [-1]: table|nil | 668 | // [-1]: table|nil |
687 | |||
688 | if (lua_isnil(L2,-1)) { | ||
689 | lua_pop(L2,1); | ||
690 | lua_newtable(L2); | ||
691 | lua_pushvalue(L2,-1); | ||
692 | lua_insert(L2,-3); | ||
693 | // | ||
694 | // [-3]: new table (2nd ref) | ||
695 | // [-2]: identity string | ||
696 | // [-1]: new table | ||
697 | 669 | ||
698 | lua_rawset(L2, L2_cache_i); | 670 | if (lua_isnil(L2,-1)) |
699 | // | 671 | { |
700 | // [-1]: new table (tied to 'L2_cache' table') | 672 | lua_pop(L2,1); |
701 | 673 | lua_newtable(L2); | |
702 | ret= FALSE; // brand new | 674 | lua_pushvalue(L2,-1); |
703 | 675 | lua_insert(L2,-3); | |
704 | } else { | 676 | // |
705 | lua_remove(L2,-2); | 677 | // [-3]: new table (2nd ref) |
706 | ret= TRUE; // from cache | 678 | // [-2]: identity table pointer lightuserdata |
707 | } | 679 | // [-1]: new table |
708 | STACK_END(L2,1) | ||
709 | // | ||
710 | // L2 [-1]: table to use as destination | ||
711 | 680 | ||
712 | ASSERT_L( lua_istable(L2,-1) ); | 681 | lua_rawset(L2, L2_cache_i); |
713 | return ret; | 682 | // |
683 | // [-1]: new table (tied to 'L2_cache' table') | ||
684 | |||
685 | ret= FALSE; // brand new | ||
686 | |||
687 | } | ||
688 | else | ||
689 | { | ||
690 | lua_remove(L2,-2); | ||
691 | ret= TRUE; // from cache | ||
692 | } | ||
693 | STACK_END(L2,1) | ||
694 | // | ||
695 | // L2 [-1]: table to use as destination | ||
696 | |||
697 | ASSERT_L( lua_istable(L2,-1) ); | ||
698 | return ret; | ||
714 | } | 699 | } |
715 | 700 | ||
716 | 701 | ||
@@ -722,82 +707,76 @@ bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t | |||
722 | */ | 707 | */ |
723 | static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ); | 708 | static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ); |
724 | 709 | ||
725 | static | 710 | static void push_cached_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) |
726 | void push_cached_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) { | 711 | { |
727 | // TBD: Merge this and same code for tables | 712 | // TBD: Merge this and same code for tables |
728 | 713 | ||
729 | ASSERT_L( hijacked_tostring ); | 714 | ASSERT_L( L2_cache_i != 0 ); |
730 | ASSERT_L( L2_cache_i != 0 ); | ||
731 | 715 | ||
732 | STACK_GROW(L,2); | 716 | STACK_GROW(L2,3); |
733 | STACK_GROW(L2,3); | ||
734 | 717 | ||
735 | STACK_CHECK(L) | 718 | // L2_cache[id_str]= function |
736 | lua_pushcfunction( L, hijacked_tostring ); | 719 | // |
737 | lua_pushvalue( L, i ); | 720 | STACK_CHECK(L2) |
738 | lua_call( L, 1 /*args*/, 1 /*retvals*/ ); | ||
739 | // | ||
740 | // [-1]: "function: 0x...." | ||
741 | 721 | ||
742 | STACK_END(L,1) | 722 | // We don't need to use the from state ('L') in ID since the life span |
743 | ASSERT_L( lua_type(L,-1) == LUA_TSTRING ); | 723 | // is only for the duration of a copy (both states are locked). |
744 | 724 | // | |
745 | // L2_cache[id_str]= function | 725 | lua_pushlightuserdata( L2, (void*)lua_topointer( L, i )); // push a light userdata uniquely representing the function |
746 | // | ||
747 | STACK_CHECK(L2) | ||
748 | 726 | ||
749 | // We don't need to use the from state ('L') in ID since the life span | 727 | //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); |
750 | // is only for the duration of a copy (both states are locked). | ||
751 | // | ||
752 | lua_pushstring( L2, lua_tostring(L,-1) ); | ||
753 | lua_pop(L,1); // remove the 'tostring(tbl)' value (in L!) | ||
754 | 728 | ||
755 | //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); | 729 | lua_pushvalue( L2, -1 ); |
730 | lua_rawget( L2, L2_cache_i ); | ||
731 | // | ||
732 | // [-2]: identity lightuserdata function pointer | ||
733 | // [-1]: function|nil|true (true means: we're working on it; recursive) | ||
756 | 734 | ||
757 | lua_pushvalue( L2, -1 ); | 735 | if (lua_isnil(L2,-1)) |
758 | lua_rawget( L2, L2_cache_i ); | 736 | { |
759 | // | 737 | lua_pop(L2,1); |
760 | // [-2]: identity string ("function: 0x...") | ||
761 | // [-1]: function|nil|true (true means: we're working on it; recursive) | ||
762 | 738 | ||
763 | if (lua_isnil(L2,-1)) { | 739 | // Set to 'true' for the duration of creation; need to find self-references |
764 | lua_pop(L2,1); | 740 | // via upvalues |
765 | 741 | // | |
766 | // Set to 'true' for the duration of creation; need to find self-references | 742 | lua_pushvalue( L2, -1); |
767 | // via upvalues | 743 | lua_pushboolean(L2,TRUE); |
768 | // | 744 | lua_rawset( L2, L2_cache_i); |
769 | lua_pushboolean(L2,TRUE); | ||
770 | lua_setfield( L2, L2_cache_i, lua_tostring(L2,-2) ); | ||
771 | |||
772 | inter_copy_func( L2, L2_cache_i, L, i ); // pushes a copy of the func | ||
773 | 745 | ||
774 | lua_pushvalue(L2,-1); | 746 | inter_copy_func( L2, L2_cache_i, L, i ); // pushes a copy of the func |
775 | lua_insert(L2,-3); | ||
776 | // | ||
777 | // [-3]: function (2nd ref) | ||
778 | // [-2]: identity string | ||
779 | // [-1]: function | ||
780 | 747 | ||
781 | lua_rawset(L2,L2_cache_i); | 748 | lua_pushvalue(L2,-1); |
782 | // | 749 | lua_insert(L2,-3); |
783 | // [-1]: function (tied to 'L2_cache' table') | 750 | // |
784 | 751 | // [-3]: function (2nd ref) | |
785 | } else if (lua_isboolean(L2,-1)) { | 752 | // [-2]: identity lightuserdata function pointer |
786 | // Loop in preparing upvalues; either direct or via a table | 753 | // [-1]: function |
787 | // | ||
788 | // Note: This excludes the case where a function directly addresses | ||
789 | // itself as an upvalue (recursive lane creation). | ||
790 | // | ||
791 | luaL_error( L, "Recursive use of upvalues; cannot copy the function" ); | ||
792 | |||
793 | } else { | ||
794 | lua_remove(L2,-2); | ||
795 | } | ||
796 | STACK_END(L2,1) | ||
797 | // | ||
798 | // L2 [-1]: function | ||
799 | 754 | ||
800 | ASSERT_L( lua_isfunction(L2,-1) ); | 755 | lua_rawset(L2,L2_cache_i); |
756 | // | ||
757 | // [-1]: function (tied to 'L2_cache' table') | ||
758 | |||
759 | } | ||
760 | else if (lua_isboolean(L2,-1)) | ||
761 | { | ||
762 | // Loop in preparing upvalues; either direct or via a table | ||
763 | // | ||
764 | // Note: This excludes the case where a function directly addresses | ||
765 | // itself as an upvalue (recursive lane creation). | ||
766 | // | ||
767 | STACK_GROW(L,1); | ||
768 | luaL_error( L, "Recursive use of upvalues; cannot copy the function" ); | ||
769 | |||
770 | } | ||
771 | else | ||
772 | { | ||
773 | lua_remove(L2,-2); | ||
774 | } | ||
775 | STACK_END(L2,1) | ||
776 | // | ||
777 | // L2 [-1]: function | ||
778 | |||
779 | ASSERT_L( lua_isfunction(L2,-1) ); | ||
801 | } | 780 | } |
802 | 781 | ||
803 | 782 | ||
@@ -1137,29 +1116,6 @@ void luaG_inter_copy( lua_State* L, lua_State *L2, uint_t n ) | |||
1137 | uint_t top_L2= lua_gettop(L2); | 1116 | uint_t top_L2= lua_gettop(L2); |
1138 | uint_t i; | 1117 | uint_t i; |
1139 | 1118 | ||
1140 | /* steal Lua library's 'luaB_tostring()' from the first call. Other calls | ||
1141 | * don't have to have access to it. | ||
1142 | * | ||
1143 | * Note: multiple threads won't come here at once; this function will | ||
1144 | * be called before there can be multiple threads (no locking needed). | ||
1145 | */ | ||
1146 | if (!hijacked_tostring) { | ||
1147 | STACK_GROW( L,1 ); | ||
1148 | |||
1149 | STACK_CHECK(L) | ||
1150 | lua_getglobal( L, "tostring" ); | ||
1151 | // | ||
1152 | // [-1]: function|nil | ||
1153 | |||
1154 | hijacked_tostring= lua_tocfunction( L, -1 ); | ||
1155 | lua_pop(L,1); | ||
1156 | STACK_END(L,0) | ||
1157 | |||
1158 | if (!hijacked_tostring) { | ||
1159 | luaL_error( L, "Need to see 'tostring()' once" ); | ||
1160 | } | ||
1161 | } | ||
1162 | |||
1163 | if (n > top_L) | 1119 | if (n > top_L) |
1164 | luaL_error( L, "Not enough values: %d < %d", top_L, n ); | 1120 | luaL_error( L, "Not enough values: %d < %d", top_L, n ); |
1165 | 1121 | ||
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 @@ | |||
22 | #define STACK_END(L,c) /*nothing*/ | 22 | #define STACK_END(L,c) /*nothing*/ |
23 | #define STACK_DUMP(L) /*nothing*/ | 23 | #define STACK_DUMP(L) /*nothing*/ |
24 | #define DEBUG() /*nothing*/ | 24 | #define DEBUG() /*nothing*/ |
25 | #define DEBUGEXEC(_code) {} /*nothing*/ | ||
25 | #else | 26 | #else |
26 | #define _ASSERT_L(lua,c) { if (!(c)) luaL_error( lua, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #c ); } | 27 | #define _ASSERT_L(lua,c) { if (!(c)) luaL_error( lua, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #c ); } |
27 | // | 28 | // |
@@ -32,6 +33,7 @@ | |||
32 | 33 | ||
33 | #define STACK_DUMP(L) luaG_dump(L); | 34 | #define STACK_DUMP(L) luaG_dump(L); |
34 | #define DEBUG() fprintf( stderr, "<<%s %d>>\n", __FILE__, __LINE__ ); | 35 | #define DEBUG() fprintf( stderr, "<<%s %d>>\n", __FILE__, __LINE__ ); |
36 | #define DEBUGEXEC(_code) {_code;} /*nothing*/ | ||
35 | #endif | 37 | #endif |
36 | #define ASSERT_L(c) _ASSERT_L(L,c) | 38 | #define ASSERT_L(c) _ASSERT_L(L,c) |
37 | 39 | ||
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 @@ | |||
1 | -- | ||
2 | -- APPENDUD.LUA | ||
3 | -- | ||
4 | -- Lanes version for John Belmonte's challenge on Lua list (about finalizers): | ||
5 | -- <http://lua-users.org/lists/lua-l/2008-02/msg00243.html> | ||
6 | -- | ||
7 | -- Needs Lanes >= 2.0.3 | ||
8 | -- | ||
9 | require "lanes" | ||
10 | |||
11 | local _tab = { | ||
12 | beginupdate = function (this) print('tab.beginupdate') end; | ||
13 | endupdate = function (this) print('tab.endupdate') end; | ||
14 | } | ||
15 | local _ud = { | ||
16 | lock = function (this) print('ud.lock') end; | ||
17 | unlock = function (this) print('ud.unlock') end; | ||
18 | 1,2,3,4,5; | ||
19 | } | ||
20 | |||
21 | -- | ||
22 | -- This sample is with the 'finalize/guard' patch applied (new keywords): | ||
23 | -- | ||
24 | --function appendud(tab, ud) | ||
25 | -- tab:beginupdate() finalize tab:endupdate() end | ||
26 | -- ud:lock() finalize ud:unlock() end | ||
27 | -- for i = 1,#ud do | ||
28 | -- tab[#tab+1] = ud[i] | ||
29 | -- end | ||
30 | --end | ||
31 | |||
32 | |||
33 | function appendud(tab, ud) | ||
34 | io.stderr:write "Starting" | ||
35 | tab:beginupdate() set_finalizer( function() tab:endupdate() end ) | ||
36 | ud:lock() set_finalizer( function() ud:unlock() end ) | ||
37 | for i = 1,#ud do | ||
38 | tab[#tab+1] = ud[i] | ||
39 | end | ||
40 | io.stderr:write "Ending" | ||
41 | return tab -- need to return 'tab' since we're running in a separate thread | ||
42 | -- ('tab' is passed over lanes by value, not by reference) | ||
43 | end | ||
44 | |||
45 | local t,err= lanes.gen( appendud )( _tab, _ud ) -- create & launch a thread | ||
46 | assert(t) | ||
47 | assert(not err) | ||
48 | |||
49 | -- test | ||
50 | |||
51 | t:join() -- Need to explicitly wait for the thread, since 'ipairs()' does not | ||
52 | -- value the '__index' metamethod (wouldn't it be cool if it did..?) | ||
53 | |||
54 | io.stderr:write(t[1]) | ||
55 | |||
56 | for k,v in ipairs(t) do | ||
57 | print(k,v) | ||
58 | 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 @@ | |||
2 | -- BASIC.LUA Copyright (c) 2007-08, Asko Kauppi <akauppi@gmail.com> | 2 | -- BASIC.LUA Copyright (c) 2007-08, Asko Kauppi <akauppi@gmail.com> |
3 | -- | 3 | -- |
4 | -- Selftests for Lua Lanes | 4 | -- Selftests for Lua Lanes |
5 | -- | 5 | -- |
6 | -- To do: | 6 | -- To do: |
7 | -- - ... | 7 | -- - ... |
8 | -- | 8 | -- |
@@ -20,7 +20,7 @@ local function PRINT(...) | |||
20 | for i=1,select('#',...) do | 20 | for i=1,select('#',...) do |
21 | str= str..tostring(select(i,...)).."\t" | 21 | str= str..tostring(select(i,...)).."\t" |
22 | end | 22 | end |
23 | if io then | 23 | if io then |
24 | io.stderr:write(str.."\n") | 24 | io.stderr:write(str.."\n") |
25 | end | 25 | end |
26 | end | 26 | end |
@@ -55,7 +55,7 @@ tables_match= function( a, b ) | |||
55 | end | 55 | end |
56 | 56 | ||
57 | 57 | ||
58 | ---=== Tasking (basic) ===--- | 58 | PRINT( "---=== Tasking (basic) ===---") |
59 | 59 | ||
60 | local function task( a, b, c ) | 60 | local function task( a, b, c ) |
61 | --error "111" -- testing error messages | 61 | --error "111" -- testing error messages |
@@ -98,7 +98,7 @@ assert( lane1.status == "done" ) | |||
98 | assert( lane1.status == "done" ) | 98 | assert( lane1.status == "done" ) |
99 | 99 | ||
100 | 100 | ||
101 | ---=== Tasking (cancelling) ===--- | 101 | PRINT( "---=== Tasking (cancelling) ===---") |
102 | 102 | ||
103 | local task_launch2= lanes_gen( "", { cancelstep=100, globals={hey=true} }, task ) | 103 | local task_launch2= lanes_gen( "", { cancelstep=100, globals={hey=true} }, task ) |
104 | 104 | ||
@@ -136,7 +136,7 @@ PRINT(" "..st) | |||
136 | assert( st == "cancelled" ) | 136 | assert( st == "cancelled" ) |
137 | 137 | ||
138 | 138 | ||
139 | ---=== Communications ===--- | 139 | PRINT( "---=== Communications ===---") |
140 | 140 | ||
141 | local function WR(...) io.stderr:write(...) end | 141 | local function WR(...) io.stderr:write(...) end |
142 | 142 | ||
@@ -157,7 +157,7 @@ local chunk= function( linda ) | |||
157 | send { 'a', 'b', 'c', d=10 }; WR( "{'a','b','c',d=10} sent\n" ) | 157 | send { 'a', 'b', 'c', d=10 }; WR( "{'a','b','c',d=10} sent\n" ) |
158 | 158 | ||
159 | v=receive(); WR( v.." received\n" ); assert( v==4 ) | 159 | v=receive(); WR( v.." received\n" ); assert( v==4 ) |
160 | 160 | ||
161 | WR( "Lane ends!\n" ) | 161 | WR( "Lane ends!\n" ) |
162 | end | 162 | end |
163 | 163 | ||
@@ -195,7 +195,7 @@ assert( PEEK() == nil ) | |||
195 | SEND(4) | 195 | SEND(4) |
196 | 196 | ||
197 | 197 | ||
198 | ---=== Stdlib naming ===--- | 198 | PRINT( "---=== Stdlib naming ===---") |
199 | 199 | ||
200 | local function io_os_f() | 200 | local function io_os_f() |
201 | assert(io) | 201 | assert(io) |
@@ -215,7 +215,7 @@ assert( f2()[1] ) | |||
215 | assert( f3()[1] ) | 215 | assert( f3()[1] ) |
216 | 216 | ||
217 | 217 | ||
218 | ---=== Comms criss cross ===--- | 218 | PRINT( "---=== Comms criss cross ===---") |
219 | 219 | ||
220 | -- We make two identical lanes, which are using the same Linda channel. | 220 | -- We make two identical lanes, which are using the same Linda channel. |
221 | -- | 221 | -- |
@@ -241,7 +241,7 @@ local a,b= tc(linda, "A","B"), tc(linda, "B","A") -- launching two lanes, twis | |||
241 | local _= a[1],b[1] -- waits until they are both ready | 241 | local _= a[1],b[1] -- waits until they are both ready |
242 | 242 | ||
243 | 243 | ||
244 | ---=== Receive & send of code ===--- | 244 | PRINT( "---=== Receive & send of code ===---") |
245 | 245 | ||
246 | local upvalue="123" | 246 | local upvalue="123" |
247 | 247 | ||
@@ -251,21 +251,21 @@ local function chunk2( linda ) | |||
251 | -- function name & line number should be there even as separate thread | 251 | -- function name & line number should be there even as separate thread |
252 | -- | 252 | -- |
253 | local info= debug.getinfo(1) -- 1 = us | 253 | local info= debug.getinfo(1) -- 1 = us |
254 | -- | 254 | -- |
255 | for k,v in pairs(info) do PRINT(k,v) end | 255 | for k,v in pairs(info) do PRINT(k,v) end |
256 | 256 | ||
257 | assert( info.nups == 2 ) -- one upvalue + PRINT | 257 | assert( info.nups == 2 ) -- one upvalue + PRINT |
258 | assert( info.what == "Lua" ) | 258 | assert( info.what == "Lua" ) |
259 | 259 | ||
260 | --assert( info.name == "chunk2" ) -- name does not seem to come through | 260 | --assert( info.name == "chunk2" ) -- name does not seem to come through |
261 | assert( string.match( info.source, "^@tests[/\\]basic.lua$" ) ) | 261 | assert( string.match( info.source, "^@basic.lua$" ) ) |
262 | assert( string.match( info.short_src, "^tests[/\\]basic.lua$" ) ) | 262 | assert( string.match( info.short_src, "^basic.lua$" ) ) |
263 | 263 | ||
264 | -- These vary so let's not be picky (they're there..) | 264 | -- These vary so let's not be picky (they're there..) |
265 | -- | 265 | -- |
266 | assert( info.linedefined > 200 ) -- start of 'chunk2' | 266 | assert( info.linedefined > 200 ) -- start of 'chunk2' |
267 | assert( info.currentline > info.linedefined ) -- line of 'debug.getinfo' | 267 | assert( info.currentline > info.linedefined ) -- line of 'debug.getinfo' |
268 | assert( info.lastlinedefined > info.currentline ) -- end of 'chunk2' | 268 | assert( info.lastlinedefined > info.currentline ) -- end of 'chunk2' |
269 | 269 | ||
270 | local func,k= linda:receive( "down" ) | 270 | local func,k= linda:receive( "down" ) |
271 | assert( type(func)=="function" ) | 271 | assert( type(func)=="function" ) |
@@ -275,7 +275,7 @@ local function chunk2( linda ) | |||
275 | 275 | ||
276 | local str= linda:receive( "down" ) | 276 | local str= linda:receive( "down" ) |
277 | assert( str=="ok" ) | 277 | assert( str=="ok" ) |
278 | 278 | ||
279 | linda:send( "up", function() return ":)" end, "ok2" ) | 279 | linda:send( "up", function() return ":)" end, "ok2" ) |
280 | end | 280 | end |
281 | 281 | ||
@@ -304,7 +304,7 @@ local ok2= linda:receive( "up" ) | |||
304 | assert( ok2 == "ok2" ) | 304 | assert( ok2 == "ok2" ) |
305 | 305 | ||
306 | 306 | ||
307 | ---=== :join test ===--- | 307 | PRINT( "---=== :join test ===---") |
308 | 308 | ||
309 | -- NOTE: 'unpack()' cannot be used on the lane handle; it will always return nil | 309 | -- NOTE: 'unpack()' cannot be used on the lane handle; it will always return nil |
310 | -- (unless [1..n] has been read earlier, in which case it would seemingly | 310 | -- (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 @@ | |||
1 | require "lanes" | ||
2 | |||
3 | local options = {globals = { b = 666 }} | ||
4 | |||
5 | -- local gen1 = lanes.gen("*", "dofile('fibonacci.lua')") | ||
6 | local gen2 = lanes.gen(options, "return b") | ||
7 | |||
8 | -- fibLane = gen1() | ||
9 | retLane1, retLane2 = gen2(), gen2() | ||
10 | -- fibLane:join() | ||
11 | |||
12 | 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 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
3 | <plist version="1.0"> | ||
4 | <dict> | ||
5 | <key>ActivePerspectiveName</key> | ||
6 | <string>Project</string> | ||
7 | <key>AllowedModules</key> | ||
8 | <array> | ||
9 | <dict> | ||
10 | <key>BundleLoadPath</key> | ||
11 | <string></string> | ||
12 | <key>MaxInstances</key> | ||
13 | <string>n</string> | ||
14 | <key>Module</key> | ||
15 | <string>PBXSmartGroupTreeModule</string> | ||
16 | <key>Name</key> | ||
17 | <string>Groups and Files Outline View</string> | ||
18 | </dict> | ||
19 | <dict> | ||
20 | <key>BundleLoadPath</key> | ||
21 | <string></string> | ||
22 | <key>MaxInstances</key> | ||
23 | <string>n</string> | ||
24 | <key>Module</key> | ||
25 | <string>PBXNavigatorGroup</string> | ||
26 | <key>Name</key> | ||
27 | <string>Editor</string> | ||
28 | </dict> | ||
29 | <dict> | ||
30 | <key>BundleLoadPath</key> | ||
31 | <string></string> | ||
32 | <key>MaxInstances</key> | ||
33 | <string>n</string> | ||
34 | <key>Module</key> | ||
35 | <string>XCTaskListModule</string> | ||
36 | <key>Name</key> | ||
37 | <string>Task List</string> | ||
38 | </dict> | ||
39 | <dict> | ||
40 | <key>BundleLoadPath</key> | ||
41 | <string></string> | ||
42 | <key>MaxInstances</key> | ||
43 | <string>n</string> | ||
44 | <key>Module</key> | ||
45 | <string>XCDetailModule</string> | ||
46 | <key>Name</key> | ||
47 | <string>File and Smart Group Detail Viewer</string> | ||
48 | </dict> | ||
49 | <dict> | ||
50 | <key>BundleLoadPath</key> | ||
51 | <string></string> | ||
52 | <key>MaxInstances</key> | ||
53 | <string>1</string> | ||
54 | <key>Module</key> | ||
55 | <string>PBXBuildResultsModule</string> | ||
56 | <key>Name</key> | ||
57 | <string>Detailed Build Results Viewer</string> | ||
58 | </dict> | ||
59 | <dict> | ||
60 | <key>BundleLoadPath</key> | ||
61 | <string></string> | ||
62 | <key>MaxInstances</key> | ||
63 | <string>1</string> | ||
64 | <key>Module</key> | ||
65 | <string>PBXProjectFindModule</string> | ||
66 | <key>Name</key> | ||
67 | <string>Project Batch Find Tool</string> | ||
68 | </dict> | ||
69 | <dict> | ||
70 | <key>BundleLoadPath</key> | ||
71 | <string></string> | ||
72 | <key>MaxInstances</key> | ||
73 | <string>n</string> | ||
74 | <key>Module</key> | ||
75 | <string>PBXRunSessionModule</string> | ||
76 | <key>Name</key> | ||
77 | <string>Run Log</string> | ||
78 | </dict> | ||
79 | <dict> | ||
80 | <key>BundleLoadPath</key> | ||
81 | <string></string> | ||
82 | <key>MaxInstances</key> | ||
83 | <string>n</string> | ||
84 | <key>Module</key> | ||
85 | <string>PBXBookmarksModule</string> | ||
86 | <key>Name</key> | ||
87 | <string>Bookmarks Tool</string> | ||
88 | </dict> | ||
89 | <dict> | ||
90 | <key>BundleLoadPath</key> | ||
91 | <string></string> | ||
92 | <key>MaxInstances</key> | ||
93 | <string>n</string> | ||
94 | <key>Module</key> | ||
95 | <string>PBXClassBrowserModule</string> | ||
96 | <key>Name</key> | ||
97 | <string>Class Browser</string> | ||
98 | </dict> | ||
99 | <dict> | ||
100 | <key>BundleLoadPath</key> | ||
101 | <string></string> | ||
102 | <key>MaxInstances</key> | ||
103 | <string>n</string> | ||
104 | <key>Module</key> | ||
105 | <string>PBXCVSModule</string> | ||
106 | <key>Name</key> | ||
107 | <string>Source Code Control Tool</string> | ||
108 | </dict> | ||
109 | <dict> | ||
110 | <key>BundleLoadPath</key> | ||
111 | <string></string> | ||
112 | <key>MaxInstances</key> | ||
113 | <string>n</string> | ||
114 | <key>Module</key> | ||
115 | <string>PBXDebugBreakpointsModule</string> | ||
116 | <key>Name</key> | ||
117 | <string>Debug Breakpoints Tool</string> | ||
118 | </dict> | ||
119 | <dict> | ||
120 | <key>BundleLoadPath</key> | ||
121 | <string></string> | ||
122 | <key>MaxInstances</key> | ||
123 | <string>n</string> | ||
124 | <key>Module</key> | ||
125 | <string>XCDockableInspector</string> | ||
126 | <key>Name</key> | ||
127 | <string>Inspector</string> | ||
128 | </dict> | ||
129 | <dict> | ||
130 | <key>BundleLoadPath</key> | ||
131 | <string></string> | ||
132 | <key>MaxInstances</key> | ||
133 | <string>n</string> | ||
134 | <key>Module</key> | ||
135 | <string>PBXOpenQuicklyModule</string> | ||
136 | <key>Name</key> | ||
137 | <string>Open Quickly Tool</string> | ||
138 | </dict> | ||
139 | <dict> | ||
140 | <key>BundleLoadPath</key> | ||
141 | <string></string> | ||
142 | <key>MaxInstances</key> | ||
143 | <string>1</string> | ||
144 | <key>Module</key> | ||
145 | <string>PBXDebugSessionModule</string> | ||
146 | <key>Name</key> | ||
147 | <string>Debugger</string> | ||
148 | </dict> | ||
149 | <dict> | ||
150 | <key>BundleLoadPath</key> | ||
151 | <string></string> | ||
152 | <key>MaxInstances</key> | ||
153 | <string>1</string> | ||
154 | <key>Module</key> | ||
155 | <string>PBXDebugCLIModule</string> | ||
156 | <key>Name</key> | ||
157 | <string>Debug Console</string> | ||
158 | </dict> | ||
159 | </array> | ||
160 | <key>Description</key> | ||
161 | <string>DefaultDescriptionKey</string> | ||
162 | <key>DockingSystemVisible</key> | ||
163 | <false/> | ||
164 | <key>Extension</key> | ||
165 | <string>mode1</string> | ||
166 | <key>FavBarConfig</key> | ||
167 | <dict> | ||
168 | <key>PBXProjectModuleGUID</key> | ||
169 | <string>27602E5F0C2F36D60086E627</string> | ||
170 | <key>XCBarModuleItemNames</key> | ||
171 | <dict/> | ||
172 | <key>XCBarModuleItems</key> | ||
173 | <array/> | ||
174 | </dict> | ||
175 | <key>FirstTimeWindowDisplayed</key> | ||
176 | <false/> | ||
177 | <key>Identifier</key> | ||
178 | <string>com.apple.perspectives.project.mode1</string> | ||
179 | <key>MajorVersion</key> | ||
180 | <integer>31</integer> | ||
181 | <key>MinorVersion</key> | ||
182 | <integer>1</integer> | ||
183 | <key>Name</key> | ||
184 | <string>Default</string> | ||
185 | <key>Notifications</key> | ||
186 | <array> | ||
187 | <dict> | ||
188 | <key>XCObserverAutoDisconnectKey</key> | ||
189 | <true/> | ||
190 | <key>XCObserverDefintionKey</key> | ||
191 | <dict/> | ||
192 | <key>XCObserverFactoryKey</key> | ||
193 | <string>XCPerspectivesSpecificationIdentifier</string> | ||
194 | <key>XCObserverGUIDKey</key> | ||
195 | <string>XCObserverProjectIdentifier</string> | ||
196 | <key>XCObserverNotificationKey</key> | ||
197 | <string>PBXStatusBuildStateMessageNotification</string> | ||
198 | <key>XCObserverTargetKey</key> | ||
199 | <string>XCMainBuildResultsModuleGUID</string> | ||
200 | <key>XCObserverTriggerKey</key> | ||
201 | <string>awakenModuleWithObserver:</string> | ||
202 | <key>XCObserverValidationKey</key> | ||
203 | <dict/> | ||
204 | </dict> | ||
205 | </array> | ||
206 | <key>OpenEditors</key> | ||
207 | <array> | ||
208 | <dict> | ||
209 | <key>Content</key> | ||
210 | <dict> | ||
211 | <key>PBXProjectModuleGUID</key> | ||
212 | <string>2784DBE60CD6544900B13CF3</string> | ||
213 | <key>PBXProjectModuleLabel</key> | ||
214 | <string>gluax_static.c</string> | ||
215 | <key>PBXSplitModuleInNavigatorKey</key> | ||
216 | <dict> | ||
217 | <key>Split0</key> | ||
218 | <dict> | ||
219 | <key>PBXProjectModuleGUID</key> | ||
220 | <string>2784DBE70CD6544900B13CF3</string> | ||
221 | <key>PBXProjectModuleLabel</key> | ||
222 | <string>gluax_static.c</string> | ||
223 | <key>_historyCapacity</key> | ||
224 | <integer>0</integer> | ||
225 | <key>bookmark</key> | ||
226 | <string>2736316D0CD721CA00A12F3E</string> | ||
227 | <key>history</key> | ||
228 | <array> | ||
229 | <string>27F8E2020CD71E630081A54F</string> | ||
230 | </array> | ||
231 | </dict> | ||
232 | <key>SplitCount</key> | ||
233 | <string>1</string> | ||
234 | </dict> | ||
235 | <key>StatusBarVisibility</key> | ||
236 | <true/> | ||
237 | </dict> | ||
238 | <key>Geometry</key> | ||
239 | <dict> | ||
240 | <key>Frame</key> | ||
241 | <string>{{0, 20}, {1057, 709}}</string> | ||
242 | <key>PBXModuleWindowStatusBarHidden2</key> | ||
243 | <false/> | ||
244 | <key>RubberWindowFrame</key> | ||
245 | <string>349 236 1057 750 0 0 1680 1028 </string> | ||
246 | </dict> | ||
247 | </dict> | ||
248 | <dict> | ||
249 | <key>Content</key> | ||
250 | <dict> | ||
251 | <key>PBXProjectModuleGUID</key> | ||
252 | <string>27F6DA310C4416540054E42A</string> | ||
253 | <key>PBXProjectModuleLabel</key> | ||
254 | <string>gluax.c</string> | ||
255 | <key>PBXSplitModuleInNavigatorKey</key> | ||
256 | <dict> | ||
257 | <key>Split0</key> | ||
258 | <dict> | ||
259 | <key>PBXProjectModuleGUID</key> | ||
260 | <string>27F6DA320C4416540054E42A</string> | ||
261 | <key>PBXProjectModuleLabel</key> | ||
262 | <string>gluax.c</string> | ||
263 | <key>_historyCapacity</key> | ||
264 | <integer>0</integer> | ||
265 | <key>bookmark</key> | ||
266 | <string>2736316E0CD721CA00A12F3E</string> | ||
267 | <key>history</key> | ||
268 | <array> | ||
269 | <string>27F8E2030CD71E630081A54F</string> | ||
270 | </array> | ||
271 | </dict> | ||
272 | <key>SplitCount</key> | ||
273 | <string>1</string> | ||
274 | </dict> | ||
275 | <key>StatusBarVisibility</key> | ||
276 | <true/> | ||
277 | </dict> | ||
278 | <key>Geometry</key> | ||
279 | <dict> | ||
280 | <key>Frame</key> | ||
281 | <string>{{0, 20}, {1057, 709}}</string> | ||
282 | <key>PBXModuleWindowStatusBarHidden2</key> | ||
283 | <false/> | ||
284 | <key>RubberWindowFrame</key> | ||
285 | <string>540 110 1057 750 0 0 1680 1028 </string> | ||
286 | </dict> | ||
287 | </dict> | ||
288 | </array> | ||
289 | <key>PerspectiveWidths</key> | ||
290 | <array> | ||
291 | <integer>-1</integer> | ||
292 | <integer>-1</integer> | ||
293 | </array> | ||
294 | <key>Perspectives</key> | ||
295 | <array> | ||
296 | <dict> | ||
297 | <key>ChosenToolbarItems</key> | ||
298 | <array> | ||
299 | <string>active-target-popup</string> | ||
300 | <string>active-buildstyle-popup</string> | ||
301 | <string>action</string> | ||
302 | <string>NSToolbarFlexibleSpaceItem</string> | ||
303 | <string>buildOrClean</string> | ||
304 | <string>build-and-runOrDebug</string> | ||
305 | <string>com.apple.ide.PBXToolbarStopButton</string> | ||
306 | <string>get-info</string> | ||
307 | <string>toggle-editor</string> | ||
308 | <string>NSToolbarFlexibleSpaceItem</string> | ||
309 | <string>com.apple.pbx.toolbar.searchfield</string> | ||
310 | </array> | ||
311 | <key>ControllerClassBaseName</key> | ||
312 | <string></string> | ||
313 | <key>IconName</key> | ||
314 | <string>WindowOfProjectWithEditor</string> | ||
315 | <key>Identifier</key> | ||
316 | <string>perspective.project</string> | ||
317 | <key>IsVertical</key> | ||
318 | <false/> | ||
319 | <key>Layout</key> | ||
320 | <array> | ||
321 | <dict> | ||
322 | <key>BecomeActive</key> | ||
323 | <true/> | ||
324 | <key>ContentConfiguration</key> | ||
325 | <dict> | ||
326 | <key>PBXBottomSmartGroupGIDs</key> | ||
327 | <array> | ||
328 | <string>1C37FBAC04509CD000000102</string> | ||
329 | <string>1C37FAAC04509CD000000102</string> | ||
330 | <string>1C08E77C0454961000C914BD</string> | ||
331 | <string>1C37FABC05509CD000000102</string> | ||
332 | <string>1C37FABC05539CD112110102</string> | ||
333 | <string>E2644B35053B69B200211256</string> | ||
334 | <string>1C37FABC04509CD000100104</string> | ||
335 | <string>1CC0EA4004350EF90044410B</string> | ||
336 | <string>1CC0EA4004350EF90041110B</string> | ||
337 | </array> | ||
338 | <key>PBXProjectModuleGUID</key> | ||
339 | <string>1CE0B1FE06471DED0097A5F4</string> | ||
340 | <key>PBXProjectModuleLabel</key> | ||
341 | <string>Files</string> | ||
342 | <key>PBXProjectStructureProvided</key> | ||
343 | <string>yes</string> | ||
344 | <key>PBXSmartGroupTreeModuleColumnData</key> | ||
345 | <dict> | ||
346 | <key>PBXSmartGroupTreeModuleColumnWidthsKey</key> | ||
347 | <array> | ||
348 | <real>186</real> | ||
349 | </array> | ||
350 | <key>PBXSmartGroupTreeModuleColumnsKey_v4</key> | ||
351 | <array> | ||
352 | <string>MainColumn</string> | ||
353 | </array> | ||
354 | </dict> | ||
355 | <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key> | ||
356 | <dict> | ||
357 | <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key> | ||
358 | <array> | ||
359 | <string>08FB7794FE84155DC02AAC07</string> | ||
360 | <string>1AB674ADFE9D54B511CA2CBB</string> | ||
361 | <string>1C37FBAC04509CD000000102</string> | ||
362 | <string>1C37FAAC04509CD000000102</string> | ||
363 | <string>1C37FABC05509CD000000102</string> | ||
364 | </array> | ||
365 | <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key> | ||
366 | <array> | ||
367 | <array> | ||
368 | <integer>12</integer> | ||
369 | </array> | ||
370 | </array> | ||
371 | <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key> | ||
372 | <string>{{0, 0}, {186, 503}}</string> | ||
373 | </dict> | ||
374 | <key>PBXTopSmartGroupGIDs</key> | ||
375 | <array/> | ||
376 | <key>XCIncludePerspectivesSwitch</key> | ||
377 | <true/> | ||
378 | <key>XCSharingToken</key> | ||
379 | <string>com.apple.Xcode.GFSharingToken</string> | ||
380 | </dict> | ||
381 | <key>GeometryConfiguration</key> | ||
382 | <dict> | ||
383 | <key>Frame</key> | ||
384 | <string>{{0, 0}, {203, 521}}</string> | ||
385 | <key>GroupTreeTableConfiguration</key> | ||
386 | <array> | ||
387 | <string>MainColumn</string> | ||
388 | <real>186</real> | ||
389 | </array> | ||
390 | <key>RubberWindowFrame</key> | ||
391 | <string>243 337 880 562 0 0 1680 1028 </string> | ||
392 | </dict> | ||
393 | <key>Module</key> | ||
394 | <string>PBXSmartGroupTreeModule</string> | ||
395 | <key>Proportion</key> | ||
396 | <string>203pt</string> | ||
397 | </dict> | ||
398 | <dict> | ||
399 | <key>Dock</key> | ||
400 | <array> | ||
401 | <dict> | ||
402 | <key>ContentConfiguration</key> | ||
403 | <dict> | ||
404 | <key>PBXProjectModuleGUID</key> | ||
405 | <string>1CE0B20306471E060097A5F4</string> | ||
406 | <key>PBXProjectModuleLabel</key> | ||
407 | <string>MyNewFile14.java</string> | ||
408 | <key>PBXSplitModuleInNavigatorKey</key> | ||
409 | <dict> | ||
410 | <key>Split0</key> | ||
411 | <dict> | ||
412 | <key>PBXProjectModuleGUID</key> | ||
413 | <string>1CE0B20406471E060097A5F4</string> | ||
414 | <key>PBXProjectModuleLabel</key> | ||
415 | <string>MyNewFile14.java</string> | ||
416 | </dict> | ||
417 | <key>SplitCount</key> | ||
418 | <string>1</string> | ||
419 | </dict> | ||
420 | <key>StatusBarVisibility</key> | ||
421 | <true/> | ||
422 | </dict> | ||
423 | <key>GeometryConfiguration</key> | ||
424 | <dict> | ||
425 | <key>Frame</key> | ||
426 | <string>{{0, 0}, {672, 0}}</string> | ||
427 | <key>RubberWindowFrame</key> | ||
428 | <string>243 337 880 562 0 0 1680 1028 </string> | ||
429 | </dict> | ||
430 | <key>Module</key> | ||
431 | <string>PBXNavigatorGroup</string> | ||
432 | <key>Proportion</key> | ||
433 | <string>0pt</string> | ||
434 | </dict> | ||
435 | <dict> | ||
436 | <key>ContentConfiguration</key> | ||
437 | <dict> | ||
438 | <key>PBXProjectModuleGUID</key> | ||
439 | <string>1CE0B20506471E060097A5F4</string> | ||
440 | <key>PBXProjectModuleLabel</key> | ||
441 | <string>Detail</string> | ||
442 | </dict> | ||
443 | <key>GeometryConfiguration</key> | ||
444 | <dict> | ||
445 | <key>Frame</key> | ||
446 | <string>{{0, 5}, {672, 516}}</string> | ||
447 | <key>RubberWindowFrame</key> | ||
448 | <string>243 337 880 562 0 0 1680 1028 </string> | ||
449 | </dict> | ||
450 | <key>Module</key> | ||
451 | <string>XCDetailModule</string> | ||
452 | <key>Proportion</key> | ||
453 | <string>516pt</string> | ||
454 | </dict> | ||
455 | </array> | ||
456 | <key>Proportion</key> | ||
457 | <string>672pt</string> | ||
458 | </dict> | ||
459 | </array> | ||
460 | <key>Name</key> | ||
461 | <string>Project</string> | ||
462 | <key>ServiceClasses</key> | ||
463 | <array> | ||
464 | <string>XCModuleDock</string> | ||
465 | <string>PBXSmartGroupTreeModule</string> | ||
466 | <string>XCModuleDock</string> | ||
467 | <string>PBXNavigatorGroup</string> | ||
468 | <string>XCDetailModule</string> | ||
469 | </array> | ||
470 | <key>TableOfContents</key> | ||
471 | <array> | ||
472 | <string>2736315A0CD71F3400A12F3E</string> | ||
473 | <string>1CE0B1FE06471DED0097A5F4</string> | ||
474 | <string>2736315B0CD71F3400A12F3E</string> | ||
475 | <string>1CE0B20306471E060097A5F4</string> | ||
476 | <string>1CE0B20506471E060097A5F4</string> | ||
477 | </array> | ||
478 | <key>ToolbarConfiguration</key> | ||
479 | <string>xcode.toolbar.config.default</string> | ||
480 | </dict> | ||
481 | <dict> | ||
482 | <key>ControllerClassBaseName</key> | ||
483 | <string></string> | ||
484 | <key>IconName</key> | ||
485 | <string>WindowOfProject</string> | ||
486 | <key>Identifier</key> | ||
487 | <string>perspective.morph</string> | ||
488 | <key>IsVertical</key> | ||
489 | <integer>0</integer> | ||
490 | <key>Layout</key> | ||
491 | <array> | ||
492 | <dict> | ||
493 | <key>BecomeActive</key> | ||
494 | <integer>1</integer> | ||
495 | <key>ContentConfiguration</key> | ||
496 | <dict> | ||
497 | <key>PBXBottomSmartGroupGIDs</key> | ||
498 | <array> | ||
499 | <string>1C37FBAC04509CD000000102</string> | ||
500 | <string>1C37FAAC04509CD000000102</string> | ||
501 | <string>1C08E77C0454961000C914BD</string> | ||
502 | <string>1C37FABC05509CD000000102</string> | ||
503 | <string>1C37FABC05539CD112110102</string> | ||
504 | <string>E2644B35053B69B200211256</string> | ||
505 | <string>1C37FABC04509CD000100104</string> | ||
506 | <string>1CC0EA4004350EF90044410B</string> | ||
507 | <string>1CC0EA4004350EF90041110B</string> | ||
508 | </array> | ||
509 | <key>PBXProjectModuleGUID</key> | ||
510 | <string>11E0B1FE06471DED0097A5F4</string> | ||
511 | <key>PBXProjectModuleLabel</key> | ||
512 | <string>Files</string> | ||
513 | <key>PBXProjectStructureProvided</key> | ||
514 | <string>yes</string> | ||
515 | <key>PBXSmartGroupTreeModuleColumnData</key> | ||
516 | <dict> | ||
517 | <key>PBXSmartGroupTreeModuleColumnWidthsKey</key> | ||
518 | <array> | ||
519 | <real>186</real> | ||
520 | </array> | ||
521 | <key>PBXSmartGroupTreeModuleColumnsKey_v4</key> | ||
522 | <array> | ||
523 | <string>MainColumn</string> | ||
524 | </array> | ||
525 | </dict> | ||
526 | <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key> | ||
527 | <dict> | ||
528 | <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key> | ||
529 | <array> | ||
530 | <string>29B97314FDCFA39411CA2CEA</string> | ||
531 | <string>1C37FABC05509CD000000102</string> | ||
532 | </array> | ||
533 | <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key> | ||
534 | <array> | ||
535 | <array> | ||
536 | <integer>0</integer> | ||
537 | </array> | ||
538 | </array> | ||
539 | <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key> | ||
540 | <string>{{0, 0}, {186, 337}}</string> | ||
541 | </dict> | ||
542 | <key>PBXTopSmartGroupGIDs</key> | ||
543 | <array/> | ||
544 | <key>XCIncludePerspectivesSwitch</key> | ||
545 | <integer>1</integer> | ||
546 | <key>XCSharingToken</key> | ||
547 | <string>com.apple.Xcode.GFSharingToken</string> | ||
548 | </dict> | ||
549 | <key>GeometryConfiguration</key> | ||
550 | <dict> | ||
551 | <key>Frame</key> | ||
552 | <string>{{0, 0}, {203, 355}}</string> | ||
553 | <key>GroupTreeTableConfiguration</key> | ||
554 | <array> | ||
555 | <string>MainColumn</string> | ||
556 | <real>186</real> | ||
557 | </array> | ||
558 | <key>RubberWindowFrame</key> | ||
559 | <string>373 269 690 397 0 0 1440 878 </string> | ||
560 | </dict> | ||
561 | <key>Module</key> | ||
562 | <string>PBXSmartGroupTreeModule</string> | ||
563 | <key>Proportion</key> | ||
564 | <string>100%</string> | ||
565 | </dict> | ||
566 | </array> | ||
567 | <key>Name</key> | ||
568 | <string>Morph</string> | ||
569 | <key>PreferredWidth</key> | ||
570 | <integer>300</integer> | ||
571 | <key>ServiceClasses</key> | ||
572 | <array> | ||
573 | <string>XCModuleDock</string> | ||
574 | <string>PBXSmartGroupTreeModule</string> | ||
575 | </array> | ||
576 | <key>TableOfContents</key> | ||
577 | <array> | ||
578 | <string>11E0B1FE06471DED0097A5F4</string> | ||
579 | </array> | ||
580 | <key>ToolbarConfiguration</key> | ||
581 | <string>xcode.toolbar.config.default.short</string> | ||
582 | </dict> | ||
583 | </array> | ||
584 | <key>PerspectivesBarVisible</key> | ||
585 | <false/> | ||
586 | <key>ShelfIsVisible</key> | ||
587 | <false/> | ||
588 | <key>SourceDescription</key> | ||
589 | <string>file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string> | ||
590 | <key>StatusbarIsVisible</key> | ||
591 | <true/> | ||
592 | <key>TimeStamp</key> | ||
593 | <real>215425482.989885</real> | ||
594 | <key>ToolbarDisplayMode</key> | ||
595 | <integer>1</integer> | ||
596 | <key>ToolbarIsVisible</key> | ||
597 | <true/> | ||
598 | <key>ToolbarSizeMode</key> | ||
599 | <integer>1</integer> | ||
600 | <key>Type</key> | ||
601 | <string>Perspectives</string> | ||
602 | <key>UpdateMessage</key> | ||
603 | <string>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 '%@'?</string> | ||
604 | <key>WindowJustification</key> | ||
605 | <integer>5</integer> | ||
606 | <key>WindowOrderList</key> | ||
607 | <array> | ||
608 | <string>2736315E0CD71F3400A12F3E</string> | ||
609 | <string>2736315F0CD71F3400A12F3E</string> | ||
610 | <string>274A5F0A0C2F4351000A66CF</string> | ||
611 | <string>273631580CD71F2400A12F3E</string> | ||
612 | <string>27F6DA310C4416540054E42A</string> | ||
613 | <string>2784DBE60CD6544900B13CF3</string> | ||
614 | <string>/Users/abisoft/Slug/public/2007/Lua Modules/Lanes/xcode/xcode.xcodeproj</string> | ||
615 | <string>27602E740C2F3B100086E627</string> | ||
616 | <string>1CD10A99069EF8BA00B06720</string> | ||
617 | </array> | ||
618 | <key>WindowString</key> | ||
619 | <string>243 337 880 562 0 0 1680 1028 </string> | ||
620 | <key>WindowTools</key> | ||
621 | <array> | ||
622 | <dict> | ||
623 | <key>FirstTimeWindowDisplayed</key> | ||
624 | <false/> | ||
625 | <key>Identifier</key> | ||
626 | <string>windowTool.build</string> | ||
627 | <key>IsVertical</key> | ||
628 | <true/> | ||
629 | <key>Layout</key> | ||
630 | <array> | ||
631 | <dict> | ||
632 | <key>Dock</key> | ||
633 | <array> | ||
634 | <dict> | ||
635 | <key>ContentConfiguration</key> | ||
636 | <dict> | ||
637 | <key>PBXProjectModuleGUID</key> | ||
638 | <string>1CD0528F0623707200166675</string> | ||
639 | <key>PBXProjectModuleLabel</key> | ||
640 | <string></string> | ||
641 | <key>StatusBarVisibility</key> | ||
642 | <true/> | ||
643 | </dict> | ||
644 | <key>GeometryConfiguration</key> | ||
645 | <dict> | ||
646 | <key>Frame</key> | ||
647 | <string>{{0, 0}, {983, 267}}</string> | ||
648 | <key>RubberWindowFrame</key> | ||
649 | <string>541 112 983 821 0 0 1680 1028 </string> | ||
650 | </dict> | ||
651 | <key>Module</key> | ||
652 | <string>PBXNavigatorGroup</string> | ||
653 | <key>Proportion</key> | ||
654 | <string>267pt</string> | ||
655 | </dict> | ||
656 | <dict> | ||
657 | <key>BecomeActive</key> | ||
658 | <true/> | ||
659 | <key>ContentConfiguration</key> | ||
660 | <dict> | ||
661 | <key>PBXBuildLogShowsTranscriptDefaultKey</key> | ||
662 | <string>{{0, 5}, {983, 503}}</string> | ||
663 | <key>PBXProjectModuleGUID</key> | ||
664 | <string>XCMainBuildResultsModuleGUID</string> | ||
665 | <key>PBXProjectModuleLabel</key> | ||
666 | <string>Build</string> | ||
667 | <key>XCBuildResultsTrigger_Collapse</key> | ||
668 | <integer>1021</integer> | ||
669 | <key>XCBuildResultsTrigger_Open</key> | ||
670 | <integer>1010</integer> | ||
671 | </dict> | ||
672 | <key>GeometryConfiguration</key> | ||
673 | <dict> | ||
674 | <key>Frame</key> | ||
675 | <string>{{0, 272}, {983, 508}}</string> | ||
676 | <key>RubberWindowFrame</key> | ||
677 | <string>541 112 983 821 0 0 1680 1028 </string> | ||
678 | </dict> | ||
679 | <key>Module</key> | ||
680 | <string>PBXBuildResultsModule</string> | ||
681 | <key>Proportion</key> | ||
682 | <string>508pt</string> | ||
683 | </dict> | ||
684 | </array> | ||
685 | <key>Proportion</key> | ||
686 | <string>780pt</string> | ||
687 | </dict> | ||
688 | </array> | ||
689 | <key>Name</key> | ||
690 | <string>Build Results</string> | ||
691 | <key>ServiceClasses</key> | ||
692 | <array> | ||
693 | <string>PBXBuildResultsModule</string> | ||
694 | </array> | ||
695 | <key>StatusbarIsVisible</key> | ||
696 | <true/> | ||
697 | <key>TableOfContents</key> | ||
698 | <array> | ||
699 | <string>27602E740C2F3B100086E627</string> | ||
700 | <string>273631510CD71F2400A12F3E</string> | ||
701 | <string>1CD0528F0623707200166675</string> | ||
702 | <string>XCMainBuildResultsModuleGUID</string> | ||
703 | </array> | ||
704 | <key>ToolbarConfiguration</key> | ||
705 | <string>xcode.toolbar.config.build</string> | ||
706 | <key>WindowString</key> | ||
707 | <string>541 112 983 821 0 0 1680 1028 </string> | ||
708 | <key>WindowToolGUID</key> | ||
709 | <string>27602E740C2F3B100086E627</string> | ||
710 | <key>WindowToolIsVisible</key> | ||
711 | <true/> | ||
712 | </dict> | ||
713 | <dict> | ||
714 | <key>FirstTimeWindowDisplayed</key> | ||
715 | <false/> | ||
716 | <key>Identifier</key> | ||
717 | <string>windowTool.debugger</string> | ||
718 | <key>IsVertical</key> | ||
719 | <true/> | ||
720 | <key>Layout</key> | ||
721 | <array> | ||
722 | <dict> | ||
723 | <key>Dock</key> | ||
724 | <array> | ||
725 | <dict> | ||
726 | <key>ContentConfiguration</key> | ||
727 | <dict> | ||
728 | <key>Debugger</key> | ||
729 | <dict> | ||
730 | <key>HorizontalSplitView</key> | ||
731 | <dict> | ||
732 | <key>_collapsingFrameDimension</key> | ||
733 | <real>0.0</real> | ||
734 | <key>_indexOfCollapsedView</key> | ||
735 | <integer>0</integer> | ||
736 | <key>_percentageOfCollapsedView</key> | ||
737 | <real>0.0</real> | ||
738 | <key>isCollapsed</key> | ||
739 | <string>yes</string> | ||
740 | <key>sizes</key> | ||
741 | <array> | ||
742 | <string>{{0, 0}, {437, 275}}</string> | ||
743 | <string>{{437, 0}, {584, 275}}</string> | ||
744 | </array> | ||
745 | </dict> | ||
746 | <key>VerticalSplitView</key> | ||
747 | <dict> | ||
748 | <key>_collapsingFrameDimension</key> | ||
749 | <real>0.0</real> | ||
750 | <key>_indexOfCollapsedView</key> | ||
751 | <integer>0</integer> | ||
752 | <key>_percentageOfCollapsedView</key> | ||
753 | <real>0.0</real> | ||
754 | <key>isCollapsed</key> | ||
755 | <string>yes</string> | ||
756 | <key>sizes</key> | ||
757 | <array> | ||
758 | <string>{{0, 0}, {1021, 275}}</string> | ||
759 | <string>{{0, 275}, {1021, 605}}</string> | ||
760 | </array> | ||
761 | </dict> | ||
762 | </dict> | ||
763 | <key>LauncherConfigVersion</key> | ||
764 | <string>8</string> | ||
765 | <key>PBXProjectModuleGUID</key> | ||
766 | <string>1C162984064C10D400B95A72</string> | ||
767 | <key>PBXProjectModuleLabel</key> | ||
768 | <string>Debug - GLUTExamples (Underwater)</string> | ||
769 | </dict> | ||
770 | <key>GeometryConfiguration</key> | ||
771 | <dict> | ||
772 | <key>DebugConsoleDrawerSize</key> | ||
773 | <string>{100, 120}</string> | ||
774 | <key>DebugConsoleVisible</key> | ||
775 | <string>None</string> | ||
776 | <key>DebugConsoleWindowFrame</key> | ||
777 | <string>{{200, 200}, {500, 300}}</string> | ||
778 | <key>DebugSTDIOWindowFrame</key> | ||
779 | <string>{{200, 200}, {500, 300}}</string> | ||
780 | <key>Frame</key> | ||
781 | <string>{{0, 0}, {1021, 880}}</string> | ||
782 | <key>RubberWindowFrame</key> | ||
783 | <string>504 97 1021 921 0 0 1680 1028 </string> | ||
784 | </dict> | ||
785 | <key>Module</key> | ||
786 | <string>PBXDebugSessionModule</string> | ||
787 | <key>Proportion</key> | ||
788 | <string>880pt</string> | ||
789 | </dict> | ||
790 | </array> | ||
791 | <key>Proportion</key> | ||
792 | <string>880pt</string> | ||
793 | </dict> | ||
794 | </array> | ||
795 | <key>Name</key> | ||
796 | <string>Debugger</string> | ||
797 | <key>ServiceClasses</key> | ||
798 | <array> | ||
799 | <string>PBXDebugSessionModule</string> | ||
800 | </array> | ||
801 | <key>StatusbarIsVisible</key> | ||
802 | <true/> | ||
803 | <key>TableOfContents</key> | ||
804 | <array> | ||
805 | <string>1CD10A99069EF8BA00B06720</string> | ||
806 | <string>273631520CD71F2400A12F3E</string> | ||
807 | <string>1C162984064C10D400B95A72</string> | ||
808 | <string>273631530CD71F2400A12F3E</string> | ||
809 | <string>273631540CD71F2400A12F3E</string> | ||
810 | <string>273631550CD71F2400A12F3E</string> | ||
811 | <string>273631560CD71F2400A12F3E</string> | ||
812 | <string>273631570CD71F2400A12F3E</string> | ||
813 | <string>273631580CD71F2400A12F3E</string> | ||
814 | </array> | ||
815 | <key>ToolbarConfiguration</key> | ||
816 | <string>xcode.toolbar.config.debug</string> | ||
817 | <key>WindowString</key> | ||
818 | <string>504 97 1021 921 0 0 1680 1028 </string> | ||
819 | <key>WindowToolGUID</key> | ||
820 | <string>1CD10A99069EF8BA00B06720</string> | ||
821 | <key>WindowToolIsVisible</key> | ||
822 | <true/> | ||
823 | </dict> | ||
824 | <dict> | ||
825 | <key>Identifier</key> | ||
826 | <string>windowTool.find</string> | ||
827 | <key>Layout</key> | ||
828 | <array> | ||
829 | <dict> | ||
830 | <key>Dock</key> | ||
831 | <array> | ||
832 | <dict> | ||
833 | <key>Dock</key> | ||
834 | <array> | ||
835 | <dict> | ||
836 | <key>ContentConfiguration</key> | ||
837 | <dict> | ||
838 | <key>PBXProjectModuleGUID</key> | ||
839 | <string>1CDD528C0622207200134675</string> | ||
840 | <key>PBXProjectModuleLabel</key> | ||
841 | <string><No Editor></string> | ||
842 | <key>PBXSplitModuleInNavigatorKey</key> | ||
843 | <dict> | ||
844 | <key>Split0</key> | ||
845 | <dict> | ||
846 | <key>PBXProjectModuleGUID</key> | ||
847 | <string>1CD0528D0623707200166675</string> | ||
848 | </dict> | ||
849 | <key>SplitCount</key> | ||
850 | <string>1</string> | ||
851 | </dict> | ||
852 | <key>StatusBarVisibility</key> | ||
853 | <integer>1</integer> | ||
854 | </dict> | ||
855 | <key>GeometryConfiguration</key> | ||
856 | <dict> | ||
857 | <key>Frame</key> | ||
858 | <string>{{0, 0}, {781, 167}}</string> | ||
859 | <key>RubberWindowFrame</key> | ||
860 | <string>62 385 781 470 0 0 1440 878 </string> | ||
861 | </dict> | ||
862 | <key>Module</key> | ||
863 | <string>PBXNavigatorGroup</string> | ||
864 | <key>Proportion</key> | ||
865 | <string>781pt</string> | ||
866 | </dict> | ||
867 | </array> | ||
868 | <key>Proportion</key> | ||
869 | <string>50%</string> | ||
870 | </dict> | ||
871 | <dict> | ||
872 | <key>BecomeActive</key> | ||
873 | <integer>1</integer> | ||
874 | <key>ContentConfiguration</key> | ||
875 | <dict> | ||
876 | <key>PBXProjectModuleGUID</key> | ||
877 | <string>1CD0528E0623707200166675</string> | ||
878 | <key>PBXProjectModuleLabel</key> | ||
879 | <string>Project Find</string> | ||
880 | </dict> | ||
881 | <key>GeometryConfiguration</key> | ||
882 | <dict> | ||
883 | <key>Frame</key> | ||
884 | <string>{{8, 0}, {773, 254}}</string> | ||
885 | <key>RubberWindowFrame</key> | ||
886 | <string>62 385 781 470 0 0 1440 878 </string> | ||
887 | </dict> | ||
888 | <key>Module</key> | ||
889 | <string>PBXProjectFindModule</string> | ||
890 | <key>Proportion</key> | ||
891 | <string>50%</string> | ||
892 | </dict> | ||
893 | </array> | ||
894 | <key>Proportion</key> | ||
895 | <string>428pt</string> | ||
896 | </dict> | ||
897 | </array> | ||
898 | <key>Name</key> | ||
899 | <string>Project Find</string> | ||
900 | <key>ServiceClasses</key> | ||
901 | <array> | ||
902 | <string>PBXProjectFindModule</string> | ||
903 | </array> | ||
904 | <key>StatusbarIsVisible</key> | ||
905 | <integer>1</integer> | ||
906 | <key>TableOfContents</key> | ||
907 | <array> | ||
908 | <string>1C530D57069F1CE1000CFCEE</string> | ||
909 | <string>1C530D58069F1CE1000CFCEE</string> | ||
910 | <string>1C530D59069F1CE1000CFCEE</string> | ||
911 | <string>1CDD528C0622207200134675</string> | ||
912 | <string>1C530D5A069F1CE1000CFCEE</string> | ||
913 | <string>1CE0B1FE06471DED0097A5F4</string> | ||
914 | <string>1CD0528E0623707200166675</string> | ||
915 | </array> | ||
916 | <key>WindowString</key> | ||
917 | <string>62 385 781 470 0 0 1440 878 </string> | ||
918 | <key>WindowToolGUID</key> | ||
919 | <string>1C530D57069F1CE1000CFCEE</string> | ||
920 | <key>WindowToolIsVisible</key> | ||
921 | <integer>0</integer> | ||
922 | </dict> | ||
923 | <dict> | ||
924 | <key>Identifier</key> | ||
925 | <string>MENUSEPARATOR</string> | ||
926 | </dict> | ||
927 | <dict> | ||
928 | <key>FirstTimeWindowDisplayed</key> | ||
929 | <false/> | ||
930 | <key>Identifier</key> | ||
931 | <string>windowTool.debuggerConsole</string> | ||
932 | <key>IsVertical</key> | ||
933 | <true/> | ||
934 | <key>Layout</key> | ||
935 | <array> | ||
936 | <dict> | ||
937 | <key>Dock</key> | ||
938 | <array> | ||
939 | <dict> | ||
940 | <key>BecomeActive</key> | ||
941 | <true/> | ||
942 | <key>ContentConfiguration</key> | ||
943 | <dict> | ||
944 | <key>PBXProjectModuleGUID</key> | ||
945 | <string>1C78EAAC065D492600B07095</string> | ||
946 | <key>PBXProjectModuleLabel</key> | ||
947 | <string>Debugger Console</string> | ||
948 | </dict> | ||
949 | <key>GeometryConfiguration</key> | ||
950 | <dict> | ||
951 | <key>Frame</key> | ||
952 | <string>{{0, 0}, {873, 523}}</string> | ||
953 | <key>RubberWindowFrame</key> | ||
954 | <string>114 193 873 564 0 0 1680 1028 </string> | ||
955 | </dict> | ||
956 | <key>Module</key> | ||
957 | <string>PBXDebugCLIModule</string> | ||
958 | <key>Proportion</key> | ||
959 | <string>523pt</string> | ||
960 | </dict> | ||
961 | </array> | ||
962 | <key>Proportion</key> | ||
963 | <string>523pt</string> | ||
964 | </dict> | ||
965 | </array> | ||
966 | <key>Name</key> | ||
967 | <string>Debugger Console</string> | ||
968 | <key>ServiceClasses</key> | ||
969 | <array> | ||
970 | <string>PBXDebugCLIModule</string> | ||
971 | </array> | ||
972 | <key>StatusbarIsVisible</key> | ||
973 | <true/> | ||
974 | <key>TableOfContents</key> | ||
975 | <array> | ||
976 | <string>274A5F0A0C2F4351000A66CF</string> | ||
977 | <string>273631590CD71F2400A12F3E</string> | ||
978 | <string>1C78EAAC065D492600B07095</string> | ||
979 | </array> | ||
980 | <key>WindowString</key> | ||
981 | <string>114 193 873 564 0 0 1680 1028 </string> | ||
982 | <key>WindowToolGUID</key> | ||
983 | <string>274A5F0A0C2F4351000A66CF</string> | ||
984 | <key>WindowToolIsVisible</key> | ||
985 | <false/> | ||
986 | </dict> | ||
987 | <dict> | ||
988 | <key>Identifier</key> | ||
989 | <string>windowTool.run</string> | ||
990 | <key>Layout</key> | ||
991 | <array> | ||
992 | <dict> | ||
993 | <key>Dock</key> | ||
994 | <array> | ||
995 | <dict> | ||
996 | <key>ContentConfiguration</key> | ||
997 | <dict> | ||
998 | <key>LauncherConfigVersion</key> | ||
999 | <string>3</string> | ||
1000 | <key>PBXProjectModuleGUID</key> | ||
1001 | <string>1CD0528B0623707200166675</string> | ||
1002 | <key>PBXProjectModuleLabel</key> | ||
1003 | <string>Run</string> | ||
1004 | <key>Runner</key> | ||
1005 | <dict> | ||
1006 | <key>HorizontalSplitView</key> | ||
1007 | <dict> | ||
1008 | <key>_collapsingFrameDimension</key> | ||
1009 | <real>0.0</real> | ||
1010 | <key>_indexOfCollapsedView</key> | ||
1011 | <integer>0</integer> | ||
1012 | <key>_percentageOfCollapsedView</key> | ||
1013 | <real>0.0</real> | ||
1014 | <key>isCollapsed</key> | ||
1015 | <string>yes</string> | ||
1016 | <key>sizes</key> | ||
1017 | <array> | ||
1018 | <string>{{0, 0}, {493, 167}}</string> | ||
1019 | <string>{{0, 176}, {493, 267}}</string> | ||
1020 | </array> | ||
1021 | </dict> | ||
1022 | <key>VerticalSplitView</key> | ||
1023 | <dict> | ||
1024 | <key>_collapsingFrameDimension</key> | ||
1025 | <real>0.0</real> | ||
1026 | <key>_indexOfCollapsedView</key> | ||
1027 | <integer>0</integer> | ||
1028 | <key>_percentageOfCollapsedView</key> | ||
1029 | <real>0.0</real> | ||
1030 | <key>isCollapsed</key> | ||
1031 | <string>yes</string> | ||
1032 | <key>sizes</key> | ||
1033 | <array> | ||
1034 | <string>{{0, 0}, {405, 443}}</string> | ||
1035 | <string>{{414, 0}, {514, 443}}</string> | ||
1036 | </array> | ||
1037 | </dict> | ||
1038 | </dict> | ||
1039 | </dict> | ||
1040 | <key>GeometryConfiguration</key> | ||
1041 | <dict> | ||
1042 | <key>Frame</key> | ||
1043 | <string>{{0, 0}, {460, 159}}</string> | ||
1044 | <key>RubberWindowFrame</key> | ||
1045 | <string>316 696 459 200 0 0 1280 1002 </string> | ||
1046 | </dict> | ||
1047 | <key>Module</key> | ||
1048 | <string>PBXRunSessionModule</string> | ||
1049 | <key>Proportion</key> | ||
1050 | <string>159pt</string> | ||
1051 | </dict> | ||
1052 | </array> | ||
1053 | <key>Proportion</key> | ||
1054 | <string>159pt</string> | ||
1055 | </dict> | ||
1056 | </array> | ||
1057 | <key>Name</key> | ||
1058 | <string>Run Log</string> | ||
1059 | <key>ServiceClasses</key> | ||
1060 | <array> | ||
1061 | <string>PBXRunSessionModule</string> | ||
1062 | </array> | ||
1063 | <key>StatusbarIsVisible</key> | ||
1064 | <integer>1</integer> | ||
1065 | <key>TableOfContents</key> | ||
1066 | <array> | ||
1067 | <string>1C0AD2B3069F1EA900FABCE6</string> | ||
1068 | <string>1C0AD2B4069F1EA900FABCE6</string> | ||
1069 | <string>1CD0528B0623707200166675</string> | ||
1070 | <string>1C0AD2B5069F1EA900FABCE6</string> | ||
1071 | </array> | ||
1072 | <key>ToolbarConfiguration</key> | ||
1073 | <string>xcode.toolbar.config.run</string> | ||
1074 | <key>WindowString</key> | ||
1075 | <string>316 696 459 200 0 0 1280 1002 </string> | ||
1076 | <key>WindowToolGUID</key> | ||
1077 | <string>1C0AD2B3069F1EA900FABCE6</string> | ||
1078 | <key>WindowToolIsVisible</key> | ||
1079 | <integer>0</integer> | ||
1080 | </dict> | ||
1081 | <dict> | ||
1082 | <key>Identifier</key> | ||
1083 | <string>windowTool.scm</string> | ||
1084 | <key>Layout</key> | ||
1085 | <array> | ||
1086 | <dict> | ||
1087 | <key>Dock</key> | ||
1088 | <array> | ||
1089 | <dict> | ||
1090 | <key>ContentConfiguration</key> | ||
1091 | <dict> | ||
1092 | <key>PBXProjectModuleGUID</key> | ||
1093 | <string>1C78EAB2065D492600B07095</string> | ||
1094 | <key>PBXProjectModuleLabel</key> | ||
1095 | <string><No Editor></string> | ||
1096 | <key>PBXSplitModuleInNavigatorKey</key> | ||
1097 | <dict> | ||
1098 | <key>Split0</key> | ||
1099 | <dict> | ||
1100 | <key>PBXProjectModuleGUID</key> | ||
1101 | <string>1C78EAB3065D492600B07095</string> | ||
1102 | </dict> | ||
1103 | <key>SplitCount</key> | ||
1104 | <string>1</string> | ||
1105 | </dict> | ||
1106 | <key>StatusBarVisibility</key> | ||
1107 | <integer>1</integer> | ||
1108 | </dict> | ||
1109 | <key>GeometryConfiguration</key> | ||
1110 | <dict> | ||
1111 | <key>Frame</key> | ||
1112 | <string>{{0, 0}, {452, 0}}</string> | ||
1113 | <key>RubberWindowFrame</key> | ||
1114 | <string>743 379 452 308 0 0 1280 1002 </string> | ||
1115 | </dict> | ||
1116 | <key>Module</key> | ||
1117 | <string>PBXNavigatorGroup</string> | ||
1118 | <key>Proportion</key> | ||
1119 | <string>0pt</string> | ||
1120 | </dict> | ||
1121 | <dict> | ||
1122 | <key>BecomeActive</key> | ||
1123 | <integer>1</integer> | ||
1124 | <key>ContentConfiguration</key> | ||
1125 | <dict> | ||
1126 | <key>PBXProjectModuleGUID</key> | ||
1127 | <string>1CD052920623707200166675</string> | ||
1128 | <key>PBXProjectModuleLabel</key> | ||
1129 | <string>SCM</string> | ||
1130 | </dict> | ||
1131 | <key>GeometryConfiguration</key> | ||
1132 | <dict> | ||
1133 | <key>ConsoleFrame</key> | ||
1134 | <string>{{0, 259}, {452, 0}}</string> | ||
1135 | <key>Frame</key> | ||
1136 | <string>{{0, 7}, {452, 259}}</string> | ||
1137 | <key>RubberWindowFrame</key> | ||
1138 | <string>743 379 452 308 0 0 1280 1002 </string> | ||
1139 | <key>TableConfiguration</key> | ||
1140 | <array> | ||
1141 | <string>Status</string> | ||
1142 | <real>30</real> | ||
1143 | <string>FileName</string> | ||
1144 | <real>199</real> | ||
1145 | <string>Path</string> | ||
1146 | <real>197.09500122070312</real> | ||
1147 | </array> | ||
1148 | <key>TableFrame</key> | ||
1149 | <string>{{0, 0}, {452, 250}}</string> | ||
1150 | </dict> | ||
1151 | <key>Module</key> | ||
1152 | <string>PBXCVSModule</string> | ||
1153 | <key>Proportion</key> | ||
1154 | <string>262pt</string> | ||
1155 | </dict> | ||
1156 | </array> | ||
1157 | <key>Proportion</key> | ||
1158 | <string>266pt</string> | ||
1159 | </dict> | ||
1160 | </array> | ||
1161 | <key>Name</key> | ||
1162 | <string>SCM</string> | ||
1163 | <key>ServiceClasses</key> | ||
1164 | <array> | ||
1165 | <string>PBXCVSModule</string> | ||
1166 | </array> | ||
1167 | <key>StatusbarIsVisible</key> | ||
1168 | <integer>1</integer> | ||
1169 | <key>TableOfContents</key> | ||
1170 | <array> | ||
1171 | <string>1C78EAB4065D492600B07095</string> | ||
1172 | <string>1C78EAB5065D492600B07095</string> | ||
1173 | <string>1C78EAB2065D492600B07095</string> | ||
1174 | <string>1CD052920623707200166675</string> | ||
1175 | </array> | ||
1176 | <key>ToolbarConfiguration</key> | ||
1177 | <string>xcode.toolbar.config.scm</string> | ||
1178 | <key>WindowString</key> | ||
1179 | <string>743 379 452 308 0 0 1280 1002 </string> | ||
1180 | </dict> | ||
1181 | <dict> | ||
1182 | <key>FirstTimeWindowDisplayed</key> | ||
1183 | <false/> | ||
1184 | <key>Identifier</key> | ||
1185 | <string>windowTool.breakpoints</string> | ||
1186 | <key>IsVertical</key> | ||
1187 | <false/> | ||
1188 | <key>Layout</key> | ||
1189 | <array> | ||
1190 | <dict> | ||
1191 | <key>Dock</key> | ||
1192 | <array> | ||
1193 | <dict> | ||
1194 | <key>BecomeActive</key> | ||
1195 | <true/> | ||
1196 | <key>ContentConfiguration</key> | ||
1197 | <dict> | ||
1198 | <key>PBXBottomSmartGroupGIDs</key> | ||
1199 | <array> | ||
1200 | <string>1C77FABC04509CD000000102</string> | ||
1201 | </array> | ||
1202 | <key>PBXProjectModuleGUID</key> | ||
1203 | <string>1CE0B1FE06471DED0097A5F4</string> | ||
1204 | <key>PBXProjectModuleLabel</key> | ||
1205 | <string>Files</string> | ||
1206 | <key>PBXProjectStructureProvided</key> | ||
1207 | <string>no</string> | ||
1208 | <key>PBXSmartGroupTreeModuleColumnData</key> | ||
1209 | <dict> | ||
1210 | <key>PBXSmartGroupTreeModuleColumnWidthsKey</key> | ||
1211 | <array> | ||
1212 | <real>168</real> | ||
1213 | </array> | ||
1214 | <key>PBXSmartGroupTreeModuleColumnsKey_v4</key> | ||
1215 | <array> | ||
1216 | <string>MainColumn</string> | ||
1217 | </array> | ||
1218 | </dict> | ||
1219 | <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key> | ||
1220 | <dict> | ||
1221 | <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key> | ||
1222 | <array> | ||
1223 | <string>1C77FABC04509CD000000102</string> | ||
1224 | <string>1C3E0DCA080725EA00A55177</string> | ||
1225 | </array> | ||
1226 | <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key> | ||
1227 | <array> | ||
1228 | <array> | ||
1229 | <integer>1</integer> | ||
1230 | <integer>0</integer> | ||
1231 | </array> | ||
1232 | </array> | ||
1233 | <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key> | ||
1234 | <string>{{0, 0}, {168, 365}}</string> | ||
1235 | </dict> | ||
1236 | <key>PBXTopSmartGroupGIDs</key> | ||
1237 | <array/> | ||
1238 | <key>XCIncludePerspectivesSwitch</key> | ||
1239 | <false/> | ||
1240 | </dict> | ||
1241 | <key>GeometryConfiguration</key> | ||
1242 | <dict> | ||
1243 | <key>Frame</key> | ||
1244 | <string>{{0, 0}, {185, 383}}</string> | ||
1245 | <key>GroupTreeTableConfiguration</key> | ||
1246 | <array> | ||
1247 | <string>MainColumn</string> | ||
1248 | <real>168</real> | ||
1249 | </array> | ||
1250 | <key>RubberWindowFrame</key> | ||
1251 | <string>713 435 871 424 0 0 1680 1028 </string> | ||
1252 | </dict> | ||
1253 | <key>Module</key> | ||
1254 | <string>PBXSmartGroupTreeModule</string> | ||
1255 | <key>Proportion</key> | ||
1256 | <string>185pt</string> | ||
1257 | </dict> | ||
1258 | <dict> | ||
1259 | <key>ContentConfiguration</key> | ||
1260 | <dict> | ||
1261 | <key>PBXProjectModuleGUID</key> | ||
1262 | <string>1CA1AED706398EBD00589147</string> | ||
1263 | <key>PBXProjectModuleLabel</key> | ||
1264 | <string>Detail</string> | ||
1265 | </dict> | ||
1266 | <key>GeometryConfiguration</key> | ||
1267 | <dict> | ||
1268 | <key>Frame</key> | ||
1269 | <string>{{190, 0}, {681, 383}}</string> | ||
1270 | <key>RubberWindowFrame</key> | ||
1271 | <string>713 435 871 424 0 0 1680 1028 </string> | ||
1272 | </dict> | ||
1273 | <key>Module</key> | ||
1274 | <string>XCDetailModule</string> | ||
1275 | <key>Proportion</key> | ||
1276 | <string>681pt</string> | ||
1277 | </dict> | ||
1278 | </array> | ||
1279 | <key>Proportion</key> | ||
1280 | <string>383pt</string> | ||
1281 | </dict> | ||
1282 | </array> | ||
1283 | <key>MajorVersion</key> | ||
1284 | <integer>2</integer> | ||
1285 | <key>MinorVersion</key> | ||
1286 | <integer>0</integer> | ||
1287 | <key>Name</key> | ||
1288 | <string>Breakpoints</string> | ||
1289 | <key>ServiceClasses</key> | ||
1290 | <array> | ||
1291 | <string>PBXSmartGroupTreeModule</string> | ||
1292 | <string>XCDetailModule</string> | ||
1293 | </array> | ||
1294 | <key>StatusbarIsVisible</key> | ||
1295 | <true/> | ||
1296 | <key>TableOfContents</key> | ||
1297 | <array> | ||
1298 | <string>271333C40C4602BB005FEE0E</string> | ||
1299 | <string>271333C50C4602BB005FEE0E</string> | ||
1300 | <string>1CE0B1FE06471DED0097A5F4</string> | ||
1301 | <string>1CA1AED706398EBD00589147</string> | ||
1302 | </array> | ||
1303 | <key>ToolbarConfiguration</key> | ||
1304 | <string>xcode.toolbar.config.breakpoints</string> | ||
1305 | <key>WindowString</key> | ||
1306 | <string>713 435 871 424 0 0 1680 1028 </string> | ||
1307 | <key>WindowToolGUID</key> | ||
1308 | <string>271333C40C4602BB005FEE0E</string> | ||
1309 | <key>WindowToolIsVisible</key> | ||
1310 | <false/> | ||
1311 | </dict> | ||
1312 | <dict> | ||
1313 | <key>Identifier</key> | ||
1314 | <string>windowTool.debugAnimator</string> | ||
1315 | <key>Layout</key> | ||
1316 | <array> | ||
1317 | <dict> | ||
1318 | <key>Dock</key> | ||
1319 | <array> | ||
1320 | <dict> | ||
1321 | <key>Module</key> | ||
1322 | <string>PBXNavigatorGroup</string> | ||
1323 | <key>Proportion</key> | ||
1324 | <string>100%</string> | ||
1325 | </dict> | ||
1326 | </array> | ||
1327 | <key>Proportion</key> | ||
1328 | <string>100%</string> | ||
1329 | </dict> | ||
1330 | </array> | ||
1331 | <key>Name</key> | ||
1332 | <string>Debug Visualizer</string> | ||
1333 | <key>ServiceClasses</key> | ||
1334 | <array> | ||
1335 | <string>PBXNavigatorGroup</string> | ||
1336 | </array> | ||
1337 | <key>StatusbarIsVisible</key> | ||
1338 | <integer>1</integer> | ||
1339 | <key>ToolbarConfiguration</key> | ||
1340 | <string>xcode.toolbar.config.debugAnimator</string> | ||
1341 | <key>WindowString</key> | ||
1342 | <string>100 100 700 500 0 0 1280 1002 </string> | ||
1343 | </dict> | ||
1344 | <dict> | ||
1345 | <key>Identifier</key> | ||
1346 | <string>windowTool.bookmarks</string> | ||
1347 | <key>Layout</key> | ||
1348 | <array> | ||
1349 | <dict> | ||
1350 | <key>Dock</key> | ||
1351 | <array> | ||
1352 | <dict> | ||
1353 | <key>Module</key> | ||
1354 | <string>PBXBookmarksModule</string> | ||
1355 | <key>Proportion</key> | ||
1356 | <string>100%</string> | ||
1357 | </dict> | ||
1358 | </array> | ||
1359 | <key>Proportion</key> | ||
1360 | <string>100%</string> | ||
1361 | </dict> | ||
1362 | </array> | ||
1363 | <key>Name</key> | ||
1364 | <string>Bookmarks</string> | ||
1365 | <key>ServiceClasses</key> | ||
1366 | <array> | ||
1367 | <string>PBXBookmarksModule</string> | ||
1368 | </array> | ||
1369 | <key>StatusbarIsVisible</key> | ||
1370 | <integer>0</integer> | ||
1371 | <key>WindowString</key> | ||
1372 | <string>538 42 401 187 0 0 1280 1002 </string> | ||
1373 | </dict> | ||
1374 | <dict> | ||
1375 | <key>Identifier</key> | ||
1376 | <string>windowTool.classBrowser</string> | ||
1377 | <key>Layout</key> | ||
1378 | <array> | ||
1379 | <dict> | ||
1380 | <key>Dock</key> | ||
1381 | <array> | ||
1382 | <dict> | ||
1383 | <key>BecomeActive</key> | ||
1384 | <integer>1</integer> | ||
1385 | <key>ContentConfiguration</key> | ||
1386 | <dict> | ||
1387 | <key>OptionsSetName</key> | ||
1388 | <string>Hierarchy, all classes</string> | ||
1389 | <key>PBXProjectModuleGUID</key> | ||
1390 | <string>1CA6456E063B45B4001379D8</string> | ||
1391 | <key>PBXProjectModuleLabel</key> | ||
1392 | <string>Class Browser - NSObject</string> | ||
1393 | </dict> | ||
1394 | <key>GeometryConfiguration</key> | ||
1395 | <dict> | ||
1396 | <key>ClassesFrame</key> | ||
1397 | <string>{{0, 0}, {374, 96}}</string> | ||
1398 | <key>ClassesTreeTableConfiguration</key> | ||
1399 | <array> | ||
1400 | <string>PBXClassNameColumnIdentifier</string> | ||
1401 | <real>208</real> | ||
1402 | <string>PBXClassBookColumnIdentifier</string> | ||
1403 | <real>22</real> | ||
1404 | </array> | ||
1405 | <key>Frame</key> | ||
1406 | <string>{{0, 0}, {630, 331}}</string> | ||
1407 | <key>MembersFrame</key> | ||
1408 | <string>{{0, 105}, {374, 395}}</string> | ||
1409 | <key>MembersTreeTableConfiguration</key> | ||
1410 | <array> | ||
1411 | <string>PBXMemberTypeIconColumnIdentifier</string> | ||
1412 | <real>22</real> | ||
1413 | <string>PBXMemberNameColumnIdentifier</string> | ||
1414 | <real>216</real> | ||
1415 | <string>PBXMemberTypeColumnIdentifier</string> | ||
1416 | <real>97</real> | ||
1417 | <string>PBXMemberBookColumnIdentifier</string> | ||
1418 | <real>22</real> | ||
1419 | </array> | ||
1420 | <key>PBXModuleWindowStatusBarHidden2</key> | ||
1421 | <integer>1</integer> | ||
1422 | <key>RubberWindowFrame</key> | ||
1423 | <string>385 179 630 352 0 0 1440 878 </string> | ||
1424 | </dict> | ||
1425 | <key>Module</key> | ||
1426 | <string>PBXClassBrowserModule</string> | ||
1427 | <key>Proportion</key> | ||
1428 | <string>332pt</string> | ||
1429 | </dict> | ||
1430 | </array> | ||
1431 | <key>Proportion</key> | ||
1432 | <string>332pt</string> | ||
1433 | </dict> | ||
1434 | </array> | ||
1435 | <key>Name</key> | ||
1436 | <string>Class Browser</string> | ||
1437 | <key>ServiceClasses</key> | ||
1438 | <array> | ||
1439 | <string>PBXClassBrowserModule</string> | ||
1440 | </array> | ||
1441 | <key>StatusbarIsVisible</key> | ||
1442 | <integer>0</integer> | ||
1443 | <key>TableOfContents</key> | ||
1444 | <array> | ||
1445 | <string>1C0AD2AF069F1E9B00FABCE6</string> | ||
1446 | <string>1C0AD2B0069F1E9B00FABCE6</string> | ||
1447 | <string>1CA6456E063B45B4001379D8</string> | ||
1448 | </array> | ||
1449 | <key>ToolbarConfiguration</key> | ||
1450 | <string>xcode.toolbar.config.classbrowser</string> | ||
1451 | <key>WindowString</key> | ||
1452 | <string>385 179 630 352 0 0 1440 878 </string> | ||
1453 | <key>WindowToolGUID</key> | ||
1454 | <string>1C0AD2AF069F1E9B00FABCE6</string> | ||
1455 | <key>WindowToolIsVisible</key> | ||
1456 | <integer>0</integer> | ||
1457 | </dict> | ||
1458 | </array> | ||
1459 | </dict> | ||
1460 | </plist> | ||
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 @@ | |||
1 | // !$*UTF8*$! | ||
2 | { | ||
3 | 08FB7793FE84155DC02AAC07 /* Project object */ = { | ||
4 | activeArchitecture = ppc; | ||
5 | activeBuildConfigurationName = Debug; | ||
6 | activeExecutable = 274A5EFC0C2F41FB000A66CF /* Lua 5.1 */; | ||
7 | activeTarget = D2AAC0620554660B00DB518D /* xcode */; | ||
8 | addToTargets = ( | ||
9 | D2AAC0620554660B00DB518D /* xcode */, | ||
10 | ); | ||
11 | breakpoints = ( | ||
12 | 27280DE10C495CCB000FD317 /* gluax_static.c:667 */, | ||
13 | 27280DE60C495D0C000FD317 /* gluax_static.c:663 */, | ||
14 | 27E802B50C4978C700B1E216 /* sdl_module.cpp:630 */, | ||
15 | 277CF6980C4A631C0044B79E /* gluax.c:2476 */, | ||
16 | 2784DBE20CD64B1000B13CF3 /* gluax_static.c:164 */, | ||
17 | 273631630CD71FBC00A12F3E /* lanes.c:1429 */, | ||
18 | 27BD9DD60E403B490056C472 /* lanes.c:1168 */, | ||
19 | 27BD9DEB0E403C250056C472 /* lanes.c:1246 */, | ||
20 | ); | ||
21 | codeSenseManager = 27602E610C2F36D60086E627 /* Code sense */; | ||
22 | executables = ( | ||
23 | 274A5EFC0C2F41FB000A66CF /* Lua 5.1 */, | ||
24 | ); | ||
25 | perUserDictionary = { | ||
26 | "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = { | ||
27 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; | ||
28 | PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID; | ||
29 | PBXFileTableDataSourceColumnWidthsKey = ( | ||
30 | 20, | ||
31 | 20, | ||
32 | 253, | ||
33 | 20, | ||
34 | 152, | ||
35 | 151, | ||
36 | 20, | ||
37 | ); | ||
38 | PBXFileTableDataSourceColumnsKey = ( | ||
39 | PBXBreakpointsDataSource_ActionID, | ||
40 | PBXBreakpointsDataSource_TypeID, | ||
41 | PBXBreakpointsDataSource_BreakpointID, | ||
42 | PBXBreakpointsDataSource_UseID, | ||
43 | PBXBreakpointsDataSource_LocationID, | ||
44 | PBXBreakpointsDataSource_ConditionID, | ||
45 | PBXBreakpointsDataSource_ContinueID, | ||
46 | ); | ||
47 | }; | ||
48 | PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { | ||
49 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; | ||
50 | PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; | ||
51 | PBXFileTableDataSourceColumnWidthsKey = ( | ||
52 | 22, | ||
53 | 300, | ||
54 | 304, | ||
55 | ); | ||
56 | PBXFileTableDataSourceColumnsKey = ( | ||
57 | PBXExecutablesDataSource_ActiveFlagID, | ||
58 | PBXExecutablesDataSource_NameID, | ||
59 | PBXExecutablesDataSource_CommentsID, | ||
60 | ); | ||
61 | }; | ||
62 | PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { | ||
63 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; | ||
64 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; | ||
65 | PBXFileTableDataSourceColumnWidthsKey = ( | ||
66 | 20, | ||
67 | 416, | ||
68 | 20, | ||
69 | 48, | ||
70 | 43, | ||
71 | 43, | ||
72 | 20, | ||
73 | ); | ||
74 | PBXFileTableDataSourceColumnsKey = ( | ||
75 | PBXFileDataSource_FiletypeID, | ||
76 | PBXFileDataSource_Filename_ColumnID, | ||
77 | PBXFileDataSource_Built_ColumnID, | ||
78 | PBXFileDataSource_ObjectSize_ColumnID, | ||
79 | PBXFileDataSource_Errors_ColumnID, | ||
80 | PBXFileDataSource_Warnings_ColumnID, | ||
81 | PBXFileDataSource_Target_ColumnID, | ||
82 | ); | ||
83 | }; | ||
84 | PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { | ||
85 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; | ||
86 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; | ||
87 | PBXFileTableDataSourceColumnWidthsKey = ( | ||
88 | 20, | ||
89 | 200, | ||
90 | 230, | ||
91 | 20, | ||
92 | 48, | ||
93 | 43, | ||
94 | 43, | ||
95 | ); | ||
96 | PBXFileTableDataSourceColumnsKey = ( | ||
97 | PBXFileDataSource_FiletypeID, | ||
98 | PBXFileDataSource_Filename_ColumnID, | ||
99 | PBXTargetDataSource_PrimaryAttribute, | ||
100 | PBXFileDataSource_Built_ColumnID, | ||
101 | PBXFileDataSource_ObjectSize_ColumnID, | ||
102 | PBXFileDataSource_Errors_ColumnID, | ||
103 | PBXFileDataSource_Warnings_ColumnID, | ||
104 | ); | ||
105 | }; | ||
106 | PBXPerProjectTemplateStateSaveDate = 239090487; | ||
107 | PBXWorkspaceStateSaveDate = 239090487; | ||
108 | }; | ||
109 | perUserProjectItems = { | ||
110 | 27BD9DD90E403B640056C472 /* PBXTextBookmark */ = 27BD9DD90E403B640056C472 /* PBXTextBookmark */; | ||
111 | 27BD9DDA0E403B640056C472 /* PBXTextBookmark */ = 27BD9DDA0E403B640056C472 /* PBXTextBookmark */; | ||
112 | 27BD9DDB0E403B640056C472 /* PBXTextBookmark */ = 27BD9DDB0E403B640056C472 /* PBXTextBookmark */; | ||
113 | 27BD9DEE0E403C960056C472 /* PBXTextBookmark */ = 27BD9DEE0E403C960056C472 /* PBXTextBookmark */; | ||
114 | }; | ||
115 | sourceControlManager = 27602E600C2F36D60086E627 /* Source Control */; | ||
116 | userBuildSettings = { | ||
117 | }; | ||
118 | }; | ||
119 | 27280DE10C495CCB000FD317 /* gluax_static.c:667 */ = { | ||
120 | isa = PBXFileBreakpoint; | ||
121 | actions = ( | ||
122 | ); | ||
123 | breakpointStyle = 0; | ||
124 | continueAfterActions = 0; | ||
125 | countType = 0; | ||
126 | delayBeforeContinue = 0; | ||
127 | fileReference = 27602E620C2F37390086E627 /* gluax_static.c */; | ||
128 | hitCount = 0; | ||
129 | ignoreCount = 0; | ||
130 | lineNumber = 667; | ||
131 | modificationTime = 239090794.843809; | ||
132 | state = 1; | ||
133 | }; | ||
134 | 27280DE60C495D0C000FD317 /* gluax_static.c:663 */ = { | ||
135 | isa = PBXFileBreakpoint; | ||
136 | actions = ( | ||
137 | ); | ||
138 | breakpointStyle = 0; | ||
139 | continueAfterActions = 0; | ||
140 | countType = 0; | ||
141 | delayBeforeContinue = 0; | ||
142 | fileReference = 27602E620C2F37390086E627 /* gluax_static.c */; | ||
143 | hitCount = 0; | ||
144 | ignoreCount = 0; | ||
145 | lineNumber = 663; | ||
146 | modificationTime = 239090794.844094; | ||
147 | state = 1; | ||
148 | }; | ||
149 | 273631630CD71FBC00A12F3E /* lanes.c:1429 */ = { | ||
150 | isa = PBXFileBreakpoint; | ||
151 | actions = ( | ||
152 | ); | ||
153 | breakpointStyle = 0; | ||
154 | continueAfterActions = 0; | ||
155 | countType = 0; | ||
156 | delayBeforeContinue = 0; | ||
157 | fileReference = 279F2E690C4A463C0020A321 /* lanes.c */; | ||
158 | functionName = "GLUA_FUNC()"; | ||
159 | hitCount = 0; | ||
160 | ignoreCount = 0; | ||
161 | lineNumber = 1429; | ||
162 | modificationTime = 239090794.843223; | ||
163 | state = 1; | ||
164 | }; | ||
165 | 274A5EFC0C2F41FB000A66CF /* Lua 5.1 */ = { | ||
166 | isa = PBXExecutable; | ||
167 | activeArgIndices = ( | ||
168 | NO, | ||
169 | YES, | ||
170 | ); | ||
171 | argumentStrings = ( | ||
172 | "-lstrict ../fibonacci.lua", | ||
173 | tests/basic.lua, | ||
174 | ); | ||
175 | autoAttachOnCrash = 1; | ||
176 | breakpointsEnabled = 1; | ||
177 | configStateDict = { | ||
178 | "PBXLSLaunchAction-0" = { | ||
179 | PBXLSLaunchAction = 0; | ||
180 | PBXLSLaunchStartAction = 1; | ||
181 | PBXLSLaunchStdioStyle = 2; | ||
182 | PBXLSLaunchStyle = 0; | ||
183 | class = PBXLSRunLaunchConfig; | ||
184 | commandLineArgs = ( | ||
185 | ); | ||
186 | displayName = "Executable Runner"; | ||
187 | environment = { | ||
188 | }; | ||
189 | identifier = com.apple.Xcode.launch.runConfig; | ||
190 | remoteHostInfo = ""; | ||
191 | startActionInfo = ""; | ||
192 | }; | ||
193 | }; | ||
194 | customDataFormattersEnabled = 1; | ||
195 | debuggerPlugin = GDBDebugging; | ||
196 | disassemblyDisplayState = 0; | ||
197 | dylibVariantSuffix = ""; | ||
198 | enableDebugStr = 1; | ||
199 | environmentEntries = ( | ||
200 | { | ||
201 | active = YES; | ||
202 | name = LUA_PATH; | ||
203 | value = "src/?.lua;/sw/share/lua/5.1/?.lua"; | ||
204 | }, | ||
205 | { | ||
206 | active = YES; | ||
207 | name = LUA_CPATH; | ||
208 | value = "xcode/build/Debug/lib?.bundle"; | ||
209 | }, | ||
210 | ); | ||
211 | executableSystemSymbolLevel = 0; | ||
212 | executableUserSymbolLevel = 0; | ||
213 | launchableReference = 274A5EFD0C2F41FB000A66CF /* lua */; | ||
214 | libgmallocEnabled = 0; | ||
215 | name = "Lua 5.1"; | ||
216 | savedGlobals = { | ||
217 | }; | ||
218 | sourceDirectories = ( | ||
219 | ); | ||
220 | startupPath = /Users/abisoft/Slug/public/2008/Lanes/; | ||
221 | variableFormatDictionary = { | ||
222 | }; | ||
223 | }; | ||
224 | 274A5EFD0C2F41FB000A66CF /* lua */ = { | ||
225 | isa = PBXFileReference; | ||
226 | explicitFileType = "compiled.mach-o.executable"; | ||
227 | name = lua; | ||
228 | path = /sw/bin/lua; | ||
229 | sourceTree = "<absolute>"; | ||
230 | }; | ||
231 | 27602E600C2F36D60086E627 /* Source Control */ = { | ||
232 | isa = PBXSourceControlManager; | ||
233 | fallbackIsa = XCSourceControlManager; | ||
234 | isSCMEnabled = 0; | ||
235 | scmConfiguration = { | ||
236 | }; | ||
237 | scmType = ""; | ||
238 | }; | ||
239 | 27602E610C2F36D60086E627 /* Code sense */ = { | ||
240 | isa = PBXCodeSenseManager; | ||
241 | indexTemplatePath = ""; | ||
242 | }; | ||
243 | 27602E620C2F37390086E627 /* gluax_static.c */ = { | ||
244 | isa = PBXFileReference; | ||
245 | fileEncoding = 30; | ||
246 | lastKnownFileType = sourcecode.c.c; | ||
247 | name = gluax_static.c; | ||
248 | path = /Users/abisoft/Slug/public/2008/gluax/gluax_static.c; | ||
249 | sourceTree = "<absolute>"; | ||
250 | }; | ||
251 | 27602E640C2F37390086E627 /* gluax.c */ = { | ||
252 | isa = PBXFileReference; | ||
253 | fileEncoding = 30; | ||
254 | lastKnownFileType = sourcecode.c.c; | ||
255 | name = gluax.c; | ||
256 | path = /Users/abisoft/Slug/public/2008/gluax/gluax.c; | ||
257 | sourceTree = "<absolute>"; | ||
258 | }; | ||
259 | 27602E660C2F37390086E627 /* sdl_module.cpp */ = { | ||
260 | isa = PBXFileReference; | ||
261 | fileEncoding = 30; | ||
262 | lastKnownFileType = sourcecode.cpp.cpp; | ||
263 | name = sdl_module.cpp; | ||
264 | path = /Users/abisoft/Slug/public/2007/Lanes/sdl_module.cpp; | ||
265 | sourceTree = "<absolute>"; | ||
266 | }; | ||
267 | 277CF6980C4A631C0044B79E /* gluax.c:2476 */ = { | ||
268 | isa = PBXFileBreakpoint; | ||
269 | actions = ( | ||
270 | ); | ||
271 | breakpointStyle = 0; | ||
272 | continueAfterActions = 0; | ||
273 | countType = 0; | ||
274 | delayBeforeContinue = 0; | ||
275 | fileReference = 27602E640C2F37390086E627 /* gluax.c */; | ||
276 | hitCount = 0; | ||
277 | ignoreCount = 0; | ||
278 | lineNumber = 2476; | ||
279 | modificationTime = 239090794.84353; | ||
280 | state = 1; | ||
281 | }; | ||
282 | 2784DBE20CD64B1000B13CF3 /* gluax_static.c:164 */ = { | ||
283 | isa = PBXFileBreakpoint; | ||
284 | actions = ( | ||
285 | ); | ||
286 | breakpointStyle = 0; | ||
287 | continueAfterActions = 0; | ||
288 | countType = 0; | ||
289 | delayBeforeContinue = 0; | ||
290 | fileReference = 27602E620C2F37390086E627 /* gluax_static.c */; | ||
291 | functionName = "Loc_PushMetatableRef_()"; | ||
292 | hitCount = 0; | ||
293 | ignoreCount = 0; | ||
294 | lineNumber = 164; | ||
295 | modificationTime = 239090794.842868; | ||
296 | state = 1; | ||
297 | }; | ||
298 | 279F2E690C4A463C0020A321 /* lanes.c */ = { | ||
299 | isa = PBXFileReference; | ||
300 | fileEncoding = 30; | ||
301 | lastKnownFileType = sourcecode.c.c; | ||
302 | name = lanes.c; | ||
303 | path = /Users/abisoft/Slug/public/2008/Lanes/lanes.c; | ||
304 | sourceTree = "<absolute>"; | ||
305 | }; | ||
306 | 27ACDA660E4031F6004F5C28 /* lanes.c */ = { | ||
307 | uiCtxt = { | ||
308 | sepNavIntBoundsRect = "{{0, 0}, {822, 17500}}"; | ||
309 | sepNavSelRange = "{31197, 0}"; | ||
310 | sepNavVisRange = "{30733, 1064}"; | ||
311 | sepNavWindowFrame = "{{86, 51}, {1052, 971}}"; | ||
312 | }; | ||
313 | }; | ||
314 | 27ACDA680E4031F6004F5C28 /* tools.c */ = { | ||
315 | uiCtxt = { | ||
316 | sepNavIntBoundsRect = "{{0, 0}, {594, 13790}}"; | ||
317 | sepNavSelRange = "{0, 0}"; | ||
318 | sepNavVisRange = "{0, 1259}"; | ||
319 | }; | ||
320 | }; | ||
321 | 27BD9DD60E403B490056C472 /* lanes.c:1168 */ = { | ||
322 | isa = PBXFileBreakpoint; | ||
323 | actions = ( | ||
324 | ); | ||
325 | breakpointStyle = 0; | ||
326 | continueAfterActions = 0; | ||
327 | countType = 0; | ||
328 | delayBeforeContinue = 0; | ||
329 | fileReference = 27ACDA660E4031F6004F5C28 /* lanes.c */; | ||
330 | functionName = "luaopen_lanes()"; | ||
331 | hitCount = 1; | ||
332 | ignoreCount = 0; | ||
333 | lineNumber = 1168; | ||
334 | location = "liblua51-lanes.bundle"; | ||
335 | modificationTime = 239090520.812976; | ||
336 | state = 1; | ||
337 | }; | ||
338 | 27BD9DD90E403B640056C472 /* PBXTextBookmark */ = { | ||
339 | isa = PBXTextBookmark; | ||
340 | fRef = 27ACDA680E4031F6004F5C28 /* tools.c */; | ||
341 | name = "tools.c: 1"; | ||
342 | rLen = 0; | ||
343 | rLoc = 0; | ||
344 | rType = 0; | ||
345 | vrLen = 1259; | ||
346 | vrLoc = 0; | ||
347 | }; | ||
348 | 27BD9DDA0E403B640056C472 /* PBXTextBookmark */ = { | ||
349 | isa = PBXTextBookmark; | ||
350 | fRef = 27ACDA660E4031F6004F5C28 /* lanes.c */; | ||
351 | rLen = 0; | ||
352 | rLoc = 1167; | ||
353 | rType = 1; | ||
354 | }; | ||
355 | 27BD9DDB0E403B640056C472 /* PBXTextBookmark */ = { | ||
356 | isa = PBXTextBookmark; | ||
357 | fRef = 27ACDA680E4031F6004F5C28 /* tools.c */; | ||
358 | name = "tools.c: 1"; | ||
359 | rLen = 0; | ||
360 | rLoc = 0; | ||
361 | rType = 0; | ||
362 | vrLen = 1259; | ||
363 | vrLoc = 0; | ||
364 | }; | ||
365 | 27BD9DEB0E403C250056C472 /* lanes.c:1246 */ = { | ||
366 | isa = PBXFileBreakpoint; | ||
367 | actions = ( | ||
368 | ); | ||
369 | breakpointStyle = 0; | ||
370 | continueAfterActions = 0; | ||
371 | countType = 0; | ||
372 | delayBeforeContinue = 0; | ||
373 | fileReference = 27ACDA660E4031F6004F5C28 /* lanes.c */; | ||
374 | functionName = "luaopen_lanes()"; | ||
375 | hitCount = 0; | ||
376 | ignoreCount = 0; | ||
377 | lineNumber = 1246; | ||
378 | location = "liblua51-lanes.bundle"; | ||
379 | modificationTime = 239090725.673196; | ||
380 | state = 1; | ||
381 | }; | ||
382 | 27BD9DEE0E403C960056C472 /* PBXTextBookmark */ = { | ||
383 | isa = PBXTextBookmark; | ||
384 | fRef = 27ACDA660E4031F6004F5C28 /* lanes.c */; | ||
385 | name = "lanes.c: 1168"; | ||
386 | rLen = 0; | ||
387 | rLoc = 31197; | ||
388 | rType = 0; | ||
389 | vrLen = 1064; | ||
390 | vrLoc = 30733; | ||
391 | }; | ||
392 | 27E802B50C4978C700B1E216 /* sdl_module.cpp:630 */ = { | ||
393 | isa = PBXFileBreakpoint; | ||
394 | actions = ( | ||
395 | ); | ||
396 | breakpointStyle = 0; | ||
397 | continueAfterActions = 0; | ||
398 | countType = 0; | ||
399 | delayBeforeContinue = 0; | ||
400 | fileReference = 27602E660C2F37390086E627 /* sdl_module.cpp */; | ||
401 | functionName = "GLUA_FUNC()"; | ||
402 | hitCount = 0; | ||
403 | ignoreCount = 0; | ||
404 | lineNumber = 630; | ||
405 | modificationTime = 239090794.842249; | ||
406 | state = 1; | ||
407 | }; | ||
408 | D2AAC0620554660B00DB518D /* xcode */ = { | ||
409 | activeExec = 0; | ||
410 | }; | ||
411 | } | ||
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 @@ | |||
1 | // !$*UTF8*$! | ||
2 | { | ||
3 | archiveVersion = 1; | ||
4 | classes = { | ||
5 | }; | ||
6 | objectVersion = 42; | ||
7 | objects = { | ||
8 | |||
9 | /* Begin PBXBuildFile section */ | ||
10 | 27602E840C2F3CA40086E627 /* liblua.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 27602E830C2F3CA40086E627 /* liblua.dylib */; }; | ||
11 | 27ACDA690E4031F6004F5C28 /* lanes.c in Sources */ = {isa = PBXBuildFile; fileRef = 27ACDA660E4031F6004F5C28 /* lanes.c */; }; | ||
12 | 27ACDA6A0E4031F6004F5C28 /* threading.c in Sources */ = {isa = PBXBuildFile; fileRef = 27ACDA670E4031F6004F5C28 /* threading.c */; }; | ||
13 | 27ACDA6B0E4031F6004F5C28 /* tools.c in Sources */ = {isa = PBXBuildFile; fileRef = 27ACDA680E4031F6004F5C28 /* tools.c */; }; | ||
14 | /* End PBXBuildFile section */ | ||
15 | |||
16 | /* Begin PBXFileReference section */ | ||
17 | 27602E830C2F3CA40086E627 /* liblua.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = liblua.dylib; path = /sw/lib/liblua.dylib; sourceTree = "<absolute>"; }; | ||
18 | 279F2E7B0C4A477B0020A321 /* liblua51-lanes.bundle */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "liblua51-lanes.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
19 | 27ACDA660E4031F6004F5C28 /* lanes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lanes.c; path = ../src/lanes.c; sourceTree = SOURCE_ROOT; }; | ||
20 | 27ACDA670E4031F6004F5C28 /* threading.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = threading.c; path = ../src/threading.c; sourceTree = SOURCE_ROOT; }; | ||
21 | 27ACDA680E4031F6004F5C28 /* tools.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tools.c; path = ../src/tools.c; sourceTree = SOURCE_ROOT; }; | ||
22 | /* End PBXFileReference section */ | ||
23 | |||
24 | /* Begin PBXFrameworksBuildPhase section */ | ||
25 | D289988505E68E00004EDB86 /* Frameworks */ = { | ||
26 | isa = PBXFrameworksBuildPhase; | ||
27 | buildActionMask = 2147483647; | ||
28 | files = ( | ||
29 | 27602E840C2F3CA40086E627 /* liblua.dylib in Frameworks */, | ||
30 | ); | ||
31 | runOnlyForDeploymentPostprocessing = 0; | ||
32 | }; | ||
33 | /* End PBXFrameworksBuildPhase section */ | ||
34 | |||
35 | /* Begin PBXGroup section */ | ||
36 | 08FB7794FE84155DC02AAC07 /* xcode */ = { | ||
37 | isa = PBXGroup; | ||
38 | children = ( | ||
39 | 27602E830C2F3CA40086E627 /* liblua.dylib */, | ||
40 | 08FB7795FE84155DC02AAC07 /* Source */, | ||
41 | 1AB674ADFE9D54B511CA2CBB /* Products */, | ||
42 | ); | ||
43 | 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"; | ||
44 | name = xcode; | ||
45 | sourceTree = "<group>"; | ||
46 | }; | ||
47 | 08FB7795FE84155DC02AAC07 /* Source */ = { | ||
48 | isa = PBXGroup; | ||
49 | children = ( | ||
50 | 27ACDA660E4031F6004F5C28 /* lanes.c */, | ||
51 | 27ACDA670E4031F6004F5C28 /* threading.c */, | ||
52 | 27ACDA680E4031F6004F5C28 /* tools.c */, | ||
53 | ); | ||
54 | name = Source; | ||
55 | sourceTree = "<group>"; | ||
56 | }; | ||
57 | 1AB674ADFE9D54B511CA2CBB /* Products */ = { | ||
58 | isa = PBXGroup; | ||
59 | children = ( | ||
60 | 279F2E7B0C4A477B0020A321 /* liblua51-lanes.bundle */, | ||
61 | ); | ||
62 | name = Products; | ||
63 | sourceTree = "<group>"; | ||
64 | }; | ||
65 | /* End PBXGroup section */ | ||
66 | |||
67 | /* Begin PBXHeadersBuildPhase section */ | ||
68 | D2AAC0600554660B00DB518D /* Headers */ = { | ||
69 | isa = PBXHeadersBuildPhase; | ||
70 | buildActionMask = 2147483647; | ||
71 | files = ( | ||
72 | ); | ||
73 | runOnlyForDeploymentPostprocessing = 0; | ||
74 | }; | ||
75 | /* End PBXHeadersBuildPhase section */ | ||
76 | |||
77 | /* Begin PBXNativeTarget section */ | ||
78 | D2AAC0620554660B00DB518D /* xcode */ = { | ||
79 | isa = PBXNativeTarget; | ||
80 | buildConfigurationList = 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "xcode" */; | ||
81 | buildPhases = ( | ||
82 | D2AAC0600554660B00DB518D /* Headers */, | ||
83 | D2AAC0610554660B00DB518D /* Sources */, | ||
84 | D289988505E68E00004EDB86 /* Frameworks */, | ||
85 | ); | ||
86 | buildRules = ( | ||
87 | ); | ||
88 | dependencies = ( | ||
89 | ); | ||
90 | name = xcode; | ||
91 | productName = xcode; | ||
92 | productReference = 279F2E7B0C4A477B0020A321 /* liblua51-lanes.bundle */; | ||
93 | productType = "com.apple.product-type.library.dynamic"; | ||
94 | }; | ||
95 | /* End PBXNativeTarget section */ | ||
96 | |||
97 | /* Begin PBXProject section */ | ||
98 | 08FB7793FE84155DC02AAC07 /* Project object */ = { | ||
99 | isa = PBXProject; | ||
100 | buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "xcode" */; | ||
101 | compatibilityVersion = "Xcode 2.4"; | ||
102 | hasScannedForEncodings = 1; | ||
103 | mainGroup = 08FB7794FE84155DC02AAC07 /* xcode */; | ||
104 | projectDirPath = ""; | ||
105 | projectRoot = ""; | ||
106 | targets = ( | ||
107 | D2AAC0620554660B00DB518D /* xcode */, | ||
108 | ); | ||
109 | }; | ||
110 | /* End PBXProject section */ | ||
111 | |||
112 | /* Begin PBXSourcesBuildPhase section */ | ||
113 | D2AAC0610554660B00DB518D /* Sources */ = { | ||
114 | isa = PBXSourcesBuildPhase; | ||
115 | buildActionMask = 2147483647; | ||
116 | files = ( | ||
117 | 27ACDA690E4031F6004F5C28 /* lanes.c in Sources */, | ||
118 | 27ACDA6A0E4031F6004F5C28 /* threading.c in Sources */, | ||
119 | 27ACDA6B0E4031F6004F5C28 /* tools.c in Sources */, | ||
120 | ); | ||
121 | runOnlyForDeploymentPostprocessing = 0; | ||
122 | }; | ||
123 | /* End PBXSourcesBuildPhase section */ | ||
124 | |||
125 | /* Begin XCBuildConfiguration section */ | ||
126 | 1DEB914B08733D8E0010E9CD /* Debug */ = { | ||
127 | isa = XCBuildConfiguration; | ||
128 | buildSettings = { | ||
129 | COPY_PHASE_STRIP = NO; | ||
130 | EXECUTABLE_PREFIX = lib; | ||
131 | GCC_DYNAMIC_NO_PIC = NO; | ||
132 | GCC_ENABLE_FIX_AND_CONTINUE = YES; | ||
133 | GCC_MODEL_TUNING = G5; | ||
134 | GCC_OPTIMIZATION_LEVEL = 0; | ||
135 | INSTALL_PATH = /usr/local/lib; | ||
136 | LIBRARY_SEARCH_PATHS = ( | ||
137 | "$(inherited)", | ||
138 | /sw/lib, | ||
139 | ); | ||
140 | PRODUCT_NAME = "lua51-lanes"; | ||
141 | ZERO_LINK = NO; | ||
142 | }; | ||
143 | name = Debug; | ||
144 | }; | ||
145 | 1DEB914C08733D8E0010E9CD /* Release */ = { | ||
146 | isa = XCBuildConfiguration; | ||
147 | buildSettings = { | ||
148 | ARCHS = ( | ||
149 | ppc, | ||
150 | i386, | ||
151 | ); | ||
152 | COPY_PHASE_STRIP = NO; | ||
153 | EXECUTABLE_PREFIX = lib; | ||
154 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; | ||
155 | GCC_MODEL_TUNING = G5; | ||
156 | INSTALL_PATH = /usr/local/lib; | ||
157 | LIBRARY_SEARCH_PATHS = ( | ||
158 | "$(inherited)", | ||
159 | /sw/lib, | ||
160 | ); | ||
161 | PRODUCT_NAME = "lua51-lanes"; | ||
162 | ZERO_LINK = NO; | ||
163 | }; | ||
164 | name = Release; | ||
165 | }; | ||
166 | 1DEB914F08733D8E0010E9CD /* Debug */ = { | ||
167 | isa = XCBuildConfiguration; | ||
168 | buildSettings = { | ||
169 | BUNDLE_LOADER = /sw/bin/lua; | ||
170 | DYLIB_COMPATIBILITY_VERSION = ""; | ||
171 | DYLIB_CURRENT_VERSION = ""; | ||
172 | EXECUTABLE_EXTENSION = bundle; | ||
173 | EXECUTABLE_PREFIX = ""; | ||
174 | GCC_ENABLE_CPP_EXCEPTIONS = NO; | ||
175 | GCC_ENABLE_CPP_RTTI = NO; | ||
176 | GCC_PREPROCESSOR_DEFINITIONS = ( | ||
177 | GLUA_LUA51, | ||
178 | "_GNU_SOURCE=1", | ||
179 | _THREAD_SAFE, | ||
180 | ); | ||
181 | GCC_WARN_ABOUT_RETURN_TYPE = YES; | ||
182 | GCC_WARN_PEDANTIC = NO; | ||
183 | GCC_WARN_UNUSED_VARIABLE = YES; | ||
184 | GENERATE_MASTER_OBJECT_FILE = YES; | ||
185 | HEADER_SEARCH_PATHS = ( | ||
186 | ../../gluax, | ||
187 | /sw/include, | ||
188 | ); | ||
189 | LIBRARY_SEARCH_PATHS = /sw/lib; | ||
190 | MACH_O_TYPE = mh_bundle; | ||
191 | OTHER_LDFLAGS = ( | ||
192 | "-framework", | ||
193 | Cocoa, | ||
194 | ); | ||
195 | PREBINDING = NO; | ||
196 | PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; | ||
197 | PRELINK_LIBS = ""; | ||
198 | PRODUCT_NAME = "lua51-lanes"; | ||
199 | SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; | ||
200 | SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; | ||
201 | SHARED_PRECOMPS_DIR = ""; | ||
202 | }; | ||
203 | name = Debug; | ||
204 | }; | ||
205 | 1DEB915008733D8E0010E9CD /* Release */ = { | ||
206 | isa = XCBuildConfiguration; | ||
207 | buildSettings = { | ||
208 | BUNDLE_LOADER = /sw/bin/lua; | ||
209 | DYLIB_COMPATIBILITY_VERSION = ""; | ||
210 | DYLIB_CURRENT_VERSION = ""; | ||
211 | EXECUTABLE_EXTENSION = bundle; | ||
212 | EXECUTABLE_PREFIX = ""; | ||
213 | GCC_ENABLE_CPP_EXCEPTIONS = NO; | ||
214 | GCC_ENABLE_CPP_RTTI = NO; | ||
215 | GCC_PREPROCESSOR_DEFINITIONS = ( | ||
216 | GLUA_LUA51, | ||
217 | "_GNU_SOURCE=1", | ||
218 | _THREAD_SAFE, | ||
219 | ); | ||
220 | GCC_WARN_ABOUT_RETURN_TYPE = YES; | ||
221 | GCC_WARN_PEDANTIC = NO; | ||
222 | GCC_WARN_UNUSED_VARIABLE = YES; | ||
223 | GENERATE_MASTER_OBJECT_FILE = YES; | ||
224 | HEADER_SEARCH_PATHS = ( | ||
225 | ../../gluax, | ||
226 | /sw/include, | ||
227 | ); | ||
228 | LIBRARY_SEARCH_PATHS = /sw/lib; | ||
229 | MACH_O_TYPE = mh_bundle; | ||
230 | OTHER_LDFLAGS = ( | ||
231 | "-framework", | ||
232 | Cocoa, | ||
233 | ); | ||
234 | PREBINDING = NO; | ||
235 | PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; | ||
236 | PRELINK_LIBS = ""; | ||
237 | PRODUCT_NAME = "lua51-lanes"; | ||
238 | SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; | ||
239 | SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; | ||
240 | SHARED_PRECOMPS_DIR = ""; | ||
241 | }; | ||
242 | name = Release; | ||
243 | }; | ||
244 | /* End XCBuildConfiguration section */ | ||
245 | |||
246 | /* Begin XCConfigurationList section */ | ||
247 | 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "xcode" */ = { | ||
248 | isa = XCConfigurationList; | ||
249 | buildConfigurations = ( | ||
250 | 1DEB914B08733D8E0010E9CD /* Debug */, | ||
251 | 1DEB914C08733D8E0010E9CD /* Release */, | ||
252 | ); | ||
253 | defaultConfigurationIsVisible = 0; | ||
254 | defaultConfigurationName = Release; | ||
255 | }; | ||
256 | 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "xcode" */ = { | ||
257 | isa = XCConfigurationList; | ||
258 | buildConfigurations = ( | ||
259 | 1DEB914F08733D8E0010E9CD /* Debug */, | ||
260 | 1DEB915008733D8E0010E9CD /* Release */, | ||
261 | ); | ||
262 | defaultConfigurationIsVisible = 0; | ||
263 | defaultConfigurationName = Release; | ||
264 | }; | ||
265 | /* End XCConfigurationList section */ | ||
266 | }; | ||
267 | rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; | ||
268 | } | ||
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 @@ | |||
1 | // !$*UTF8*$! | ||
2 | { | ||
3 | 0429C3740C416BB800EC1476 /* Source Control */ = { | ||
4 | isa = PBXSourceControlManager; | ||
5 | fallbackIsa = XCSourceControlManager; | ||
6 | isSCMEnabled = 0; | ||
7 | scmConfiguration = { | ||
8 | }; | ||
9 | scmType = ""; | ||
10 | }; | ||
11 | 0429C3750C416BB800EC1476 /* Code sense */ = { | ||
12 | isa = PBXCodeSenseManager; | ||
13 | indexTemplatePath = ""; | ||
14 | }; | ||
15 | 04C412EF0C42B7D500A0AD77 /* Lua */ = { | ||
16 | isa = PBXExecutable; | ||
17 | activeArgIndex = 0; | ||
18 | activeArgIndices = ( | ||
19 | YES, | ||
20 | ); | ||
21 | argumentStrings = ( | ||
22 | test.lua, | ||
23 | ); | ||
24 | autoAttachOnCrash = 1; | ||
25 | comments = "This is not stored in svn, is it?\n"; | ||
26 | configStateDict = { | ||
27 | "PBXLSLaunchAction-0" = { | ||
28 | PBXLSLaunchAction = 0; | ||
29 | PBXLSLaunchStartAction = 1; | ||
30 | PBXLSLaunchStdioStyle = 2; | ||
31 | PBXLSLaunchStyle = 0; | ||
32 | class = PBXLSRunLaunchConfig; | ||
33 | displayName = "Executable Runner"; | ||
34 | identifier = com.apple.Xcode.launch.runConfig; | ||
35 | remoteHostInfo = ""; | ||
36 | startActionInfo = ""; | ||
37 | }; | ||
38 | }; | ||
39 | customDataFormattersEnabled = 1; | ||
40 | debuggerPlugin = GDBDebugging; | ||
41 | disassemblyDisplayState = 0; | ||
42 | dylibVariantSuffix = ""; | ||
43 | enableDebugStr = 1; | ||
44 | environmentEntries = ( | ||
45 | { | ||
46 | active = YES; | ||
47 | name = LUA_CPATH; | ||
48 | value = "xcode/build/Debug/lib?.bundle"; | ||
49 | }, | ||
50 | ); | ||
51 | executableSystemSymbolLevel = 0; | ||
52 | executableUserSymbolLevel = 0; | ||
53 | launchableReference = 04C412F00C42B7D500A0AD77 /* lua */; | ||
54 | libgmallocEnabled = 0; | ||
55 | name = Lua; | ||
56 | savedGlobals = { | ||
57 | }; | ||
58 | sourceDirectories = ( | ||
59 | ); | ||
60 | startupPath = /Users/soumya/Slug/public/2007/SDL/; | ||
61 | }; | ||
62 | 04C412F00C42B7D500A0AD77 /* lua */ = { | ||
63 | isa = PBXFileReference; | ||
64 | explicitFileType = "compiled.mach-o.executable"; | ||
65 | name = lua; | ||
66 | path = /sw/bin/lua; | ||
67 | sourceTree = "<absolute>"; | ||
68 | }; | ||
69 | 08FB7793FE84155DC02AAC07 /* Project object */ = { | ||
70 | activeBuildConfigurationName = Debug; | ||
71 | activeExecutable = 04C412EF0C42B7D500A0AD77 /* Lua */; | ||
72 | activeTarget = D2AAC0620554660B00DB518D /* xcode */; | ||
73 | codeSenseManager = 0429C3750C416BB800EC1476 /* Code sense */; | ||
74 | executables = ( | ||
75 | 04C412EF0C42B7D500A0AD77 /* Lua */, | ||
76 | ); | ||
77 | perUserDictionary = { | ||
78 | PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { | ||
79 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; | ||
80 | PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; | ||
81 | PBXFileTableDataSourceColumnWidthsKey = ( | ||
82 | 22, | ||
83 | 300, | ||
84 | 225, | ||
85 | ); | ||
86 | PBXFileTableDataSourceColumnsKey = ( | ||
87 | PBXExecutablesDataSource_ActiveFlagID, | ||
88 | PBXExecutablesDataSource_NameID, | ||
89 | PBXExecutablesDataSource_CommentsID, | ||
90 | ); | ||
91 | }; | ||
92 | PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { | ||
93 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; | ||
94 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; | ||
95 | PBXFileTableDataSourceColumnWidthsKey = ( | ||
96 | 20, | ||
97 | 338, | ||
98 | 20, | ||
99 | 48, | ||
100 | 43, | ||
101 | 43, | ||
102 | 20, | ||
103 | ); | ||
104 | PBXFileTableDataSourceColumnsKey = ( | ||
105 | PBXFileDataSource_FiletypeID, | ||
106 | PBXFileDataSource_Filename_ColumnID, | ||
107 | PBXFileDataSource_Built_ColumnID, | ||
108 | PBXFileDataSource_ObjectSize_ColumnID, | ||
109 | PBXFileDataSource_Errors_ColumnID, | ||
110 | PBXFileDataSource_Warnings_ColumnID, | ||
111 | PBXFileDataSource_Target_ColumnID, | ||
112 | ); | ||
113 | }; | ||
114 | PBXPerProjectTemplateStateSaveDate = 205699730; | ||
115 | PBXWorkspaceStateSaveDate = 205699730; | ||
116 | }; | ||
117 | sourceControlManager = 0429C3740C416BB800EC1476 /* Source Control */; | ||
118 | userBuildSettings = { | ||
119 | }; | ||
120 | }; | ||
121 | D2AAC0620554660B00DB518D /* xcode */ = { | ||
122 | activeExec = 0; | ||
123 | }; | ||
124 | } | ||