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:
parent
73a9eade1c
commit
112aad3630
|
@ -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))
|
||||||
|
|
13
Misc/NEWS
13
Misc/NEWS
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue