Skip to content

Commit

Permalink
Issue #11223: Replace threading._info() by sys.thread_info
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor Stinner committed Apr 30, 2011
1 parent fab6c70 commit d5c355c
Show file tree
Hide file tree
Showing 13 changed files with 119 additions and 108 deletions.
29 changes: 29 additions & 0 deletions Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,35 @@ always available.
to a console and Python apps started with :program:`pythonw`.


.. data:: thread_info

A :term:`struct sequence` holding information about the thread
implementation.

+------------------+---------------------------------------------------------+
| Attribute | Explanation |
+==================+=========================================================+
| :const:`name` | Name of the thread implementation: |
| | |
| | * ``'nt'``: Windows threads |
| | * ``'os2'``: OS/2 threads |
| | * ``'pthread'``: POSIX threads |
| | * ``'solaris'``: Solaris threads |
+------------------+---------------------------------------------------------+
| :const:`lock` | Name of the lock implementation: |
| | |
| | * ``'semaphore'``: a lock uses a semaphore |
| | * ``'mutex+cond'``: a lock uses a mutex |
| | and a condition variable |
| | * ``None`` if this information is unknown |
+------------------+---------------------------------------------------------+
| :const:`version` | Name and version of the thread library. It is a string, |
| | or ``None`` if these informations are unknown. |
+------------------+---------------------------------------------------------+

.. versionadded:: 3.3


.. data:: tracebacklimit

When this variable is set to an integer value, it determines the maximum number
Expand Down
24 changes: 0 additions & 24 deletions Doc/library/threading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -175,30 +175,6 @@ This module defines the following functions and objects:
Availability: Windows, systems with POSIX threads.


.. function:: _info()

Return a dictionary with informations about the thread implementation.
The ``'name'`` key gives the name of the thread implementation (string):

* ``'nt'``: Windows threads
* ``'os2'``: OS/2 threads
* ``'pthread'``: POSIX threads
* ``'solaris'``: Solaris threads

POSIX threads have two more keys:

* ``'lock_implementation'`` (string): name of the lock
implementation

* ``'semaphore'``: a lock uses a semaphore
* ``'mutex+cond'``: a lock uses a mutex and a condition variable

* ``'pthread_version'`` (string, optional): name and version of the pthread
library

.. versionadded:: 3.3


This module also defines the following constant:

.. data:: TIMEOUT_MAX
Expand Down
8 changes: 4 additions & 4 deletions Doc/whatsnew/3.3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ connection when done::

(Contributed by Giampaolo Rodolà in :issue:`9795`)

threading
---------
sys
---

* The :mod:`threading` module has a new :func:`~threading._info` function which
provides informations about the thread implementation.
* The :mod:`sys` module has a new :func:`~sys.thread_info` :term:`struct
sequence` holding informations about the thread implementation.

(:issue:`11223`)

Expand Down
2 changes: 1 addition & 1 deletion Include/pythread.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock);
PyAPI_FUNC(size_t) PyThread_get_stacksize(void);
PyAPI_FUNC(int) PyThread_set_stacksize(size_t);

PyAPI_FUNC(PyObject*) _PyThread_Info(void);
PyAPI_FUNC(PyObject*) PyThread_GetInfo(void);

/* Thread Local Storage (TLS) API */
PyAPI_FUNC(int) PyThread_create_key(void);
Expand Down
3 changes: 0 additions & 3 deletions Lib/_dummy_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,3 @@ def interrupt_main():
else:
global _interrupt
_interrupt = True

def info():
return {'name': 'dummy'}
13 changes: 4 additions & 9 deletions Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,10 @@
# and unmaintained) linuxthreads threading library. There's an issue
# when combining linuxthreads with a failed execv call: see
# http://bugs.python.org/issue4970.
USING_LINUXTHREADS = False
if threading:
info = threading._info()
try:
pthread_version = info['pthread_version']
except KeyError:
pass
else:
USING_LINUXTHREADS = pthread_version.startswith("linuxthreads")
if hasattr(sys, 'thread_info') and sys.thread_info.version:
USING_LINUXTHREADS = sys.thread_info.version.startswith("linuxthreads")
else:
USING_LINUXTHREADS = False

# Tests creating TESTFN
class FileTests(unittest.TestCase):
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,14 @@ def test_attributes(self):
if not sys.platform.startswith('win'):
self.assertIsInstance(sys.abiflags, str)

