blob: 85a9ce76040fd12504ad1978a36a966ab01b11de [file] [log] [blame]
Guido van Rossuma027efa1997-05-05 20:56:21 +00001
2/* Thread and interpreter state structures and their interfaces */
3
4#include "Python.h"
5
Guido van Rossum25ce5661997-08-02 03:10:38 +00006#define ZAP(x) { \
7 PyObject *tmp = (PyObject *)(x); \
8 (x) = NULL; \
9 Py_XDECREF(tmp); \
10}
11
12
Guido van Rossum1d5ad901999-06-18 14:22:24 +000013#ifdef WITH_THREAD
14#include "pythread.h"
15static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
Moshe Zadka9fb6af92000-08-04 21:27:47 +000016#define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock()))
Guido van Rossum1d5ad901999-06-18 14:22:24 +000017#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
24
Guido van Rossum25ce5661997-08-02 03:10:38 +000025static PyInterpreterState *interp_head = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +000026
Guido van Rossum18bc7c21998-12-21 18:27:28 +000027PyThreadState *_PyThreadState_Current = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +000028
29
30PyInterpreterState *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000031PyInterpreterState_New(void)
Guido van Rossuma027efa1997-05-05 20:56:21 +000032{
33 PyInterpreterState *interp = PyMem_NEW(PyInterpreterState, 1);
Guido van Rossum25ce5661997-08-02 03:10:38 +000034
Guido van Rossuma027efa1997-05-05 20:56:21 +000035 if (interp != NULL) {
Guido van Rossum1d5ad901999-06-18 14:22:24 +000036 HEAD_INIT();
Guido van Rossum25ce5661997-08-02 03:10:38 +000037 interp->modules = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +000038 interp->sysdict = NULL;
Guido van Rossum25ce5661997-08-02 03:10:38 +000039 interp->builtins = NULL;
40 interp->checkinterval = 10;
41 interp->tstate_head = NULL;
42
43 interp->next = interp_head;
44 interp_head = interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +000045 }
Guido van Rossum25ce5661997-08-02 03:10:38 +000046
Guido van Rossuma027efa1997-05-05 20:56:21 +000047 return interp;
48}
49
50
51void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000052PyInterpreterState_Clear(PyInterpreterState *interp)
Guido van Rossum25ce5661997-08-02 03:10:38 +000053{
54 PyThreadState *p;
Guido van Rossum1d5ad901999-06-18 14:22:24 +000055 HEAD_LOCK();
Guido van Rossum25ce5661997-08-02 03:10:38 +000056 for (p = interp->tstate_head; p != NULL; p = p->next)
57 PyThreadState_Clear(p);
Guido van Rossum1d5ad901999-06-18 14:22:24 +000058 HEAD_UNLOCK();
Guido van Rossum25ce5661997-08-02 03:10:38 +000059 ZAP(interp->modules);
60 ZAP(interp->sysdict);
61 ZAP(interp->builtins);
62}
63
64
65static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000066zapthreads(PyInterpreterState *interp)
Guido van Rossum25ce5661997-08-02 03:10:38 +000067{
Guido van Rossum1d5ad901999-06-18 14:22:24 +000068 PyThreadState *p;
69 /* No need to lock the mutex here because this should only happen
70 when the threads are all really dead (XXX famous last words). */
71 while ((p = interp->tstate_head) != NULL) {
Guido van Rossum25ce5661997-08-02 03:10:38 +000072 PyThreadState_Delete(p);
Guido van Rossum25ce5661997-08-02 03:10:38 +000073 }
74}
75
76
77void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000078PyInterpreterState_Delete(PyInterpreterState *interp)
Guido van Rossuma027efa1997-05-05 20:56:21 +000079{
Guido van Rossum25ce5661997-08-02 03:10:38 +000080 PyInterpreterState **p;
81 zapthreads(interp);
82 for (p = &interp_head; ; p = &(*p)->next) {
83 if (*p == NULL)
84 Py_FatalError(
85 "PyInterpreterState_Delete: invalid interp");
86 if (*p == interp)
87 break;
88 }
89 if (interp->tstate_head != NULL)
90 Py_FatalError("PyInterpreterState_Delete: remaining threads");
91 *p = interp->next;
Guido van Rossuma027efa1997-05-05 20:56:21 +000092 PyMem_DEL(interp);
93}
94
95
96PyThreadState *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000097PyThreadState_New(PyInterpreterState *interp)
Guido van Rossuma027efa1997-05-05 20:56:21 +000098{
99 PyThreadState *tstate = PyMem_NEW(PyThreadState, 1);
Guido van Rossum25ce5661997-08-02 03:10:38 +0000100
Guido van Rossuma027efa1997-05-05 20:56:21 +0000101 if (tstate != NULL) {
Guido van Rossum25ce5661997-08-02 03:10:38 +0000102 tstate->interp = interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000103
104 tstate->frame = NULL;
105 tstate->recursion_depth = 0;
106 tstate->ticker = 0;
107 tstate->tracing = 0;
108
Guido van Rossumede04391998-04-10 20:18:25 +0000109 tstate->dict = NULL;
110
Guido van Rossuma027efa1997-05-05 20:56:21 +0000111 tstate->curexc_type = NULL;
112 tstate->curexc_value = NULL;
113 tstate->curexc_traceback = NULL;
114
115 tstate->exc_type = NULL;
116 tstate->exc_value = NULL;
117 tstate->exc_traceback = NULL;
118
119 tstate->sys_profilefunc = NULL;
120 tstate->sys_tracefunc = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000121
Guido van Rossum1d5ad901999-06-18 14:22:24 +0000122 HEAD_LOCK();
Guido van Rossum25ce5661997-08-02 03:10:38 +0000123 tstate->next = interp->tstate_head;
124 interp->tstate_head = tstate;
Guido van Rossum1d5ad901999-06-18 14:22:24 +0000125 HEAD_UNLOCK();
Guido van Rossuma027efa1997-05-05 20:56:21 +0000126 }
Guido van Rossum25ce5661997-08-02 03:10:38 +0000127
Guido van Rossuma027efa1997-05-05 20:56:21 +0000128 return tstate;
129}
130
131
132void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000133PyThreadState_Clear(PyThreadState *tstate)
Guido van Rossum25ce5661997-08-02 03:10:38 +0000134{
Guido van Rossum22348dc1997-11-03 22:08:36 +0000135 if (Py_VerboseFlag && tstate->frame != NULL)
Guido van Rossum25ce5661997-08-02 03:10:38 +0000136 fprintf(stderr,
Guido van Rossum5f896a41997-08-21 02:28:19 +0000137 "PyThreadState_Clear: warning: thread still has a frame\n");
Guido van Rossum25ce5661997-08-02 03:10:38 +0000138
139 ZAP(tstate->frame);
140
Guido van Rossumede04391998-04-10 20:18:25 +0000141 ZAP(tstate->dict);
142
Guido van Rossum25ce5661997-08-02 03:10:38 +0000143 ZAP(tstate->curexc_type);
144 ZAP(tstate->curexc_value);
145 ZAP(tstate->curexc_traceback);
146
147 ZAP(tstate->exc_type);
148 ZAP(tstate->exc_value);
149 ZAP(tstate->exc_traceback);
150
151 ZAP(tstate->sys_profilefunc);
152 ZAP(tstate->sys_tracefunc);
153}
154
155
156void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000157PyThreadState_Delete(PyThreadState *tstate)
Guido van Rossuma027efa1997-05-05 20:56:21 +0000158{
Guido van Rossum25ce5661997-08-02 03:10:38 +0000159 PyInterpreterState *interp;
160 PyThreadState **p;
161 if (tstate == NULL)
162 Py_FatalError("PyThreadState_Delete: NULL tstate");
Guido van Rossum18bc7c21998-12-21 18:27:28 +0000163 if (tstate == _PyThreadState_Current)
Guido van Rossum25ce5661997-08-02 03:10:38 +0000164 Py_FatalError("PyThreadState_Delete: tstate is still current");
165 interp = tstate->interp;
166 if (interp == NULL)
167 Py_FatalError("PyThreadState_Delete: NULL interp");
Guido van Rossum1d5ad901999-06-18 14:22:24 +0000168 HEAD_LOCK();
Guido van Rossum25ce5661997-08-02 03:10:38 +0000169 for (p = &interp->tstate_head; ; p = &(*p)->next) {
170 if (*p == NULL)
171 Py_FatalError(
172 "PyThreadState_Delete: invalid tstate");
173 if (*p == tstate)
174 break;
175 }
176 *p = tstate->next;
Guido van Rossum1d5ad901999-06-18 14:22:24 +0000177 HEAD_UNLOCK();
Guido van Rossuma027efa1997-05-05 20:56:21 +0000178 PyMem_DEL(tstate);
179}
180
181
182PyThreadState *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000183PyThreadState_Get(void)
Guido van Rossuma027efa1997-05-05 20:56:21 +0000184{
Guido van Rossum18bc7c21998-12-21 18:27:28 +0000185 if (_PyThreadState_Current == NULL)
Guido van Rossum25ce5661997-08-02 03:10:38 +0000186 Py_FatalError("PyThreadState_Get: no current thread");
187
Guido van Rossum18bc7c21998-12-21 18:27:28 +0000188 return _PyThreadState_Current;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000189}
190
191
192PyThreadState *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000193PyThreadState_Swap(PyThreadState *new)
Guido van Rossuma027efa1997-05-05 20:56:21 +0000194{
Guido van Rossum18bc7c21998-12-21 18:27:28 +0000195 PyThreadState *old = _PyThreadState_Current;
Guido van Rossum25ce5661997-08-02 03:10:38 +0000196
Guido van Rossum18bc7c21998-12-21 18:27:28 +0000197 _PyThreadState_Current = new;
Guido van Rossum25ce5661997-08-02 03:10:38 +0000198
Guido van Rossuma027efa1997-05-05 20:56:21 +0000199 return old;
200}
Guido van Rossumede04391998-04-10 20:18:25 +0000201
202/* An extension mechanism to store arbitrary additional per-thread state.
203 PyThreadState_GetDict() returns a dictionary that can be used to hold such
204 state; the caller should pick a unique key and store its state there. If
205 PyThreadState_GetDict() returns NULL, an exception has been raised (most
206 likely MemoryError) and the caller should pass on the exception. */
207
208PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000209PyThreadState_GetDict(void)
Guido van Rossumede04391998-04-10 20:18:25 +0000210{
Guido van Rossum18bc7c21998-12-21 18:27:28 +0000211 if (_PyThreadState_Current == NULL)
Guido van Rossumede04391998-04-10 20:18:25 +0000212 Py_FatalError("PyThreadState_GetDict: no current thread");
213
Guido van Rossum18bc7c21998-12-21 18:27:28 +0000214 if (_PyThreadState_Current->dict == NULL)
215 _PyThreadState_Current->dict = PyDict_New();
216 return _PyThreadState_Current->dict;
Guido van Rossumede04391998-04-10 20:18:25 +0000217}