home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Python / pystate.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  4.7 KB  |  222 lines

  1.  
  2. /* Thread and interpreter state structures and their interfaces */
  3.  
  4. #include "Python.h"
  5.  
  6. #define ZAP(x) { \
  7.     PyObject *tmp = (PyObject *)(x); \
  8.     (x) = NULL; \
  9.     Py_XDECREF(tmp); \
  10. }
  11.  
  12.  
  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
  24.  
  25. static PyInterpreterState *interp_head = NULL;
  26.  
  27. PyThreadState *_PyThreadState_Current = NULL;
  28.  
  29.  
  30. PyInterpreterState *
  31. PyInterpreterState_New(void)
  32. {
  33.     PyInterpreterState *interp = PyMem_NEW(PyInterpreterState, 1);
  34.  
  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;
  42.  
  43.         HEAD_LOCK();
  44.         interp->next = interp_head;
  45.         interp_head = interp;
  46.         HEAD_UNLOCK();
  47.     }
  48.  
  49.     return interp;
  50. }
  51.  
  52.  
  53. void
  54. PyInterpreterState_Clear(PyInterpreterState *interp)
  55. {
  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);
  64. }
  65.  
  66.  
  67. static void
  68. zapthreads(PyInterpreterState *interp)
  69. {
  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);
  75.     }
  76. }
  77.  
  78.  
  79. void
  80. PyInterpreterState_Delete(PyInterpreterState *interp)
  81. {
  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;
  91.     }
  92.     if (interp->tstate_head != NULL)
  93.         Py_FatalError("PyInterpreterState_Delete: remaining threads");
  94.     *p = interp->next;
  95.     HEAD_UNLOCK();
  96.     PyMem_DEL(interp);
  97. }
  98.  
  99.  
  100. PyThreadState *
  101. PyThreadState_New(PyInterpreterState *interp)
  102. {
  103.     PyThreadState *tstate = PyMem_NEW(PyThreadState, 1);
  104.  
  105.     if (tstate != NULL) {
  106.         tstate->interp = interp;
  107.  
  108.         tstate->frame = NULL;
  109.         tstate->recursion_depth = 0;
  110.         tstate->ticker = 0;
  111.         tstate->tracing = 0;
  112.  
  113.         tstate->dict = NULL;
  114.  
  115.         tstate->curexc_type = NULL;
  116.         tstate->curexc_value = NULL;
  117.         tstate->curexc_traceback = NULL;
  118.  
  119.         tstate->exc_type = NULL;
  120.         tstate->exc_value = NULL;
  121.         tstate->exc_traceback = NULL;
  122.  
  123.         tstate->sys_profilefunc = NULL;
  124.         tstate->sys_tracefunc = NULL;
  125.  
  126.         HEAD_LOCK();
  127.         tstate->next = interp->tstate_head;
  128.         interp->tstate_head = tstate;
  129.         HEAD_UNLOCK();
  130.     }
  131.  
  132.     return tstate;
  133. }
  134.  
  135.  
  136. void
  137. PyThreadState_Clear(PyThreadState *tstate)
  138. {
  139.     if (Py_VerboseFlag && tstate->frame != NULL)
  140.         fprintf(stderr,
  141.           "PyThreadState_Clear: warning: thread still has a frame\n");
  142.  
  143.     ZAP(tstate->frame);
  144.  
  145.     ZAP(tstate->dict);
  146.  
  147.     ZAP(tstate->curexc_type);
  148.     ZAP(tstate->curexc_value);
  149.     ZAP(tstate->curexc_traceback);
  150.  
  151.     ZAP(tstate->exc_type);
  152.     ZAP(tstate->exc_value);
  153.     ZAP(tstate->exc_traceback);
  154.  
  155.     ZAP(tstate->sys_profilefunc);
  156.     ZAP(tstate->sys_tracefunc);
  157. }
  158.  
  159.  
  160. void
  161. PyThreadState_Delete(PyThreadState *tstate)
  162. {
  163.     PyInterpreterState *interp;
  164.     PyThreadState **p;
  165.     if (tstate == NULL)
  166.         Py_FatalError("PyThreadState_Delete: NULL tstate");
  167.     if (tstate == _PyThreadState_Current)
  168.         Py_FatalError("PyThreadState_Delete: tstate is still current");
  169.     interp = tstate->interp;
  170.     if (interp == NULL)
  171.         Py_FatalError("PyThreadState_Delete: NULL interp");
  172.     HEAD_LOCK();
  173.     for (p = &interp->tstate_head; ; p = &(*p)->next) {
  174.         if (*p == NULL)
  175.             Py_FatalError(
  176.                 "PyThreadState_Delete: invalid tstate");
  177.         if (*p == tstate)
  178.             break;
  179.     }
  180.     *p = tstate->next;
  181.     HEAD_UNLOCK();
  182.     PyMem_DEL(tstate);
  183. }
  184.  
  185.  
  186. PyThreadState *
  187. PyThreadState_Get(void)
  188. {
  189.     if (_PyThreadState_Current == NULL)
  190.         Py_FatalError("PyThreadState_Get: no current thread");
  191.  
  192.     return _PyThreadState_Current;
  193. }
  194.  
  195.  
  196. PyThreadState *
  197. PyThreadState_Swap(PyThreadState *new)
  198. {
  199.     PyThreadState *old = _PyThreadState_Current;
  200.  
  201.     _PyThreadState_Current = new;
  202.  
  203.     return old;
  204. }
  205.  
  206. /* An extension mechanism to store arbitrary additional per-thread state.
  207.    PyThreadState_GetDict() returns a dictionary that can be used to hold such
  208.    state; the caller should pick a unique key and store its state there.  If
  209.    PyThreadState_GetDict() returns NULL, an exception has been raised (most
  210.    likely MemoryError) and the caller should pass on the exception. */
  211.  
  212. PyObject *
  213. PyThreadState_GetDict(void)
  214. {
  215.     if (_PyThreadState_Current == NULL)
  216.         Py_FatalError("PyThreadState_GetDict: no current thread");
  217.  
  218.     if (_PyThreadState_Current->dict == NULL)
  219.         _PyThreadState_Current->dict = PyDict_New();
  220.     return _PyThreadState_Current->dict;
  221. }
  222.