@unittest.skipUnless(hasattr(sys, 'thread_info'),
'Threading required for this test.')
def test_thread_info(self):
info = sys.thread_info
self.assertTrue(len(info), 3)
self.assertIn(info.name, ('nt', 'os2', 'pthread', 'solaris', None))
self.assertIn(info.lock, ('semaphore', 'mutex+cond', None))

def test_43581(self):
# Can't use sys.stdout, as this is a StringIO object when
# the test runs under regrtest.
Expand Down
12 changes: 1 addition & 11 deletions Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -719,24 +719,14 @@ class BarrierTests(lock_tests.BarrierTests):
barriertype = staticmethod(threading.Barrier)


class MiscTests(unittest.TestCase):
def test_info(self):
info = threading._info()
self.assertIn(info['name'],
'nt os2 pthread solaris'.split())
if info['name'] == 'pthread':
self.assertIn(info['lock_implementation'],
('semaphore', 'mutex+cond'))


def test_main():
test.support.run_unittest(LockTests, PyRLockTests, CRLockTests, EventTests,
ConditionAsRLockTests, ConditionTests,
SemaphoreTests, BoundedSemaphoreTests,
ThreadTests,
ThreadJoinOnShutdown,
ThreadingExceptionTests,
BarrierTests, MiscTests,
BarrierTests,
)

if __name__ == "__main__":
Expand Down
5 changes: 2 additions & 3 deletions Lib/test/test_threadsignals.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
process_pid = os.getpid()
signalled_all=thread.allocate_lock()

info = thread.info()
USING_PTHREAD_COND = (info['name'] == 'pthread'
and info['lock_implementation'] == 'mutex+cond')
USING_PTHREAD_COND = (sys.thread_info.name == 'pthread'
and sys.thread_info.lock == 'mutex+cond')

def registerSignals(for_usr1, for_usr2, for_alrm):
usr1 = signal.signal(signal.SIGUSR1, for_usr1)
Expand Down
3 changes: 1 addition & 2 deletions Lib/threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

__all__ = ['active_count', 'Condition', 'current_thread', 'enumerate', 'Event',
'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier',
'Timer', 'setprofile', 'settrace', 'local', 'stack_size', '_info']
'Timer', 'setprofile', 'settrace', 'local', 'stack_size']

# Rename some stuff so "from threading import *" is safe
_start_new_thread = _thread.start_new_thread
Expand All @@ -31,7 +31,6 @@
except AttributeError:
_CRLock = None
TIMEOUT_MAX = _thread.TIMEOUT_MAX
_info = _thread.info
del _thread


Expand Down
13 changes: 0 additions & 13 deletions Modules/_threadmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1227,17 +1227,6 @@ requiring allocation in multiples of the system memory page size\n\
(4kB pages are common; using multiples of 4096 for the stack size is\n\
the suggested approach in the absence of more specific information).");

static PyObject *
thread_info(PyObject *self)
{
return _PyThread_Info();
}

PyDoc_STRVAR(thread_info_doc,
"info() -> dict\n\
\n\
Informations about the thread implementation.");

static PyMethodDef thread_methods[] = {
{"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
METH_VARARGS, start_new_doc},
Expand All @@ -1259,8 +1248,6 @@ static PyMethodDef thread_methods[] = {
METH_NOARGS, _count_doc},
{"stack_size", (PyCFunction)thread_stack_size,
METH_VARARGS, stack_size_doc},
{"info", (PyCFunction)thread_info,
METH_NOARGS, thread_info_doc},
{NULL, NULL} /* sentinel */
};

Expand Down
24 changes: 15 additions & 9 deletions Python/sysmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Data members:
#include "Python.h"
#include "code.h"
#include "frameobject.h"
#include "pythread.h"

#include "osdefs.h"

