aboutsummaryrefslogtreecommitdiff
path: root/lstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'lstate.c')
-rw-r--r--lstate.c75
1 files changed, 30 insertions, 45 deletions
diff --git a/lstate.c b/lstate.c
index fd4edff5..9fb89a8d 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.54 2001/01/25 16:45:36 roberto Exp roberto $ 2** $Id: lstate.c,v 1.55 2001/01/26 11:45:51 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -19,33 +19,27 @@
19#include "ltm.h" 19#include "ltm.h"
20 20
21 21
22#ifdef LUA_DEBUG
23static lua_State *lua_state = NULL;
24void luaB_opentests (lua_State *L);
25int islocked = 0;
26#endif
27
28
29/*
30** built-in implementation for ERRORMESSAGE. In a "correct" environment
31** ERRORMESSAGE should have an external definition, and so this function
32** would not be used.
33*/
34static int errormessage (lua_State *L) {
35 const char *s = lua_tostring(L, 1);
36 if (s == NULL) s = "(no message)";
37 fprintf(stderr, "error: %s\n", s);
38 return 0;
39}
40
41
42struct Sopen { 22struct Sopen {
43 int stacksize; 23 int stacksize;
44 lua_State *L; 24 lua_State *L;
45}; 25};
46 26
47 27
48static void close_state (lua_State *L); 28static void close_state (lua_State *L, lua_State *OL);
29
30
31/*
32** initialize ref array and registry
33*/
34#define INIT_REFSIZE 4
35
36static void ref_init (lua_State *L) {
37 G(L)->refArray = luaM_newvector(L, INIT_REFSIZE, struct Ref);
38 G(L)->sizeref = INIT_REFSIZE;
39 sethvalue(&G(L)->refArray[0].o, luaH_new(L, 0));
40 G(L)->refArray[0].st = LOCK;
41 G(L)->nref = 1;
42}
49 43
50 44
51/* 45/*
@@ -90,17 +84,8 @@ static void f_luaopen (lua_State *L, void *ud) {
90 luaS_init(L); 84 luaS_init(L);
91 luaX_init(L); 85 luaX_init(L);
92 luaT_init(L); 86 luaT_init(L);
87 ref_init(L);
93 G(L)->GCthreshold = 4*G(L)->nblocks; 88 G(L)->GCthreshold = 4*G(L)->nblocks;
94 LUA_UNLOCK; /* temporary exit to use the API */
95 lua_newtable(L);
96 lua_ref(L, 1); /* create registry */
97 lua_register(L, LUA_ERRORMESSAGE, errormessage);
98#ifdef LUA_DEBUG
99 luaB_opentests(L);
100 if (lua_state == NULL) lua_state = L; /* keep first state to be opened */
101 lua_assert(lua_gettop(L) == 0);
102#endif
103 LUA_LOCK; /* go back inside */
104 } 89 }
105} 90}
106 91
@@ -108,7 +93,7 @@ static void f_luaopen (lua_State *L, void *ud) {
108LUA_API lua_State *lua_open (lua_State *OL, int stacksize) { 93LUA_API lua_State *lua_open (lua_State *OL, int stacksize) {
109 struct Sopen so; 94 struct Sopen so;
110 lua_State *L; 95 lua_State *L;
111 LUA_LOCK; 96 if (OL) LUA_LOCK(OL);
112 L = luaM_new(OL, lua_State); 97 L = luaM_new(OL, lua_State);
113 if (L) { /* allocation OK? */ 98 if (L) { /* allocation OK? */
114 L->G = NULL; 99 L->G = NULL;
@@ -123,20 +108,17 @@ LUA_API lua_State *lua_open (lua_State *OL, int stacksize) {
123 so.L = OL; 108 so.L = OL;
124 if (luaD_runprotected(L, f_luaopen, &so) != 0) { 109 if (luaD_runprotected(L, f_luaopen, &so) != 0) {
125 /* memory allocation error: free partial state */ 110 /* memory allocation error: free partial state */
126 close_state(L); 111 close_state(L, OL);
127 L = NULL; 112 L = NULL;
128 } 113 }
129 } 114 }
130 LUA_UNLOCK; 115 if (OL) LUA_UNLOCK(OL);
131 return L; 116 return L;
132} 117}
133 118
134 119
135static void close_state (lua_State *L) { 120static void close_state (lua_State *L, lua_State *OL) {
136 lua_State *L1; 121 if (OL != NULL) { /* are there other threads? */
137 L1 = L->next; /* any surviving thread (if there is one) */
138 if (L1 == L) L1 = NULL; /* no surviving threads */
139 if (L1 != NULL) { /* are there other threads? */
140 lua_assert(L->previous != L); 122 lua_assert(L->previous != L);
141 L->previous->next = L->next; 123 L->previous->next = L->next;
142 L->next->previous = L->previous; 124 L->next->previous = L->previous;
@@ -152,15 +134,18 @@ static void close_state (lua_State *L) {
152 luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char); 134 luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char);
153 luaM_freelem(NULL, L->G, global_State); 135 luaM_freelem(NULL, L->G, global_State);
154 } 136 }
155 luaM_freearray(L1, L->stack, L->stacksize, TObject); 137 luaM_freearray(OL, L->stack, L->stacksize, TObject);
156 luaM_freelem(L1, L, lua_State); 138 luaM_freelem(OL, L, lua_State);
157} 139}
158 140
159LUA_API void lua_close (lua_State *L) { 141LUA_API void lua_close (lua_State *L) {
142 lua_State *OL;
160 lua_assert(L != lua_state || lua_gettop(L) == 0); 143 lua_assert(L != lua_state || lua_gettop(L) == 0);
161 LUA_LOCK; 144 LUA_LOCK(L);
162 close_state(L); 145 OL = L->next; /* any surviving thread (if there is one) */
163 LUA_UNLOCK; 146 if (OL == L) OL = NULL; /* no surviving threads */
147 close_state(L, OL);
148 if (OL) LUA_UNLOCK(OL); /* cannot unlock over a freed state */
164 lua_assert(L != lua_state || memdebug_numblocks == 0); 149 lua_assert(L != lua_state || memdebug_numblocks == 0);
165 lua_assert(L != lua_state || memdebug_total == 0); 150 lua_assert(L != lua_state || memdebug_total == 0);
166} 151}