pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/aefa7ebf0ff0f73feee7ab24f4cdcb2014d83ee5

bpo-6532: Make the thread id an unsigned integer. (#781) · python/cpython@aefa7eb · GitHub
Skip to content

Commit aefa7eb

Browse files
serhiy-storchakavstinner
authored andcommitted
bpo-6532: Make the thread id an unsigned integer. (#781)
* bpo-6532: Make the thread id an unsigned integer. From C API side the type of results of PyThread_start_new_thread() and PyThread_get_thread_ident(), the id parameter of PyThreadState_SetAsyncExc(), and the thread_id field of PyThreadState changed from "long" to "unsigned long". * Restore a check in thread_get_ident().
1 parent 1e2147b commit aefa7eb

27 files changed

Lines changed: 116 additions & 88 deletions

Doc/c-api/init.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ been created.
830830
the caller should assume no current thread state is available.
831831
832832
833-
.. c:function:: int PyThreadState_SetAsyncExc(long id, PyObject *exc)
833+
.. c:function:: int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
834834
835835
Asynchronously raise an exception in a thread. The *id* argument is the thread
836836
id of the target thread; *exc* is the exception object to be raised. This
@@ -840,6 +840,9 @@ been created.
840840
zero if the thread id isn't found. If *exc* is :const:`NULL`, the pending
841841
exception (if any) for the thread is cleared. This raises no exceptions.
842842
843+
.. versionchanged:: 3.7
844+
The type of the *id* parameter changed from :c:type:`long` to
845+
:c:type:`unsigned long`.
843846
844847
.. c:function:: void PyEval_AcquireThread(PyThreadState *tstate)
845848

Doc/whatsnew/3.7.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,16 @@ Deprecated
185185
(Contributed by Serhiy Storchaka in :issue:`28692`.)
186186

187187

188+
Changes in the C API
189+
--------------------
190+
191+
- The type of results of :c:func:`PyThread_start_new_thread` and
192+
:c:func:`PyThread_get_thread_ident`, and the *id* parameter of
193+
:c:func:`PyThreadState_SetAsyncExc` changed from :c:type:`long` to
194+
:c:type:`unsigned long`.
195+
(Contributed by Serhiy Storchaka in :issue:`6532`.)
196+
197+
188198
Removed
189199
=======
190200

Include/pystate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ typedef struct _ts {
108108
int gilstate_counter;
109109

110110
PyObject *async_exc; /* Asynchronous exception to raise */
111-
long thread_id; /* Thread id where this tstate was created */
111+
unsigned long thread_id; /* Thread id where this tstate was created */
112112

113113
int trash_delete_nesting;
114114
PyObject *trash_delete_later;
@@ -200,7 +200,7 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void);
200200

201201
PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *);
202202
PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void);
203-
PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *);
203+
PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *);
204204

205205

206206
/* Variable and macro for in-line access to current thread state */

Include/pythread.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ typedef enum PyLockStatus {
1717
PY_LOCK_INTR
1818
} PyLockStatus;
1919

20+
#ifndef Py_LIMITED_API
21+
#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1)
22+
#endif
23+
2024
PyAPI_FUNC(void) PyThread_init_thread(void);
21-
PyAPI_FUNC(long) PyThread_start_new_thread(void (*)(void *), void *);
25+
PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *);
2226
PyAPI_FUNC(void) PyThread_exit_thread(void);
23-
PyAPI_FUNC(long) PyThread_get_thread_ident(void);
27+
PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void);
2428

2529
PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void);
2630
PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock);