Expand Down Expand Up @@ -1251,20 +1252,21 @@ PyDoc_STR(
"\n\
Static objects:\n\
\n\
float_info -- a dict with information about the float implementation.\n\
builtin_module_names -- tuple of module names built into this interpreter\n\
copyright -- copyright notice pertaining to this interpreter\n\
exec_prefix -- prefix used to find the machine-specific Python library\n\
executable -- pathname of this Python interpreter\n\
float_info -- a struct sequence with information about the float implementation.\n\
float_repr_style -- string indicating the style of repr() output for floats\n\
hexversion -- version information encoded as a single integer\n\
int_info -- a struct sequence with information about the int implementation.\n\
maxsize -- the largest supported length of containers.\n\
maxunicode -- the largest supported character\n\
builtin_module_names -- tuple of module names built into this interpreter\n\
version -- the version of this interpreter as a string\n\
version_info -- version information as a named tuple\n\
hexversion -- version information encoded as a single integer\n\
copyright -- copyright notice pertaining to this interpreter\n\
platform -- platform identifier\n\
executable -- pathname of this Python interpreter\n\
prefix -- prefix used to find the Python library\n\
exec_prefix -- prefix used to find the machine-specific Python library\n\
float_repr_style -- string indicating the style of repr() output for floats\n\
thread_info -- a struct sequence with information about the thread implementation.\n\
version -- the version of this interpreter as a string\n\
version_info -- version information as a named tuple\n\
"
)
#ifdef MS_WINDOWS
Expand Down Expand Up @@ -1611,6 +1613,10 @@ _PySys_Init(void)
PyUnicode_FromString("legacy"));
#endif

#ifdef WITH_THREAD
SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo());
#endif

#undef SET_SYS_FROM_STRING
if (PyErr_Occurred())
return NULL;
Expand Down
83 changes: 54 additions & 29 deletions Python/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#include "Python.h"


#ifndef _POSIX_THREADS
/* This means pthreads are not implemented in libc headers, hence the macro
not present in unistd.h. But they still can be implemented as an external
Expand Down Expand Up @@ -415,57 +414,83 @@ PyThread_ReInitTLS(void)

#endif /* Py_HAVE_NATIVE_TLS */

PyDoc_STRVAR(threadinfo__doc__,
"sys.thread_info\n\
\n\
A struct sequence holding information about the thread implementation.");

static PyStructSequence_Field threadinfo_fields[] = {
{"name", "name of the thread implementation"},
{"lock", "name of the lock implementation"},
{"version", "name and version of the thread library"},
{0}
};

static PyStructSequence_Desc threadinfo_desc = {
"sys.thread_info", /* name */
threadinfo__doc__, /* doc */
threadinfo_fields, /* fields */
3
};

static PyTypeObject ThreadInfoType;

PyObject*
_PyThread_Info(void)
PyThread_GetInfo(void)
{
PyObject *info, *value;
int ret;
PyObject *threadinfo, *value;
int pos = 0;
#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
&& defined(_CS_GNU_LIBPTHREAD_VERSION))
char buffer[255];
int len;
#endif

info = PyDict_New();
if (info == NULL)
if (ThreadInfoType.tp_name == 0)
PyStructSequence_InitType(&ThreadInfoType, &threadinfo_desc);

threadinfo = PyStructSequence_New(&ThreadInfoType);
if (threadinfo == NULL)
return NULL;

value = PyUnicode_FromString(PYTHREAD_NAME);
ret = PyDict_SetItemString(info, "name", value);
Py_DECREF(value);
if (ret)
goto error;
if (value == NULL) {
Py_DECREF(threadinfo);
return NULL;
}
PyStructSequence_SET_ITEM(threadinfo, pos++, value);

#ifdef _POSIX_THREADS
#ifdef USE_SEMAPHORES
value = PyUnicode_FromString("semaphore");
#else
value = PyUnicode_FromString("mutex+cond");
#endif
if (value == NULL)
if (value == NULL) {
Py_DECREF(threadinfo);
return NULL;
ret = PyDict_SetItemString(info, "lock_implementation", value);
Py_DECREF(value);
if (ret)
goto error;
}
#else
Py_INCREF(Py_None);
value = Py_None;
#endif
PyStructSequence_SET_ITEM(threadinfo, pos++, value);

#if defined(HAVE_CONFSTR) && defined(_CS_GNU_LIBPTHREAD_VERSION)
#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
&& defined(_CS_GNU_LIBPTHREAD_VERSION))
value = NULL;
len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
if (0 < len && len < sizeof(buffer)) {
if (1 < len && len < sizeof(buffer)) {
value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
if (value == NULL)
goto error;
ret = PyDict_SetItemString(info, "pthread_version", value);
Py_DECREF(value);
if (ret)
goto error;
PyErr_Clear();
}
if (value == NULL)
#endif
#endif

return info;

error:
Py_DECREF(info);
return NULL;
{
Py_INCREF(Py_None);
value = Py_None;
}
PyStructSequence_SET_ITEM(threadinfo, pos++, value);
return threadinfo;
}

0 comments on commit d5c355c

Please sign in to comment.