SF bug 1524317: configure --without-threads fails to build

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.
This commit is contained in:
Tim Peters 2006-07-19 00:03:19 +00:00
parent 73a9eade1c
commit 112aad3630
3 changed files with 78 additions and 52 deletions

View File

@ -239,6 +239,19 @@ class SysModuleTest(unittest.TestCase):
# sys._current_frames() is a CPython-only gimmick. # sys._current_frames() is a CPython-only gimmick.
def test_current_frames(self): 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 threading, thread
import traceback import traceback
@ -298,6 +311,15 @@ class SysModuleTest(unittest.TestCase):
leave_g.set() leave_g.set()
t.join() 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): def test_attributes(self):
self.assert_(isinstance(sys.api_version, int)) self.assert_(isinstance(sys.api_version, int))
self.assert_(isinstance(sys.argv, list)) self.assert_(isinstance(sys.argv, list))

View File

@ -24,6 +24,11 @@ Core and builtins
again. Fixing this problem required changing the .pyc magic number. again. Fixing this problem required changing the .pyc magic number.
This means that .pyc files generated before 2.5c1 will be regenerated. 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 Library
------- -------
@ -155,9 +160,9 @@ Library
Extension Modules Extension Modules
----------------- -----------------
- #1494314: Fix a regression with high-numbered sockets in 2.4.3. This - #1494314: Fix a regression with high-numbered sockets in 2.4.3. This
means that select() on sockets > FD_SETSIZE (typically 1024) work again. means that select() on sockets > FD_SETSIZE (typically 1024) work again.
The patch makes sockets use poll() internally where available. The patch makes sockets use poll() internally where available.
- Assigning None to pointer type fields in ctypes structures possible - Assigning None to pointer type fields in ctypes structures possible
overwrote the wrong fields, this is fixed now. overwrote the wrong fields, this is fixed now.
@ -1216,7 +1221,7 @@ Extension Modules
Library Library
------- -------
- Patch #1388073: Numerous __-prefixed attributes of unittest.TestCase have - Patch #1388073: Numerous __-prefixed attributes of unittest.TestCase have
been renamed to have only a single underscore prefix. This was done to been renamed to have only a single underscore prefix. This was done to
make subclassing easier. make subclassing easier.

View File

@ -387,6 +387,53 @@ PyThreadState_Next(PyThreadState *tstate) {
return tstate->next; 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. */ /* Python "auto thread state" API. */
#ifdef WITH_THREAD #ifdef WITH_THREAD
@ -550,54 +597,6 @@ PyGILState_Release(PyGILState_STATE oldstate)
PyEval_SaveThread(); 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 #ifdef __cplusplus
} }
#endif #endif