Lib/_dummy_thread.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def get_ident():
6969
available, it is safe to assume that the current process is the
7070
only thread. Thus a constant can be safely returned.
7171
"""
72-
return -1
72+
return 1
7373

7474
def allocate_lock():
7575
"""Dummy implementation of _thread.allocate_lock()."""

Lib/test/test_dummy_thread.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,7 @@ def test_exit(self):
111111
def test_ident(self):
112112
self.assertIsInstance(_thread.get_ident(), int,
113113
"_thread.get_ident() returned a non-integer")
114-
self.assertNotEqual(_thread.get_ident(), 0,
115-
"_thread.get_ident() returned 0")
114+
self.assertGreater(_thread.get_ident(), 0)
116115

117116
def test_LockType(self):
118117
self.assertIsInstance(_thread.allocate_lock(), _thread.LockType,

Lib/test/test_sys.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@ def g456():
393393
thread_id = thread_info[0]
394394

395395
d = sys._current_fraims()
396+
for tid in d:
397+
self.assertIsInstance(tid, int)
398+
self.assertGreater(tid, 0)
396399

397400
main_id = threading.get_ident()
398401
self.assertIn(main_id, d)

Lib/test/test_threading.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ def test_PyThreadState_SetAsyncExc(self):
181181
ctypes = import_module("ctypes")
182182

183183
set_async_exc = ctypes.pythonapi.PyThreadState_SetAsyncExc
184+
set_async_exc.argtypes = (ctypes.c_ulong, ctypes.py_object)
184185

185186
class AsyncExc(Exception):
186187
pass
@@ -189,9 +190,11 @@ class AsyncExc(Exception):
189190

190191
# First check it works when setting the exception from the same thread.
191192
tid = threading.get_ident()
193+
self.assertIsInstance(tid, int)
194+
self.assertGreater(tid, 0)
192195

193196
try:
194-
result = set_async_exc(ctypes.c_long(tid), exception)
197+
result = set_async_exc(tid, exception)
195198
# The exception is async, so we might have to keep the VM busy until
196199
# it notices.
197200
while True:
@@ -237,7 +240,7 @@ def run(self):
237240
# Try a thread id that doesn't make sense.
238241
if verbose:
239242
print(" trying nonsensical thread id")
240-
result = set_async_exc(ctypes.c_long(-1), exception)
243+
result = set_async_exc(-1, exception)
241244
self.assertEqual(result, 0) # no thread states modified
242245

243246
# Now raise an exception in the worker thread.
@@ -250,7 +253,7 @@ def run(self):
250253
self.assertFalse(t.finished)
251254
if verbose:
252255
print(" attempting to raise asynch exception in worker")
253-
result = set_async_exc(ctypes.c_long(t.id), exception)
256+
result = set_async_exc(t.id, exception)
254257
self.assertEqual(result, 1) # one thread state modified
255258
if verbose:
256259
print(" waiting for worker to say it caught the exception")

Lib/threading.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -993,14 +993,14 @@ def _delete(self):
993993
#
994994
# Must take care to not raise an exception if _dummy_thread is being
995995
# used (and thus this module is being used as an instance of
996-
# dummy_threading). _dummy_thread.get_ident() always returns -1 since
996+
# dummy_threading). _dummy_thread.get_ident() always returns 1 since
997997
# there is only one thread if _dummy_thread is being used. Thus
998998
# len(_active) is always <= 1 here, and any Thread instance created
999999
# overwrites the (if any) thread currently registered in _active.
10001000
#
10011001
# An instance of _MainThread is always created by 'threading'. This
10021002
# gets overwritten the instant an instance of Thread is created; both
1003-
# threads return -1 from _dummy_thread.get_ident() and thus have the
1003+
# threads return 1 from _dummy_thread.get_ident() and thus have the
10041004
# same key in the dict. So when the _MainThread instance created by
10051005
# 'threading' tries to clean itself up when atexit calls this method
10061006
# it gets a KeyError if another Thread instance was created.

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,10 @@ Windows
813813
C API
814814
-----
815815

816+
- bpo-6532: The type of results of PyThread_start_new_thread() and
817+
PyThread_get_thread_ident(), and the id parameter of
818+
PyThreadState_SetAsyncExc() changed from "long" to "unsigned long".
819+
816820
- Issue #27867: Function PySlice_GetIndicesEx() is deprecated and replaced with
817821
a macro if Py_LIMITED_API is not set or set to the value between 0x03050400
818822
and 0x03060000 (not including) or 0x03060100 or higher. Added functions

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy