Apparently the code to forestall Tk eating events was too aggressive (Tk user input...
[python/dscho.git] / Python / pystate.c
blob8e5896a44fd1ea27f207557ae0aa2d508a5e5415
2 /* Thread and interpreter state structures and their interfaces */
4 #include "Python.h"
6 #define ZAP(x) { \
7 PyObject *tmp = (PyObject *)(x); \
8 (x) = NULL; \
9 Py_XDECREF(tmp); \
13 #ifdef WITH_THREAD
14 #include "pythread.h"
15 static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
16 #define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock()))
17 #define HEAD_LOCK() PyThread_acquire_lock(head_mutex, WAIT_LOCK)
18 #define HEAD_UNLOCK() PyThread_release_lock(head_mutex)
19 #else
20 #define HEAD_INIT() /* Nothing */
21 #define HEAD_LOCK() /* Nothing */
22 #define HEAD_UNLOCK() /* Nothing */
23 #endif
25 static PyInterpreterState *interp_head = NULL;
27 PyThreadState *_PyThreadState_Current = NULL;
30 PyInterpreterState *
31 PyInterpreterState_New(void)
33 PyInterpreterState *interp = PyMem_NEW(PyInterpreterState, 1);
35 if (interp != NULL) {
36 HEAD_INIT();
37 interp->modules = NULL;
38 interp->sysdict = NULL;
39 interp->builtins = NULL;
40 interp->checkinterval = 10;
41 interp->tstate_head = NULL;
43 HEAD_LOCK();
44 interp->next = interp_head;
45 interp_head = interp;
46 HEAD_UNLOCK();
49 return interp;
53 void
54 PyInterpreterState_Clear(PyInterpreterState *interp)
56 PyThreadState *p;
57 HEAD_LOCK();
58 for (p = interp->tstate_head; p != NULL; p = p->next)
59 PyThreadState_Clear(p);
60 HEAD_UNLOCK();
61 ZAP(interp->modules);
62 ZAP(interp->sysdict);
63 ZAP(interp->builtins);
67 static void
68 zapthreads(PyInterpreterState *interp)
70 PyThreadState *p;
71 /* No need to lock the mutex here because this should only happen
72 when the threads are all really dead (XXX famous last words). */
73 while ((p = interp->tstate_head) != NULL) {
74 PyThreadState_Delete(p);
79 void
80 PyInterpreterState_Delete(PyInterpreterState *interp)
82 PyInterpreterState **p;
83 zapthreads(interp);
84 HEAD_LOCK();
85 for (p = &interp_head; ; p = &(*p)->next) {
86 if (*p == NULL)
87 Py_FatalError(
88 "PyInterpreterState_Delete: invalid interp");
89 if (*p == interp)
90 break;
92 if (interp->tstate_head != NULL)
93 Py_FatalError("PyInterpreterState_Delete: remaining threads");
94 *p = interp->next;
95 HEAD_UNLOCK();
96 PyMem_DEL(interp);
100 PyThreadState *
101 PyThreadState_New(PyInterpreterState *interp)
103 PyThreadState *tstate = PyMem_NEW(PyThreadState, 1);
105 if (tstate != NULL) {
106 tstate->interp = interp;
108 tstate->frame = NULL;
109 tstate->recursion_depth = 0;
110 tstate->ticker = 0;
111 tstate->tracing = 0;
113 tstate->dict = NULL;
115 tstate->curexc_type = NULL;
116 tstate->curexc_value = NULL;
117 tstate->curexc_traceback = NULL;
119 tstate->exc_type = NULL;
120 tstate->exc_value = NULL;
121 tstate->exc_traceback = NULL;
123 tstate->sys_profilefunc = NULL;
124 tstate->sys_tracefunc = NULL;
126 HEAD_LOCK();
127 tstate->next = interp->tstate_head;
128 interp->tstate_head = tstate;
129 HEAD_UNLOCK();
132 return tstate;
136 void
137 PyThreadState_Clear(PyThreadState *tstate)
139 if (Py_VerboseFlag && tstate->frame != NULL)
140 fprintf(stderr,
141 "PyThreadState_Clear: warning: thread still has a frame\n");
143 ZAP(tstate->frame);
145 ZAP(tstate->dict);
147 ZAP(tstate->curexc_type);
148 ZAP(tstate->curexc_value);
149 ZAP(tstate->curexc_traceback);
151 ZAP(tstate->exc_type);
152 ZAP(tstate->exc_value);
153 ZAP(tstate->exc_traceback);
155 ZAP(tstate->sys_profilefunc);
156 ZAP(tstate->sys_tracefunc);
160 /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
161 static void
162 tstate_delete_common(PyThreadState *tstate)
164 PyInterpreterState *interp;
165 PyThreadState **p;
166 if (tstate == NULL)
167 Py_FatalError("PyThreadState_Delete: NULL tstate");
168 interp = tstate->interp;
169 if (interp == NULL)
170 Py_FatalError("PyThreadState_Delete: NULL interp");
171 HEAD_LOCK();
172 for (p = &interp->tstate_head; ; p = &(*p)->next) {
173 if (*p == NULL)
174 Py_FatalError(
175 "PyThreadState_Delete: invalid tstate");
176 if (*p == tstate)
177 break;
179 *p = tstate->next;
180 HEAD_UNLOCK();
181 PyMem_DEL(tstate);
185 void
186 PyThreadState_Delete(PyThreadState *tstate)
188 if (tstate == _PyThreadState_Current)
189 Py_FatalError("PyThreadState_Delete: tstate is still current");
190 tstate_delete_common(tstate);
194 #ifdef WITH_THREAD
195 void
196 PyThreadState_DeleteCurrent()
198 PyThreadState *tstate = _PyThreadState_Current;
199 if (tstate == NULL)
200 Py_FatalError(
201 "PyThreadState_DeleteCurrent: no current tstate");
202 _PyThreadState_Current = NULL;
203 tstate_delete_common(tstate);
204 PyEval_ReleaseLock();
206 #endif /* WITH_THREAD */
209 PyThreadState *
210 PyThreadState_Get(void)
212 if (_PyThreadState_Current == NULL)
213 Py_FatalError("PyThreadState_Get: no current thread");
215 return _PyThreadState_Current;
219 PyThreadState *
220 PyThreadState_Swap(PyThreadState *new)
222 PyThreadState *old = _PyThreadState_Current;
224 _PyThreadState_Current = new;
226 return old;
229 /* An extension mechanism to store arbitrary additional per-thread state.
230 PyThreadState_GetDict() returns a dictionary that can be used to hold such
231 state; the caller should pick a unique key and store its state there. If
232 PyThreadState_GetDict() returns NULL, an exception has been raised (most
233 likely MemoryError) and the caller should pass on the exception. */
235 PyObject *
236 PyThreadState_GetDict(void)
238 if (_PyThreadState_Current == NULL)
239 Py_FatalError("PyThreadState_GetDict: no current thread");
241 if (_PyThreadState_Current->dict == NULL)
242 _PyThreadState_Current->dict = PyDict_New();
243 return _PyThreadState_Current->dict;