]> granicus.if.org Git - python/commitdiff
SF bug 1524317: configure --without-threads fails to build
authorTim Peters <tim.peters@gmail.com>
Wed, 19 Jul 2006 00:03:19 +0000 (00:03 +0000)
committerTim Peters <tim.peters@gmail.com>
Wed, 19 Jul 2006 00:03:19 +0000 (00:03 +0000)
Moved the code for _PyThread_CurrentFrames() up, so it's no longer
in a huge "#ifdef WITH_THREAD" block (I didn't realize it /was/ in
one).

Changed test_sys's test_current_frames() so it passes with or without
thread supported compiled in.

Note that test_sys fails when Python is compiled without threads,
but for an unrelated reason (the old test_exit() fails with an
indirect ImportError on the `thread` module).  There are also
other unrelated compilation failures without threads, in extension
modules (like ctypes); at least the core compiles again.

Do we really support --without-threads?  If so, there are several
problems remaining.

Lib/test/test_sys.py
Misc/NEWS
Python/pystate.c

index bb86c882377694a06b5601c6e3721f215504a915..9d4bbe7480e3187e9f48a8cbdf21e700bd9395c4 100644 (file)
@@ -239,6 +239,19 @@ class SysModuleTest(unittest.TestCase):
 
     # sys._current_frames() is a CPython-only gimmick.
     def test_current_frames(self):
+        have_threads = True
+        try:
+            import thread
+        except ImportError:
+            have_threads = False
+
+        if have_threads:
+            self.current_frames_with_threads()
+        else:
+            self.current_frames_without_threads()
+
+    # Test sys._current_frames() in a WITH_THREADS build.
+    def current_frames_with_threads(self):
         import threading, thread
         import traceback
 
@@ -298,6 +311,15 @@ class SysModuleTest(unittest.TestCase):
         leave_g.set()
         t.join()
 
+    # Test sys._current_frames() when thread support doesn't exist.
+    def current_frames_without_threads(self):
+        # Not much happens here:  there is only one thread, with artificial
+        # "thread id" 0.
+        d = sys._current_frames()
+        self.assertEqual(len(d), 1)
+        self.assert_(0 in d)
+        self.assert_(d[0] is sys._getframe())
+
     def test_attributes(self):
         self.assert_(isinstance(sys.api_version, int))
         self.assert_(isinstance(sys.argv, list))
index 9fa594e0cecd8f27917fb53db98617530b4b3eed..7339db2ec59c65f27276e79658e67bffdf7bcc1a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -24,6 +24,11 @@ Core and builtins
   again.  Fixing this problem required changing the .pyc magic number.
   This means that .pyc files generated before 2.5c1 will be regenerated.
 
+- Bug #1524317:  Compiling Python ``--without-threads`` failed.
+  The Python core compiles again then, and, in a build without threads, the
+  new ``sys._current_frames()`` returns a dictionary with one entry,
+  mapping the faux "thread id" 0 to the current frame.
+
 Library
 -------
 
@@ -155,9 +160,9 @@ Library
 Extension Modules
 -----------------
 
-- #1494314: Fix a regression with high-numbered sockets in 2.4.3. This 
-  means that select() on sockets > FD_SETSIZE (typically 1024) work again. 
-  The patch makes sockets use poll() internally where available. 
+- #1494314: Fix a regression with high-numbered sockets in 2.4.3. This
+  means that select() on sockets > FD_SETSIZE (typically 1024) work again.
+  The patch makes sockets use poll() internally where available.
 
 - Assigning None to pointer type fields in ctypes structures possible
   overwrote the wrong fields, this is fixed now.
@@ -1216,7 +1221,7 @@ Extension Modules
 
 Library
 -------
-  
+
 - Patch #1388073: Numerous __-prefixed attributes of unittest.TestCase have
   been renamed to have only a single underscore prefix.  This was done to
   make subclassing easier.
index b872dc0752c6b231e400e972e45d944fe6255782..eca26c78c8b5329000b8489e148891f6d44689a9 100644 (file)
@@ -387,6 +387,53 @@ PyThreadState_Next(PyThreadState *tstate) {
        return tstate->next;
 }
 
+/* The implementation of sys._current_frames().  This is intended to be
+   called with the GIL held, as it will be when called via
+   sys._current_frames().  It's possible it would work fine even without
+   the GIL held, but haven't thought enough about that.
+*/
+PyObject *
+_PyThread_CurrentFrames(void)
+{
+       PyObject *result;
+       PyInterpreterState *i;
+
+       result = PyDict_New();
+       if (result == NULL)
+               return NULL;
+
+       /* for i in all interpreters:
+        *     for t in all of i's thread states:
+        *          if t's frame isn't NULL, map t's id to its frame
+        * Because these lists can mutute even when the GIL is held, we
+        * need to grab head_mutex for the duration.
+        */
+       HEAD_LOCK();
+       for (i = interp_head; i != NULL; i = i->next) {
+               PyThreadState *t;
+               for (t = i->tstate_head; t != NULL; t = t->next) {
+                       PyObject *id;
+                       int stat;
+                       struct _frame *frame = t->frame;
+                       if (frame == NULL)
+                               continue;
+                       id = PyInt_FromLong(t->thread_id);
+                       if (id == NULL)
+                               goto Fail;
+                       stat = PyDict_SetItem(result, id, (PyObject *)frame);
+                       Py_DECREF(id);
+                       if (stat < 0)
+                               goto Fail;
+               }
+       }
+       HEAD_UNLOCK();
+       return result;
+
+ Fail:
+       HEAD_UNLOCK();
+       Py_DECREF(result);
+       return NULL;
+}
 
 /* Python "auto thread state" API. */
 #ifdef WITH_THREAD
@@ -550,54 +597,6 @@ PyGILState_Release(PyGILState_STATE oldstate)
                PyEval_SaveThread();
 }
 
-/* The implementation of sys._current_frames().  This is intended to be
-   called with the GIL held, as it will be when called via
-   sys._current_frames().  It's possible it would work fine even without
-   the GIL held, but haven't thought enough about that.
-*/
-PyObject *
-_PyThread_CurrentFrames(void)
-{
-       PyObject *result;
-       PyInterpreterState *i;
-
-       result = PyDict_New();
-       if (result == NULL)
-               return NULL;
-
-       /* for i in all interpreters:
-        *     for t in all of i's thread states:
-        *          if t's frame isn't NULL, map t's id to its frame
-        * Because these lists can mutute even when the GIL is held, we
-        * need to grab head_mutex for the duration.
-        */
-       HEAD_LOCK();
-       for (i = interp_head; i != NULL; i = i->next) {
-               PyThreadState *t;
-               for (t = i->tstate_head; t != NULL; t = t->next) {
-                       PyObject *id;
-                       int stat;
-                       struct _frame *frame = t->frame;
-                       if (frame == NULL)
-                               continue;
-                       id = PyInt_FromLong(t->thread_id);
-                       if (id == NULL)
-                               goto Fail;
-                       stat = PyDict_SetItem(result, id, (PyObject *)frame);
-                       Py_DECREF(id);
-                       if (stat < 0)
-                               goto Fail;
-               }
-       }
-       HEAD_UNLOCK();
-       return result;
-
- Fail:
-       HEAD_UNLOCK();
-       Py_DECREF(result);
-       return NULL;
-}
-
 #ifdef __cplusplus
 }
 #endif